]> Creatis software - gdcm.git/blob - src/gdcmJpeg.cxx
* src/jpeg/libijg8/jconfig.* : JPR bug fix : now compile on both
[gdcm.git] / src / gdcmJpeg.cxx
1 #include <stdio.h>
2 #include "gdcmFile.h"
3
4 #define DEBUG 0
5
6 /*
7  * <setjmp.h> is used for the optional error recovery mechanism shown in
8  * the second part of the example.
9  */
10
11 /*
12  * Include file for users of JPEG library.
13  * You will need to have included system headers that define at least
14  * the typedefs FILE and size_t before you can include jpeglib.h.
15  * (stdio.h is sufficient on ANSI-conforming systems.)
16  * You may also wish to include "jerror.h".
17  */
18
19 extern "C" {
20 #include "jpeglib.h"
21 #include <setjmp.h>
22 }
23
24 /******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
25
26 /* This half of the example shows how to read data from the JPEG decompressor.
27  * It's a bit more refined than the above, in that we show:
28  *   (a) how to modify the JPEG library's standard error-reporting behavior;
29  *   (b) how to allocate workspace using the library's memory manager.
30  *
31  * Just to make this example a little different from the first one, we'll
32  * assume that we do not intend to put the whole image into an in-memory
33  * buffer, but to send it line-by-line someplace else.  We need a one-
34  * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG
35  * memory manager allocate it for us.  This approach is actually quite useful
36  * because we don't need to remember to deallocate the buffer separately: it
37  * will go away automatically when the JPEG object is cleaned up.
38  */
39
40 /*
41  * ERROR HANDLING:
42  *
43  * The JPEG library's standard error handler (jerror.c) is divided into
44  * several "methods" which you can override individually.  This lets you
45  * adjust the behavior without duplicating a lot of code, which you might
46  * have to update with each future release.
47  *
48  * Our example here shows how to override the "error_exit" method so that
49  * control is returned to the library's caller when a fatal error occurs,
50  * rather than calling exit() as the standard error_exit method does.
51  *
52  * We use C's setjmp/longjmp facility to return control.  This means that the
53  * routine which calls the JPEG library must first execute a setjmp() call to
54  * establish the return point.  We want the replacement error_exit to do a
55  * longjmp().  But we need to make the setjmp buffer accessible to the
56  * error_exit routine.  To do this, we make a private extension of the
57  * standard JPEG error handler object.  (If we were using C++, we'd say we
58  * were making a subclass of the regular error handler.)
59  *
60  * Here's the extended error handler struct:
61  */
62
63 struct my_error_mgr {
64   struct jpeg_error_mgr pub;    /* "public" fields */
65   jmp_buf setjmp_buffer;        /* for return to caller */
66 };
67
68 typedef struct my_error_mgr * my_error_ptr;
69
70 /*
71  * Here's the routine that will replace the standard error_exit method:
72  */
73
74 METHODDEF(void)
75 my_error_exit (j_common_ptr cinfo) {
76   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
77   my_error_ptr myerr = (my_error_ptr) cinfo->err;
78
79   /* Always display the message. */
80   /* We could postpone this until after returning, if we chose. */
81   (*cinfo->err->output_message) (cinfo);
82
83   /* Return control to the setjmp point */
84   longjmp(myerr->setjmp_buffer, 1);
85 }
86
87
88 /*
89  * Sample routine for JPEG decompression.  We assume that the source file name
90  * is passed in.  We want to return 1 on success, 0 on error.
91  */
92
93
94 //GLOBAL(int)
95 int
96 gdcmFile::gdcm_read_JPEG_file (void * image_buffer) {
97
98 char *pimage;
99
100   /* This struct contains the JPEG decompression parameters and pointers to
101    * working space (which is allocated as needed by the JPEG library).
102    */
103    
104   struct jpeg_decompress_struct cinfo;
105   
106   /* -------------- inside, we found :
107   JDIMENSION image_width;       // input image width 
108   JDIMENSION image_height;      // input image height 
109   int input_components;         // nb of color components in input image 
110   J_COLOR_SPACE in_color_space; // colorspace of input image 
111   double input_gamma;           // image gamma of input image 
112      -------------- */
113   
114   /* We use our private extension JPEG error handler.
115    * Note that this struct must live as long as the main JPEG parameter
116    * struct, to avoid dangling-pointer problems.
117    */
118   struct my_error_mgr jerr;
119   /* More stuff */
120  
121   JSAMPARRAY buffer;            /* Output row buffer */
122   
123   // rappel :
124   // typedef unsigned char JSAMPLE;
125   // typedef JSAMPLE FAR *JSAMPROW;     /* ptr to one image row of pixel samples. */
126   // typedef JSAMPROW *JSAMPARRAY;      /* ptr to some rows (a 2-D sample array) */
127   // typedef JSAMPARRAY *JSAMPIMAGE;    /* a 3-D sample array: top index is color */
128   
129  
130   int row_stride;               /* physical row width in output buffer */
131   
132  if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file, depuis gdcmJpeg\n");
133
134
135   /* In this example we want to open the input file before doing anything else,
136    * so that the setjmp() error recovery below can assume the file is open.
137    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
138    * requires it in order to read binary files.
139    */
140
141   /* Step 1: allocate and initialize JPEG decompression object */
142   
143   if (DEBUG)printf("Entree Step 1\n");
144
145   /* We set up the normal JPEG error routines, then override error_exit. */
146   
147   cinfo.err = jpeg_std_error(&jerr.pub);
148   jerr.pub.error_exit = my_error_exit;
149   
150   /* Establish the setjmp return context for my_error_exit to use. */
151   
152   if (setjmp(jerr.setjmp_buffer)) {
153     /* If we get here, the JPEG code has signaled an error.
154      * We need to clean up the JPEG object, close the input file, and return.
155      */
156     jpeg_destroy_decompress(&cinfo);
157     return 0;
158   }
159   /* Now we can initialize the JPEG decompression object. */
160   jpeg_create_decompress(&cinfo);
161
162   /* Step 2: specify data source (eg, a file) */
163   
164 if (DEBUG) printf("Entree Step 2\n");
165
166   jpeg_stdio_src(&cinfo, fp);
167
168   /* Step 3: read file parameters with jpeg_read_header() */
169
170  if (DEBUG) printf("Entree Step 3\n");
171
172   (void) jpeg_read_header(&cinfo, TRUE);
173    
174   /* We can ignore the return value from jpeg_read_header since
175    *   (a) suspension is not possible with the stdio data source, and
176    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
177    * See libjpeg.doc for more info.
178    */
179
180 if (DEBUG) {   
181         printf("--------------Header contents :----------------\n");
182         printf("image_width %d image_height %d\n", 
183                                 cinfo.image_width , cinfo.image_height);
184         printf("bits of precision in image data  %d \n", 
185                                 cinfo.output_components);
186         printf("nb of color components returned  %d \n", 
187                                 cinfo.data_precision);
188 }
189
190
191 /*
192   JDIMENSION image_width;       // input image width 
193   JDIMENSION image_height;      // input image height 
194   int output_components;        // # of color components returned 
195   J_COLOR_SPACE in_color_space; // colorspace of input image 
196   double input_gamma;           // image gamma of input image
197   int data_precision;           // bits of precision in image data 
198  
199 */
200
201   /* Step 4: set parameters for decompression */
202   
203  if (DEBUG) printf("Entree Step 4\n");
204
205   /* In this example, we don't need to change any of the defaults set by
206    * jpeg_read_header(), so we do nothing here.
207    */
208
209   /* Step 5: Start decompressor */
210   
211  if (DEBUG) printf("Entree Step 5\n");
212
213   (void) jpeg_start_decompress(&cinfo);
214   /* We can ignore the return value since suspension is not possible
215    * with the stdio data source.
216    */
217    
218   /* We may need to do some setup of our own at this point before reading
219    * the data.  After jpeg_start_decompress() we have the correct scaled
220    * output image dimensions available, as well as the output colormap
221    * if we asked for color quantization.
222    * In this example, we need to make an output work buffer of the right size.
223    */ 
224   /* JSAMPLEs per row in output buffer */
225   row_stride = cinfo.output_width * cinfo.output_components;
226   
227  if (DEBUG) printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
228         cinfo.output_width, cinfo.output_components,row_stride);
229         
230   /* Make a one-row-high sample array that will go away when done with image */
231   buffer = (*cinfo.mem->alloc_sarray)
232                 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
233
234   /* Step 6: while (scan lines remain to be read) */
235   
236  if (DEBUG)  printf("Entree Step 6\n"); 
237
238   /*           jpeg_read_scanlines(...); */
239
240   /* Here we use the library's state variable cinfo.output_scanline as the
241    * loop counter, so that we don't have to keep track ourselves.
242    */
243    
244  if (DEBUG)  printf ("cinfo.output_height %d  cinfo.output_width %d\n",
245                         cinfo.output_height,cinfo.output_width);
246  
247   pimage=(char *)image_buffer;
248   
249   
250   while (cinfo.output_scanline < cinfo.output_height) {
251     /* jpeg_read_scanlines expects an array of pointers to scanlines.
252      * Here the array is only one element long, but you could ask for
253      * more than one scanline at a time if that's more convenient.
254      */
255      
256      // l'image est deja allouée (et passée en param)
257      // on ecrit directement les pixels
258      // (on DEVRAIT pouvoir)
259     
260     //(void) jpeg_read_scanlines(&cinfo, pimage, 1);
261     
262      (void) jpeg_read_scanlines(&cinfo, buffer, 1); 
263      memcpy( pimage, buffer[0],row_stride*2 ); // FIXME : *2  car 16 bits?!?
264      
265     pimage+=row_stride*2;  // FIXME : *2 car 16 bits?!?
266   }
267  
268   /* Step 7: Finish decompression */
269   
270 if (DEBUG)  printf("Entree Step 7\n");
271
272   (void) jpeg_finish_decompress(&cinfo);
273   /* We can ignore the return value since suspension is not possible
274    * with the stdio data source.
275    */
276
277   /* Step 8: Release JPEG decompression object */
278   
279 if (DEBUG) printf("Entree Step 8\n");
280
281   /* This is an important step since it will release a good deal of memory. */
282   
283   jpeg_destroy_decompress(&cinfo);
284
285   /* After finish_decompress, we can close the input file.
286    * Here we postpone it until after no more JPEG errors are possible,
287    * so as to simplify the setjmp error logic above.  (Actually, I don't
288    * think that jpeg_destroy can do an error exit, but why assume anything...)
289    */
290
291   /* At this point you may want to check to see whether any corrupt-data
292    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
293    */
294
295   /* And we're done! */
296   
297   return 1;
298 }
299
300 /*
301  * SOME FINE POINTS:
302  *
303  * In the above code, we ignored the return value of jpeg_read_scanlines,
304  * which is the number of scanlines actually read.  We could get away with
305  * this because we asked for only one line at a time and we weren't using
306  * a suspending data source.  See libjpeg.doc for more info.
307  *
308  * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
309  * we should have done it beforehand to ensure that the space would be
310  * counted against the JPEG max_memory setting.  In some systems the above
311  * code would risk an out-of-memory error.  However, in general we don't
312  * know the output image dimensions before jpeg_start_decompress(), unless we
313  * call jpeg_calc_output_dimensions().  See libjpeg.doc for more about this.
314  *
315  * Scanlines are returned in the same order as they appear in the JPEG file,
316  * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
317  * you can use one of the virtual arrays provided by the JPEG memory manager
318  * to invert the data.  See wrbmp.c for an example.
319  *
320  * As with compression, some operating modes may require temporary files.
321  * On some systems you may need to set up a signal handler to ensure that
322  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
323  */
324  
325