EMAN2
jpegio.cpp
Go to the documentation of this file.
1/*
2 * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#ifdef USE_JPEG
33
34#ifdef WIN32
35#include <windows.h>
36#endif // WIN32
37
38#include <stdlib.h>
39#include <stdio.h>
40#include <math.h>
41#include "jpegio.h"
42#include "geometry.h"
43#include "util.h"
44
45using namespace EMAN;
46
47JpegIO::JpegIO(const string & fname, IOMode rw)
48: ImageIO(fname, rw),
49 rendermin(0.0), rendermax(0.0), renderbits(16)
50{}
51
52JpegIO::~JpegIO()
53{
54 if (file) {
55 fclose(file);
56 file = NULL;
57 }
58
59}
60
61void JpegIO::init()
62{
64
65 if (initialized) {
66 return;
67 }
68
69 initialized = true;
70
71 bool is_new_file = false;
72 file = sfopen(filename, rw_mode, &is_new_file, true);
73
74 if (! is_new_file) {
75 throw ImageReadException(filename, "JPEG reading not supported");
76 }
77 else {
78 cinfo.err = jpeg_std_error(&jerr);
79 jpeg_create_compress(&cinfo);
80 jpeg_stdio_dest(&cinfo, file);
81 }
82
83 rendermin = 0.0;
84 rendermax = 0.0;
85
86 jpegqual = 75;
87
89}
90
91bool JpegIO::is_valid(const void *)
92{
93// ENTERFUNC;
94
95 return false;
96}
97
98// int JpegIO::read_header(Dict & dict, int image_index,
99// const Region * area, bool)
100
101int JpegIO::read_header(Dict &, int, const Region *, bool)
102{
103 ENTERFUNC;
104
105 throw ImageReadException(filename, "JPEG reading not supported");
106
107 EXITFUNC;
108
109 return 0;
110}
111
112int JpegIO::write_header(const Dict & dict, int image_index,
113 const Region* area, EMUtil::EMDataType, bool)
114{
115 ENTERFUNC;
116
117 // single image format, index can only be zero
118
119 if (image_index == -1) {
120 image_index = 0;
121 }
122
123 if (image_index != 0) {
124 throw ImageWriteException(filename,
125 "JPEG file does not support stack.");
126 }
127
128 check_write_access(rw_mode, image_index);
129
130 if ((int) dict["nz"] != 1) {
131 LOGERR("Only support 2D JPEG file write");
132
133 return 1;
134 }
135
136// rendermin = (float)dict["render_min"]; // float value representing black in the output
137// rendermax = (float)dict["render_max"]; // float value representign white in the output
138
139 EMUtil::getRenderLimits(dict, rendermin, rendermax, renderbits);
140
141 jpegqual = (int)dict["jpeg_quality"];
142 if (jpegqual == 0) jpegqual = 75;
143
144 cinfo.image_width = (int) dict["nx"]; /* image width and height, in pixels */
145 cinfo.image_height = (int) dict["ny"];
146
147 if (area) {
148 cinfo.image_width = (int) area->size[0];
149 cinfo.image_height = (int) area->size[1];
150 }
151
152 cinfo.input_components = 1; /* # of color components per pixel */
153 cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
154
155 jpeg_set_defaults(&cinfo);
156 jpeg_set_quality(&cinfo, jpegqual, TRUE);
157
158 EXITFUNC;
159
160 return 0;
161}
162
163int JpegIO::read_data(float *, int, const Region *, bool)
164{
165 ENTERFUNC;
166
167 EXITFUNC;
168
169 return 0;
170}
171
172int JpegIO::write_data(float *data, int image_index, const Region* area,
173 EMUtil::EMDataType, bool)
174{
175 ENTERFUNC;
176
177 if (image_index > 0)
178 throw ImageWriteException("N/A", "JPEG files are single-image only");
179
180 if (area && (area->size[0] != cinfo.image_width ||
181 area->size[1] != cinfo.image_height))
182 throw ImageWriteException("N/A", "No region writing for JPEG images");
183
184 int nx = cinfo.image_width, ny = cinfo.image_height;
185
186 // If we didn't get any parameters in 'render_min' or 'render_max',
187 // we need to find some good ones.
188
189 if (renderbits==0 || renderbits>8) renderbits=8;
190 EMUtil::getRenderMinMax(data, nx, ny, rendermin, rendermax, renderbits);
191
192 unsigned char *cdata = (unsigned char *)malloc(nx+1);
193
194 /* Flip the image vertically, since EMAN use top-left corner as image origin
195 But PNG use bottom-left corner as image origin */
196 // convert and write the data 1 scanline at a time
197
198 JSAMPROW rp[1];
199 rp[0] = cdata;
200
201 jpeg_start_compress(&cinfo, TRUE);
202
203 for (int i=ny-1; i>=0; i--) {
204 for (int j=0; j<nx; j++) {
205 if (data[i*nx+j] <= rendermin) cdata[j] = 0;
206 else if (data[i*nx+j] >= rendermax) cdata[j] = 255;
207 else cdata[j]= (int)((data[i*nx+j]-rendermin)/
208 (rendermax-rendermin)*256.0);
209 }
210
211 jpeg_write_scanlines(&cinfo, rp, 1);
212 }
213
214 jpeg_finish_compress(&cinfo);
215 jpeg_destroy_compress(&cinfo);
216
217 free(cdata);
218
219 EXITFUNC;
220
221 return 0;
222}
223
224int JpegIO::get_nimg() {
225 return 0;
226}
227
228void JpegIO::flush()
229{
230
231}
232
233bool JpegIO::is_complex_mode()
234{
235 return false;
236}
237
238bool JpegIO::is_image_big_endian()
239{
240 return true;
241}
242
243#endif //USE_JPEG
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
EMDataType
Image pixel data type used in EMAN.
Definition: emutil.h:92
ImageIO classes are designed for reading/writing various electron micrography image formats,...
Definition: imageio.h:127
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
FloatSize size
Definition: geometry.h:655
void read_data(string fsp, size_t loc, const Region *area=0, const int file_nx=0, const int file_ny=0, const int file_nz=0)
Read the image pixel data in native byte order from a disk file.
void write_data(string fsp, size_t loc, const Region *const area=0, const int file_nx=0, const int file_ny=0, const int file_nz=0)
Dump the image pixel data in native byte order to a disk file.
#define ImageReadException(filename, desc)
Definition: exception.h:204
#define ImageWriteException(imagename, desc)
Definition: exception.h:223
#define LOGERR
Definition: log.h:51
#define ENTERFUNC
Definition: log.h:48
#define EXITFUNC
Definition: log.h:49
E2Exception class.
Definition: aligner.h:40