Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CompressJpeg.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifdef WIN32
26 # include <windows.h>
27 # ifdef BIAS_HAVE_WXWIDGETS
28 # include <wx/msw/winundef.h>
29 # endif
30 #endif
31 #include "CompressJpeg.hh"
32 #include <Base/Image/MetaData.hh>
33 
34 /*
35  * Include file for users of JPEG library.
36  * You will need to have included system headers that define at least
37  * the typedefs FILE and size_t before you can include jpeglib.h.
38  * (stdio.h is sufficient on ANSI-conforming systems.)
39  * You may also wish to include "jerror.h".
40  */
41 
42 #ifdef WIN32
43 // undef backward compatibility define - not needed
44 # undef FAR
45 #endif
46 
47 extern "C" {
48 #include "jpeglib.h"
49 }
50 
51 #ifdef WIN32
52 //Disable warning for setjmp can't interact with C++ Dtors, which is not
53 //the case here (no Dtors interact with setjmp)
54 #pragma warning(disable:4611)
55 //disable padding warng (structure padding unknown)
56 #pragma warning(disable:4324)
57 #endif /* WIN32 */
58 
59 /*
60  * <setjmp.h> is used for the optional error recovery mechanism shown in
61  * the second part of the example.
62  */
63 
64 #include <setjmp.h>
65 
66 /*
67  * include memory-system-funcs
68  */
69 #ifdef WIN32
70 #include <io.h>
71 #else
72 #include <sys/mman.h>
73 #endif
74 #include <fcntl.h>
75 #include <sys/types.h>
76 
77 /*
78  * global vars for jpeg-library
79  */
80 extern "C" {
81  JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
82  int image_height; /* Number of rows in image */
83  int image_width; /* Number of columns in image */
84  int image_channels; /* Number of channels in image */
85 }
86 
87 using namespace std;
88 using namespace BIAS;
89 
90 /** \cond HIDDEN_SYMBOLS
91  * Some stuff for decompressor-method
92  */
93 struct my_error_mgr {
94  struct jpeg_error_mgr pub; /* "public" fields */
95  jmp_buf setjmp_buffer; /* for return to caller */
96 };
97 
98 typedef struct my_error_mgr * my_error_ptr;
99 /** \endcond */
100 
101 /*
102  * Here are routines that will replace the standard error_exit method:
103  */
104 METHODDEF(void)
105 my_error_exit (j_common_ptr cinfo)
106 {
107  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
108  my_error_ptr myerr = (my_error_ptr) cinfo->err;
109 
110  /* Always display the message. */
111  /* We could postpone this until after returning, if we chose. */
112  (*cinfo->err->output_message) (cinfo);
113 
114  /* Return control to the setjmp point */
115  longjmp(myerr->setjmp_buffer, 1);
116 }
117 
118 METHODDEF(void)
119 silent_error_exit (j_common_ptr cinfo)
120 {
121  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
122  my_error_ptr myerr = (my_error_ptr) cinfo->err;
123 
124  /* Return control to the setjmp point */
125  longjmp(myerr->setjmp_buffer, 1);
126 }
127 
128 /**
129  Routines for source (data array) managing
130 */
131 METHODDEF(void)
132 init_source (j_decompress_ptr /*cinfo*/)
133 {
134  /* no work necessary here */
135 }
136 
137 METHODDEF(boolean)
138 fill_input_buffer (j_decompress_ptr cinfo)
139 {
140  static JOCTET dummy[] = { (JOCTET) 0xFF, (JOCTET) JPEG_EOI };
141 
142  // WARNMS(cinfo, JWRN_JPEG_EOF);
143 
144  /* Insert a fake EOI marker */
145 
146  cinfo->src->next_input_byte = dummy;
147  cinfo->src->bytes_in_buffer = 2;
148 
149  return TRUE;
150 }
151 
152 METHODDEF(void)
153 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
154 {
155  if (num_bytes > 0) {
156  while (num_bytes > (long) cinfo->src->bytes_in_buffer) {
157  num_bytes -= (long) cinfo->src->bytes_in_buffer;
158  (void) fill_input_buffer(cinfo);
159  }
160  cinfo->src->next_input_byte += (size_t) num_bytes;
161  cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
162  }
163 
164 }
165 
166 METHODDEF(void)
167 term_source (j_decompress_ptr /* cinfo*/)
168 {
169  /* no work necessary here */
170 }
171 
172 /**
173  Routines for destination (data array) managing
174 */
175 METHODDEF(void)
176 init_destination (j_compress_ptr /*cinfo*/)
177 { /* initialize destination */
178  /* no work necessary here (buffer = data) */
179 }
180 
181 METHODDEF(boolean)
182 empty_output_buffer (j_compress_ptr cinfo)
183 {
184  BIASERR("JPEG-buffer is too small!!!");
185  cinfo->dest->next_output_byte = NULL;
186  cinfo->dest->free_in_buffer = 0;
187  return true;
188 }
189 
190 METHODDEF(void)
191 term_destination (j_compress_ptr /*cinfo*/)
192 {
193  /* no work necessary here */
194 }
195 
196 /**
197  Routine for using libjpeg compression-methods
198  (borrowed from libjpeg-example, with litle changes)
199 */
200 int create_JPEG_file (void * outfile, long length, int quality)
201 {
202  /* This struct contains the JPEG compression parameters and pointers to
203  * working space (which is allocated as needed by the JPEG library).
204  * It is possible to have several such structures, representing multiple
205  * compression/decompression processes, in existence at once. We refer
206  * to any one struct (and its associated working data) as a "JPEG object".
207  */
208  struct jpeg_compress_struct cinfo;
209  /* This struct represents a JPEG error handler. It is declared separately
210  * because applications often want to supply a specialized error handler
211  * (see the second half of this file for an example). But here we just
212  * take the easy way out and use the standard error handler, which will
213  * print a message on stderr and call exit() if compression fails.
214  * Note that this struct must live as long as the main JPEG parameter
215  * struct, to avoid dangling-pointer problems.
216  */
217  struct jpeg_error_mgr jerr;
218  struct jpeg_destination_mgr jdest;
219  /* More stuff */
220  JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
221  int row_stride; /* physical row width in image buffer */
222 
223  /* Step 1: allocate and initialize JPEG compression object */
224 
225  /* We have to set up the error handler first, in case the initialization
226  * step fails. (Unlikely, but it could happen if you are out of memory.)
227  * This routine fills in the contents of struct jerr, and returns jerr's
228  * address which we place into the link field in cinfo.
229  */
230  cinfo.err = jpeg_std_error(&jerr);
231  /* Now we can initialize the JPEG compression object. */
232  jpeg_create_compress(&cinfo);
233 
234  /* Step 2: specify data destination (eg, a file) */
235  /* Note: steps 2 and 3 can be done in either order. */
236 
237  /* Here we use the library-supplied code to send compressed data to a
238  * stdio stream. You can also write your own code to do something else.
239  * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
240  * requires it in order to write binary files.
241  */
242  //no more files
243  // if (outfile == NULL) {
244  // fprintf(stderr, "can't open \n");
245  // return -1;
246  // }
247  // jpeg_stdio_dest(&cinfo, outfile);
248  //init destination mgr
249  cinfo.dest = &jdest;
250  jdest.init_destination = init_destination;
251  jdest.empty_output_buffer = empty_output_buffer;
252  jdest.term_destination = term_destination;
253  jdest.free_in_buffer = length;
254  jdest.next_output_byte = (JOCTET *) outfile;
255 
256  /* Step 3: set parameters for compression */
257 
258  /* First we supply a description of the input image.
259  * Four fields of the cinfo struct must be filled in:
260  */
261  cinfo.image_width = image_width; /* image width and height, in pixels */
262  cinfo.image_height = image_height;
263  cinfo.input_components = image_channels;/* # of color components per pixel */
264  if (image_channels == 1) {
265  cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
266  } else if (image_channels == 3) {
267  cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
268  } else {
269  BIASERR("Compression not implemented for images with channels != 1,3");
270  return -1;
271  }
272  /* Now use the library's routine to set default compression parameters.
273  * (You must set at least cinfo.in_color_space before calling this,
274  * since the defaults depend on the source color space.)
275  */
276  jpeg_set_defaults(&cinfo);
277  /* Now you can set any non-default parameters you wish to.
278  * Here we just illustrate the use of quality (quantization table) scaling:
279  */
280  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
281 
282  /* Step 4: Start compressor */
283 
284  /* TRUE ensures that we will write a complete interchange-JPEG file.
285  * Pass TRUE unless you are very sure of what you're doing.
286  */
287  jpeg_start_compress(&cinfo, TRUE);
288 
289  /* Step 5: while (scan lines remain to be written) */
290  /* jpeg_write_scanlines(...); */
291 
292  /* Here we use the library's state variable cinfo.next_scanline as the
293  * loop counter, so that we don't have to keep track ourselves.
294  * To keep things simple, we pass one scanline per call; you can pass
295  * more if you wish, though.
296  */
297  row_stride = image_width * image_channels;/*SAMPLEs per row in image_buffer*/
298 
299  while (cinfo.next_scanline < cinfo.image_height) {
300  /* jpeg_write_scanlines expects an array of pointers to scanlines.
301  * Here the array is only one element long, but you could pass
302  * more than one scanline at a time if that's more convenient.
303  */
304  row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
305  (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
306  }
307 
308  /* Step 6: Finish compression */
309 
310  jpeg_finish_compress(&cinfo);
311 
312  int res = int(length - cinfo.dest->free_in_buffer);
313  /* After finish_compress, we can close the output file. */
314  // fclose(outfile); NOT closed -> needed for next cicle and filelength
315 
316  /* Step 7: release JPEG compression object */
317 
318  /* This is an important step since it will release a good deal of memory. */
319  jpeg_destroy_compress(&cinfo);
320 
321  /* And we're done! */
322  return res;
323 }
324 
325 
326 int deflate_JPEG_file (void * infile, long length,
328  bool readComment, bool verbose = true)
329 {
330  /* This struct contains the JPEG decompression parameters and pointers to
331  * working space (which is allocated as needed by the JPEG library).
332  */
333  struct jpeg_decompress_struct cinfo;
334  /* We use our protected extension JPEG error handler.
335  * Note that this struct must live as long as the main JPEG parameter
336  * struct, to avoid dangling-pointer problems.
337  */
338  struct my_error_mgr jerr;
339  //hanlder for datasource
340  struct jpeg_source_mgr jsrc;
341  /* More stuff */
342  JSAMPARRAY buffer; /* Output row buffer */
343  int row_stride; /* physical row width in output buffer */
344 
345  /* In this example we want to open the input file before doing anything else,
346  * so that the setjmp() error recovery below can assume the file is open.
347  * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
348  * requires it in order to read binary files.
349  */
350 
351  if (infile == NULL) {
352  BIASERR("No source JPEG given!");
353  return -1;
354  }
355 
356  /* Step 1: allocate and initialize JPEG decompression object */
357 
358  /* We set up the normal JPEG error routines, then override error_exit. */
359  cinfo.err = jpeg_std_error(&jerr.pub);
360  if (verbose) {
361  jerr.pub.error_exit = my_error_exit;
362  } else {
363  jerr.pub.error_exit = silent_error_exit;
364  }
365  /* Establish the setjmp return context for my_error_exit to use. */
366  if (setjmp(jerr.setjmp_buffer)) {
367  /* If we get here, the JPEG code has signaled an error.
368  * We need to clean up the JPEG object, close the input file, and return.
369  */
370  jpeg_destroy_decompress(&cinfo);
371  return -1;
372  }
373  /* Now we can initialize the JPEG decompression object. */
374  jpeg_create_decompress(&cinfo);
375 
376  /* Step 2: specify data source (eg, a file) */
377 
378  // No longer from file
379  // jpeg_stdio_src(&cinfo, infile);
380  if (length == 0) {
381  /* Treat empty input data as fatal error */
382  jpeg_destroy_decompress(&cinfo);
383  return -1;
384  }
385  //set function pointers for source-mgr
386  cinfo.src = &jsrc;
387  jsrc.init_source = init_source;
388  jsrc.fill_input_buffer = fill_input_buffer;
389  jsrc.skip_input_data = skip_input_data;
390  jsrc.resync_to_restart = jpeg_resync_to_restart; /* use default method */
391  jsrc.term_source = term_source;
392  jsrc.bytes_in_buffer = length;
393  jsrc.next_input_byte = (JOCTET *) infile;
394 
395  // Enable reading comment metadata during decompression (opt.)
396  if (readComment) {
397  jpeg_save_markers(&cinfo, JPEG_COM, 0xFFFF);
398  }
399 
400  /* Step 3: read file parameters with jpeg_read_header() */
401 
402  (void) jpeg_read_header(&cinfo, TRUE);
403  /* We can ignore the return value from jpeg_read_header since
404  * (a) suspension is not possible with the stdio data source, and
405  * (b) we passed TRUE to reject a tables-only JPEG file as an error.
406  * See libjpeg.doc for more info.
407  */
408 
409  // Read comment metadata from JPEG image (opt.)
410  std::string comment("");
411  if (readComment) {
412  jpeg_marker_struct* marker_ptr = cinfo.marker_list;
413  while (marker_ptr) {
414  if (marker_ptr->marker == JPEG_COM) {
415  unsigned char *c_ptr = marker_ptr->data;
416  unsigned int c_len = marker_ptr->data_length;
417  comment += std::string((char*)c_ptr, c_len);
418  }
419  marker_ptr = marker_ptr->next;
420  }
421  }
422 
423  /* Step 4: set parameters for decompression */
424 
425  /* In this example, we don't need to change any of the defaults set by
426  * jpeg_read_header(), so we do nothing here.
427  */
428 
429  /* Step 5: Start decompressor */
430 
431  (void) jpeg_start_decompress(&cinfo);
432  /* We can ignore the return value since suspension is not possible
433  * with the stdio data source.
434  */
435 
436  /* We may need to do some setup of our own at this point before reading
437  * the data. After jpeg_start_decompress() we have the correct scaled
438  * output image dimensions available, as well as the output colormap
439  * if we asked for color quantization.
440  * In this example, we need to make an output work buffer of the right size.
441  */
442  if (destImg.IsEmpty()) {
443  destImg.Init(cinfo.output_width, cinfo.output_height,
444  cinfo.output_components);
445  }
446  //#ifdef BIAS_DEBUG
447  if ((destImg.GetWidth() != (unsigned int) cinfo.output_width)||
448  (destImg.GetHeight() != (unsigned int) cinfo.output_height)||
449  (destImg.GetChannelCount() != (unsigned int) cinfo.output_components)) {
450  BIASWARN("Given image has wrong format (height, width, ...) but is now initialized correctly!");
451  destImg.Release();
452  destImg.Init(cinfo.output_width, cinfo.output_height,
453  cinfo.output_components);
454  }
455  //#endif //BIAS_DEBUG
456 
457  unsigned char** img_data = destImg.GetImageDataArray();
458  /* JSAMPLEs per row in output buffer */
459  row_stride = cinfo.output_width * cinfo.output_components;
460  /* Make a one-row-high sample array that will go away when done with image */
461  buffer = (*cinfo.mem->alloc_sarray)
462  ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
463 
464 
465  /* Step 6: while (scan lines remain to be read) */
466  /* jpeg_read_scanlines(...); */
467 
468  /* Here we use the library's state variable cinfo.output_scanline as the
469  * loop counter, so that we don't have to keep track ourselves.
470  */
471  while (cinfo.output_scanline < cinfo.output_height) {
472  /* jpeg_read_scanlines expects an array of pointers to scanlines.
473  * Here the array is only one element long, but you could ask for
474  * more than one scanline at a time if that's more convenient.
475  */
476  (void) jpeg_read_scanlines(&cinfo, buffer, 1);
477  /* Assume put_scanline_someplace wants a pointer and sample count.
478  canceld for use directly with img_data
479  put_scanline_someplace(buffer[0], row_stride);
480  */
481  memcpy(img_data[cinfo.output_scanline-1],buffer[0],row_stride);
482  }
483 
484  /* Step 7: Finish decompression */
485 
486  (void) jpeg_finish_decompress(&cinfo);
487  /* We can ignore the return value since suspension is not possible
488  * with the stdio data source.
489  */
490 
491  /* Step 8: Release JPEG decompression object */
492 
493  /* This is an important step since it will release a good deal of memory. */
494  jpeg_destroy_decompress(&cinfo);
495 
496  /* After finish_decompress, we can close the input file.
497  * Here we postpone it until after no more JPEG errors are possible,
498  * so as to simplify the setjmp error logic above. (Actually, I don't
499  * think that jpeg_destroy can do an error exit, but why assume anything...)
500  */
501  // will be done outside fclose(infile);
502 
503  /* At this point you may want to check to see whether any corrupt-data
504  * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
505  */
506 
507  // Add metadata to destination image (opt.)
508  if (readComment && comment != "") {
509  BIAS::MetaData metadata;
510  metadata.Add("#[Comment]", comment);
511  destImg.SetMetaData(metadata);
512  }
513 
514  /* And we're done! */
515  return 0;
516 }
517 
518 int deflate_JPEG_file (void * infile, long length, unsigned int &width,
519  unsigned int &height, unsigned int &channels,
520  unsigned char* &data, bool verbose = true)
521 {
522  /* This struct contains the JPEG decompression parameters and pointers to
523  * working space (which is allocated as needed by the JPEG library).
524  */
525  struct jpeg_decompress_struct cinfo;
526  /* We use our protected extension JPEG error handler.
527  * Note that this struct must live as long as the main JPEG parameter
528  * struct, to avoid dangling-pointer problems.
529  */
530  struct my_error_mgr jerr;
531  //hanlder for datasource
532  struct jpeg_source_mgr jsrc;
533  /* More stuff */
534  JSAMPARRAY buffer; /* Output row buffer */
535  int row_stride; /* physical row width in output buffer */
536 
537  /* In this example we want to open the input file before doing anything else,
538  * so that the setjmp() error recovery below can assume the file is open.
539  * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
540  * requires it in order to read binary files.
541  */
542 
543  if (infile == NULL) {
544  BIASERR("No source JPEG given!!!");
545  return -1;
546  }
547 
548  /* Step 1: allocate and initialize JPEG decompression object */
549 
550  /* We set up the normal JPEG error routines, then override error_exit. */
551  cinfo.err = jpeg_std_error(&jerr.pub);
552  if (verbose) {
553  jerr.pub.error_exit = my_error_exit;
554  } else {
555  jerr.pub.error_exit = silent_error_exit;
556  }
557  /* Establish the setjmp return context for my_error_exit to use. */
558  if (setjmp(jerr.setjmp_buffer)) {
559  /* If we get here, the JPEG code has signaled an error.
560  * We need to clean up the JPEG object, close the input file, and return.
561  */
562  jpeg_destroy_decompress(&cinfo);
563  return -1;
564  }
565  /* Now we can initialize the JPEG decompression object. */
566  jpeg_create_decompress(&cinfo);
567 
568  /* Step 2: specify data source (eg, a file) */
569 
570  // No longer from file
571  // jpeg_stdio_src(&cinfo, infile);
572  if (length == 0) {
573  /* Treat empty input data as fatal error */
574  jpeg_destroy_decompress(&cinfo);
575  return -1;
576  }
577  //set function pointers for source-mgr
578  cinfo.src = &jsrc;
579  jsrc.init_source = init_source;
580  jsrc.fill_input_buffer = fill_input_buffer;
581  jsrc.skip_input_data = skip_input_data;
582  jsrc.resync_to_restart = jpeg_resync_to_restart; /* use default method */
583  jsrc.term_source = term_source;
584  jsrc.bytes_in_buffer = length;
585  jsrc.next_input_byte = (JOCTET *) infile;
586 
587  /* Step 3: read file parameters with jpeg_read_header() */
588 
589  (void) jpeg_read_header(&cinfo, TRUE);
590  /* We can ignore the return value from jpeg_read_header since
591  * (a) suspension is not possible with the stdio data source, and
592  * (b) we passed TRUE to reject a tables-only JPEG file as an error.
593  * See libjpeg.doc for more info.
594  */
595 
596  /* Step 4: set parameters for decompression */
597 
598  /* In this example, we don't need to change any of the defaults set by
599  * jpeg_read_header(), so we do nothing here.
600  */
601 
602  /* Step 5: Start decompressor */
603 
604  (void) jpeg_start_decompress(&cinfo);
605  /* We can ignore the return value since suspension is not possible
606  * with the stdio data source.
607  */
608 
609  /* We may need to do some setup of our own at this point before reading
610  * the data. After jpeg_start_decompress() we have the correct scaled
611  * output image dimensions available, as well as the output colormap
612  * if we asked for color quantization.
613  * In this example, we need to make an output work buffer of the right size.
614  */
615  width = cinfo.output_width;
616  height = cinfo.output_height;
617  channels = cinfo.output_components;
618 
619  if (data == NULL) {
620  BIASWARN("Allocating " << width * height * channels << " bytes of mem for"
621  << " returned datafield!!!\n");
622  data = new unsigned char[width * height * channels];
623  }
624 
625  /* JSAMPLEs per row in output buffer */
626  row_stride = cinfo.output_width * cinfo.output_components;
627  /* Make a one-row-high sample array that will go away when done with image */
628  buffer = (*cinfo.mem->alloc_sarray)
629  ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
630 
631  /* Step 6: while (scan lines remain to be read) */
632  /* jpeg_read_scanlines(...); */
633 
634  /* Here we use the library's state variable cinfo.output_scanline as the
635  * loop counter, so that we don't have to keep track ourselves.
636  */
637  while (cinfo.output_scanline < cinfo.output_height) {
638  /* jpeg_read_scanlines expects an array of pointers to scanlines.
639  * Here the array is only one element long, but you could ask for
640  * more than one scanline at a time if that's more convenient.
641  */
642  (void) jpeg_read_scanlines(&cinfo, buffer, 1);
643  /* Assume put_scanline_someplace wants a pointer and sample count.
644  canceld for use directly with img_data
645  put_scanline_someplace(buffer[0], row_stride);
646  */
647  memcpy(data + (cinfo.output_scanline-1)*width*channels, buffer[0], row_stride);
648  }
649 
650  /* Step 7: Finish decompression */
651 
652  (void) jpeg_finish_decompress(&cinfo);
653  /* We can ignore the return value since suspension is not possible
654  * with the stdio data source.
655  */
656 
657  /* Step 8: Release JPEG decompression object */
658 
659  /* This is an important step since it will release a good deal of memory. */
660  jpeg_destroy_decompress(&cinfo);
661 
662  /* After finish_decompress, we can close the input file.
663  * Here we postpone it until after no more JPEG errors are possible,
664  * so as to simplify the setjmp error logic above. (Actually, I don't
665  * think that jpeg_destroy can do an error exit, but why assume anything...)
666  */
667  // will be done outside fclose(infile);
668 
669  /* At this point you may want to check to see whether any corrupt-data
670  * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
671  */
672 
673  /* And we're done! */
674  return 0;
675 }
676 
677 
678 JpegHandler::JpegHandler()
679 {
680  data_ = NULL;
681  dataLength_ = 0;
682  bufferSize_ = 0;
683  verbose_ = false;
684 }
685 
686 JpegHandler::JpegHandler(long size)
687 {
688  data_ = NULL;
689  dataLength_ = 0;
690  bufferSize_ = 0;
691  verbose_ = false;
692  Init(size);
693 }
694 
695 JpegHandler::~JpegHandler()
696 {
697  Release();
698 }
699 
700 int JpegHandler::Init(long size)
701 {
702  Release();
703 
704  // create buffer
705  data_ = (void *) new unsigned char[size];
706 
707  if (data_ == NULL) {
708  BIASERR("Could not create buffer!");
709  return -1;
710  } else {
711  bufferSize_ = size;
712  return 0;
713  }
714 }
715 
716 void JpegHandler::Release()
717 {
718  if (data_ != NULL) {
719  delete[] ((unsigned char *) data_);
720  }
721  data_ = NULL;
722  bufferSize_ = 0;
723 }
724 
725 int JpegHandler::
726 Compress(BIAS::Image<unsigned char> &srcImg, int quality)
727 {
728  if (!data_) {
729  BIASERR("Data buffer has not been set up. Call Init() first!");
730  return -1;
731  }
732 
733  image_height = srcImg.GetHeight();
734  image_width = srcImg.GetWidth();
735  image_channels = srcImg.GetChannelCount();
736  image_buffer = srcImg.GetImageData();
737 
738  dataLength_ = create_JPEG_file(data_, bufferSize_, quality);
739 
740  if (dataLength_ < 0) {
741  BIASERR("Error crunching JPEG image!");
742  dataLength_ = 0;
743  return -1;
744  }
745 
746  return 0;
747 }
748 
749 int JpegHandler::
750 Compress(unsigned int width, unsigned int height, unsigned int channels,
751  unsigned char* data, int quality)
752 {
753  if (!data_) {
754  BIASERR("Data buffer has not been set up. Call Init() first!");
755  return -1;
756  }
757 
758  image_height = height;
759  image_width = width;
760  image_channels = channels;
761  image_buffer = data;
762 
763  dataLength_ = create_JPEG_file(data_, bufferSize_, quality);
764 
765  if (dataLength_ < 0) {
766  BIASERR("Error crunching JPEG image!");
767  dataLength_ = 0;
768  return -1;
769  }
770 
771  return 0;
772 }
773 
774 int JpegHandler::
775 Decompress(BIAS::Image<unsigned char> &destImg, bool readComment)
776 {
777  if (!data_) {
778  BIASERR("Data buffer has not been set up. Call Init() first!");
779  return -1;
780  }
781 
782  return deflate_JPEG_file(data_, dataLength_, destImg, readComment, verbose_);
783 }
784 
785 int JpegHandler::
786 Decompress(unsigned int &width, unsigned int &height,
787  unsigned int &channels, unsigned char* &data)
788 {
789  if (!data_) {
790  BIASERR("Data buffer has not been set up. Call Init() first!");
791  return -1;
792  }
793 
794  return deflate_JPEG_file(data_, dataLength_, width, height,
795  channels, data, verbose_);
796 }
797 
798 int JpegHandler::
799 Compress(unsigned int width, unsigned int height, unsigned int channels,
800  unsigned char* inData, unsigned char *outData, long &outBytes,
801  int quality)
802 {
803  image_height = height;
804  image_width = width;
805  image_channels = channels;
806  image_buffer = inData;
807 
808  outBytes = create_JPEG_file(outData, width * height * channels, quality);
809 
810  if (outBytes < 0) {
811  BIASERR("Error crunching JPEG image!");
812  outBytes = 0;
813  return -1;
814  }
815  return 0;
816 }
817 
818 int JpegHandler::
819 Decompress(unsigned int &width, unsigned int &height, unsigned int &channels,
820  unsigned char* inData, long inBytes, unsigned char* outData)
821 {
822  return deflate_JPEG_file(inData, inBytes, width, height, channels, outData, verbose_);
823 }
824 
825 int JpegHandler::WriteJPEG(const string &filename) {
826 
827  if (!data_) {
828  BIASERR("Data buffer has not been set up. Call Init() first!");
829  return -1;
830  }
831 
832 #ifdef WIN32
833  FILE * output;
834  fopen_s(&output, filename.c_str(), "wb");
835 #else
836  FILE * output = fopen(filename.c_str(), "wb");
837 #endif
838 
839  if (output == NULL) {
840  BIASERR("Could not open output file" << filename << "!");
841  return -1;
842  }
843 
844  if (long(fwrite(data_, 1, dataLength_, output)) != dataLength_) {
845  BIASERR("Could not write data to file " << filename << " completely!");
846  return -1;
847  }
848 
849  fclose (output);
850 
851  return 0;
852 }
853 
854 int JpegHandler::ReadJPEG(const string &filename) {
855 
856  if (!data_) {
857  BIASERR("Data buffer has not been set up. Call Init() first!");
858  return -1;
859  }
860 
861 #ifdef WIN32
862  FILE * input;
863  fopen_s(&input, filename.c_str(), "rb");
864 #else
865  FILE * input = fopen(filename.c_str(), "rb");
866 #endif
867 
868  if (input == NULL) {
869  BIASERR("Could not read file " << filename << "!");
870  return -1;
871  }
872 
873  dataLength_ = 0;
874  fseek(input, 0L, SEEK_END);
875  dataLength_ = ftell(input);
876  rewind(input);
877 
878  if (data_ == NULL || bufferSize_ < dataLength_) {
879  BIASWARN("File (" << dataLength_ << " bytes) is too large for internal "
880  "buffer (" << bufferSize_ << " bytes), re-initialising buffer...");
881  if (Init(dataLength_) < 0)
882  return -1;
883  }
884 
885  if (long(fread(data_, 1, dataLength_, input)) != dataLength_) {
886  BIASERR("Failed to load file " << filename <<" completely!");
887  return -1;
888  }
889 
890  fclose (input);
891 
892  return 0;
893 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void Add(enum AppData::TAppData ID, unsigned int length, char *data)
Add a new binary meta datum.
Definition: MetaData.cpp:317
unsigned int GetWidth() const
Definition: ImageBase.hh:312
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
this class collects all additional data chunks of type AppData to be written into/read from an image ...
Definition: MetaData.hh:121
void SetMetaData(const MetaData &m)
Definition: ImageBase.hh:470
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153