00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifdef EM_JPEG
00037
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include "jpegio.h"
00041 #include "geometry.h"
00042 #include "util.h"
00043 #include <math.h>
00044
00045 using namespace EMAN;
00046
00047 JpegIO::JpegIO(const string & file, IOMode rw): filename(file), rw_mode(rw), jpeg_file(0), initialized(false),rendermin(0),rendermax(0)
00048 {}
00049
00050 JpegIO::~JpegIO()
00051 {
00052 if (jpeg_file) {
00053 fclose(jpeg_file);
00054 jpeg_file = 0;
00055 }
00056
00057 }
00058
00059 void JpegIO::init()
00060 {
00061 ENTERFUNC;
00062 if (initialized) {
00063 return;
00064 }
00065
00066 initialized = true;
00067
00068 bool is_new_file = false;
00069 jpeg_file = sfopen(filename, rw_mode, &is_new_file, true);
00070
00071 if (!is_new_file) {
00072 throw ImageReadException(filename, "JPEG reading not supported");
00073 }
00074 else {
00075 cinfo.err = jpeg_std_error(&jerr);
00076 jpeg_create_compress(&cinfo);
00077 jpeg_stdio_dest(&cinfo, jpeg_file);
00078 }
00079
00080 rendermin=rendermax=0;
00081 jpegqual=75;
00082 EXITFUNC;
00083 }
00084
00085 bool JpegIO::is_valid(const void *)
00086 {
00087
00088 return false;
00089 }
00090
00091
00092 int JpegIO::read_header(Dict &, int, const Region *, bool)
00093 {
00094 ENTERFUNC;
00095
00096 throw ImageReadException(filename, "JPEG reading not supported");
00097
00098 EXITFUNC;
00099 return 0;
00100 }
00101
00102 int JpegIO::write_header(const Dict & dict, int image_index, const Region* area,
00103 EMUtil::EMDataType, bool)
00104 {
00105 ENTERFUNC;
00106
00107
00108 if(image_index == -1) {
00109 image_index = 0;
00110 }
00111 if(image_index != 0) {
00112 throw ImageWriteException(filename, "JPEG file does not support stack.");
00113 }
00114 check_write_access(rw_mode, image_index);
00115
00116 if ((int) dict["nz"] != 1) {
00117 LOGERR("Only support 2D JPEG file write");
00118 return 1;
00119 }
00120
00121 rendermin=(float)dict["render_min"];
00122 rendermax=(float)dict["render_max"];
00123 jpegqual=(int)dict["jpeg_quality"];
00124 if (jpegqual==0) jpegqual=75;
00125
00126 cinfo.image_width = (int) dict["nx"];
00127 cinfo.image_height = (int) dict["ny"];
00128 if (area) {
00129 cinfo.image_width = (int) area->size[0];
00130 cinfo.image_height = (int) area->size[1];
00131 }
00132 cinfo.input_components = 1;
00133 cinfo.in_color_space = JCS_GRAYSCALE;
00134 jpeg_set_defaults(&cinfo);
00135 jpeg_set_quality(&cinfo,jpegqual,true);
00136
00137 EXITFUNC;
00138 return 0;
00139 }
00140
00141 int JpegIO::read_data(float *, int, const Region *, bool)
00142 {
00143 ENTERFUNC;
00144
00145 EXITFUNC;
00146 return 0;
00147 }
00148
00149 int JpegIO::write_data(float *data, int image_index, const Region* area,
00150 EMUtil::EMDataType, bool)
00151 {
00152 ENTERFUNC;
00153
00154 if (image_index>0) throw ImageWriteException("N/A", "JPEG files are single-image only");
00155 if (area && (area->size[0]!=cinfo.image_width || area->size[1]!=cinfo.image_height))
00156 throw ImageWriteException("N/A", "No region writing for JPEG images");
00157 int nx=cinfo.image_width,ny=cinfo.image_height;
00158
00159
00160 EMUtil::getRenderMinMax(data, nx, ny, rendermin, rendermax);
00161
00162 unsigned char *cdata=(unsigned char *)malloc(nx+1);
00163
00166
00167 JSAMPROW rp[1];
00168 rp[0]=cdata;
00169 jpeg_start_compress(&cinfo, TRUE);
00170 for (int i=ny-1; i>=0; i--) {
00171 for (int j=0; j<nx; j++) {
00172 if (data[i*nx+j]<=rendermin) cdata[j]=0;
00173 else if (data[i*nx+j]>=rendermax) cdata[j]=255;
00174 else cdata[j]=(int)((data[i*nx+j]-rendermin)/(rendermax-rendermin)*256.0);
00175 }
00176 jpeg_write_scanlines(&cinfo, rp, 1);
00177 }
00178
00179 jpeg_finish_compress(&cinfo);
00180 jpeg_destroy_compress(&cinfo);
00181
00182 free(cdata);
00183 EXITFUNC;
00184
00185 return 0;
00186 }
00187
00188 int JpegIO::get_nimg() {
00189 return 0;
00190 }
00191
00192 void JpegIO::flush()
00193 {
00194
00195 }
00196
00197 bool JpegIO::is_complex_mode()
00198 {
00199 return false;
00200 }
00201
00202 bool JpegIO::is_image_big_endian()
00203 {
00204 return true;
00205 }
00206
00207
00208 #endif //EM_JPEG