JpegReader.cpp
Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <stdlib.h>
00003 #include <stdio.h>
00004 #include <sys/time.h>
00005 extern "C" {
00006 #include <jpeglib.h>
00007 }
00008 #include <string.h>
00009 #include <setjmp.h>
00010 
00011 #include "canon_vbc50i/libCanon/JpegReader.h"
00012 
00013 JpegReader::JpegReader()
00014 {
00015         width = height = 0;
00016         outputColorSpace = cmAuto;
00017         reqColorSpace = cmAuto;
00018         externaloutput = false;
00019         buffer = NULL;
00020         timestamp = 0;
00021 }
00022 
00023 JpegReader::~JpegReader()
00024 {
00025         //printf("~JpegReader\n");
00026         free(buffer);
00027         buffer = NULL;
00028         
00029 }
00030 
00031 void JpegReader::setTimeStamp()
00032 {
00033         struct timeval tv;
00034         gettimeofday(&tv,NULL);
00035         timestamp = tv.tv_sec + 1e-6*tv.tv_usec;
00036 }
00037 
00038 void JpegReader::setTimeStamp(double ts)
00039 {
00040         timestamp = ts;
00041 }
00042 
00043 struct my_error_mgr {
00044         struct jpeg_error_mgr pub;      /* "public" fields */
00045 
00046         jmp_buf setjmp_buffer;  /* for return to caller */
00047 };
00048 
00049 typedef struct my_error_mgr * my_error_ptr;
00050 
00051 /*
00052  * Here's the routine that will replace the standard error_exit method:
00053  */
00054 
00055 void my_error_exit (j_common_ptr cinfo)
00056 {
00057         /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
00058         my_error_ptr myerr = (my_error_ptr) cinfo->err;
00059 
00060         /* Always display the message. */
00061         /* We could postpone this until after returning, if we chose. */
00062         (*cinfo->err->output_message) (cinfo);
00063 
00064         /* Return control to the setjmp point */
00065         longjmp(myerr->setjmp_buffer, 1);
00066 }
00067 
00068 
00069 bool JpegReader::load(char * filename)
00070 {
00071         //printf("Reading\n");
00072         /* This struct contains the JPEG decompression parameters and pointers to
00073          * working space (which is allocated as needed by the JPEG library).
00074          */
00075         struct jpeg_decompress_struct cinfo;
00076         /* We use our private extension JPEG error handler.
00077          * Note that this struct must live as long as the main JPEG parameter
00078          * struct, to avoid dangling-pointer problems.
00079          */
00080         struct my_error_mgr jerr;
00081         /* More stuff */
00082         FILE * infile;          /* source file */
00083         int row_stride;         /* physical row width in output buffer */
00084         JSAMPARRAY lbuffer;             /* Output row buffer */
00085 
00086         /* In this example we want to open the input file before doing anything else,
00087          * so that the setjmp() error recovery below can assume the file is open.
00088          * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
00089          * requires it in order to read binary files.
00090          */
00091 
00092         if ((infile = fopen(filename, "rb")) == NULL) {
00093                 fprintf(stderr, "can't open %s\n", filename);
00094                 return false;
00095         }
00096         //printf("File %s opened\n",filename);
00097 
00098         /* Step 1: allocate and initialize JPEG decompression object */
00099 
00100         /* We set up the normal JPEG error routines, then override error_exit. */
00101         cinfo.err = jpeg_std_error(&jerr.pub);
00102         jerr.pub.error_exit = my_error_exit;
00103         /* Establish the setjmp return context for my_error_exit to use. */
00104         if (setjmp(jerr.setjmp_buffer)) {
00105                 /* If we get here, the JPEG code has signaled an error.
00106                  * We need to clean up the JPEG object, close the input file, and return.
00107                  */
00108                 jpeg_destroy_decompress(&cinfo);
00109                 fclose(infile);
00110                 return 0;
00111         }
00112         /* Now we can initialize the JPEG decompression object. */
00113         jpeg_create_decompress(&cinfo);
00114 
00115         /* Step 2: specify data source (eg, a file) */
00116 
00117         jpeg_stdio_src(&cinfo, infile);
00118 
00119         /* Step 3: read file parameters with jpeg_read_header() */
00120 
00121         int res = jpeg_read_header(&cinfo, TRUE);
00122         //printf("Header : %d\n",res);
00123         /* We can ignore the return value from jpeg_read_header since
00124          *   (a) suspension is not possible with the stdio data source, and
00125          *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
00126          * See libjpeg.doc for more info.
00127          */
00128 
00129 
00130         width = cinfo.image_width;
00131         height = cinfo.image_height;
00132         size = 0;
00133         switch (reqColorSpace) {
00134                 case cmAuto :
00135                         switch (cinfo.jpeg_color_space) {
00136                                 case JCS_GRAYSCALE:
00137                                         outputColorSpace = cmGray;
00138                                         cinfo.out_color_space = JCS_GRAYSCALE;
00139                                         size = width*height*sizeof(char);
00140                                         break;
00141                                 default :
00142                                         outputColorSpace = cmRGB;
00143                                         cinfo.out_color_space = JCS_RGB;
00144                                         size = width*height*sizeof(char)*3;
00145                                         break;
00146                         }
00147                         break;
00148                 case cmRGB:
00149                         outputColorSpace = cmRGB;
00150                         cinfo.out_color_space = JCS_RGB;
00151                         size = width*height*sizeof(char)*3;
00152                         break;
00153                 case cmYUV:
00154                         outputColorSpace = cmYUV;
00155                         cinfo.out_color_space = JCS_YCbCr;
00156                         size = width*height*sizeof(char)*3;
00157                         break;
00158                 case cmGray:
00159                 default :
00160                         outputColorSpace = cmGray;
00161                         cinfo.out_color_space = JCS_GRAYSCALE;
00162                         size = width*height*sizeof(char);
00163                         break;
00164                         
00165         }
00166                 
00167         if (!externaloutput) {
00168                 buffer = (unsigned char*)(realloc(buffer,size));
00169                 assert(buffer != NULL);
00170         }
00171 
00172         /* Step 4: set parameters for decompression */
00173 
00174         /* In this example, we don't need to change any of the defaults set by
00175          * jpeg_read_header(), so we do nothing here.
00176          */
00177 
00178         /* Step 5: Start decompressor */
00179 
00180         (void) jpeg_start_decompress(&cinfo);
00181         /* We can ignore the return value since suspension is not possible
00182          * with the stdio data source.
00183          */
00184 
00185         /* We may need to do some setup of our own at this point before reading
00186          * the data.  After jpeg_start_decompress() we have the correct scaled
00187          * output image dimensions available, as well as the output colormap
00188          * if we asked for color quantization.
00189          * In this example, we need to make an output work buffer of the right size.
00190          */ 
00191         /* JSAMPLEs per row in output buffer */
00192         row_stride = cinfo.output_width * cinfo.output_components;
00193         //printf("Output components: %d stride %d\n",cinfo.output_components,
00194         //              row_stride);
00195         /* Make a one-row-high sample array that will go away when done with image */
00196         lbuffer = (*cinfo.mem->alloc_sarray)
00197                 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00198 
00199         /* Step 6: while (scan lines remain to be read) */
00200         /*           jpeg_read_scanlines(...); */
00201 
00202         /* Here we use the library's state variable cinfo.output_scanline as the
00203          * loop counter, so that we don't have to keep track ourselves.
00204          */
00205         while (cinfo.output_scanline < cinfo.output_height) {
00206                 /* jpeg_read_scanlines expects an array of pointers to scanlines.
00207                  * Here the array is only one element long, but you could ask for
00208                  * more than one scanline at a time if that's more convenient.
00209                  */
00210                 res = jpeg_read_scanlines(&cinfo, lbuffer, 1);
00211                 //printf("scanline : %d %d\n",res,cinfo.output_scanline);
00212                 //assert((cinfo.output_scanline+1)*cinfo.output_width <= width*height);
00213                 memcpy(buffer + (cinfo.output_scanline-1)*row_stride, 
00214                                 lbuffer[0], row_stride);
00215         }
00216 
00217         /* Step 7: Finish decompression */
00218 
00219         (void) jpeg_finish_decompress(&cinfo);
00220         /* We can ignore the return value since suspension is not possible
00221          * with the stdio data source.
00222          */
00223 
00224         /* Step 8: Release JPEG decompression object */
00225 
00226         /* This is an important step since it will release a good deal of memory. */
00227         jpeg_destroy_decompress(&cinfo);
00228 
00229         /* After finish_decompress, we can close the input file.
00230          * Here we postpone it until after no more JPEG errors are possible,
00231          * so as to simplify the setjmp error logic above.  (Actually, I don't
00232          * think that jpeg_destroy can do an error exit, but why assume anything...)
00233          */
00234         fclose(infile);
00235 
00236         /* At this point you may want to check to see whether any corrupt-data
00237          * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
00238          */
00239 
00240         /* And we're done! */
00241         return true;
00242 }
00243 
00244 
00245 /*
00246  * Initialize source --- called by jpeg_read_header
00247  * before any data is actually read.
00248  */
00249 
00250 static void init_source (j_decompress_ptr cinfo)
00251 {
00252 }
00253 
00254 
00255 
00256 static boolean fill_input_buffer (j_decompress_ptr cinfo)
00257 {
00258   return FALSE;
00259 }
00260 
00261 
00262 static void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
00263 {
00264   cinfo->src->next_input_byte += (size_t) num_bytes;
00265   cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
00266 }
00267 
00268 
00269 static void term_source (j_decompress_ptr cinfo)
00270 {
00271   /* no work necessary here */
00272 }
00273 
00274 
00275 /*
00276  * Prepare for input from a stdio stream.
00277  * The caller must have already opened the stream, and is responsible
00278  * for closing it after finishing decompression.
00279  */
00280 
00281 static void jpeg_mem_src (j_decompress_ptr cinfo, 
00282                 const unsigned char * src, unsigned int srcsize)
00283 {
00284   /* The source object and input buffer are made permanent so that a series
00285    * of JPEG images can be read from the same file by calling jpeg_stdio_src
00286    * only before the first one.  (If we discarded the buffer at the end of
00287    * one image, we'd likely lose the start of the next one.)
00288    * This makes it unsafe to use this manager and a different source
00289    * manager serially with the same JPEG object.  Caveat programmer.
00290    */
00291   if (cinfo->src == NULL) {     /* first time for this JPEG object? */
00292     cinfo->src = (struct jpeg_source_mgr *)
00293       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00294                                   sizeof(jpeg_source_mgr));
00295         cinfo->src->next_input_byte = src;
00296         cinfo->src->bytes_in_buffer = srcsize;
00297   }
00298 
00299   cinfo->src->init_source = init_source;
00300   cinfo->src->fill_input_buffer = fill_input_buffer;
00301   cinfo->src->skip_input_data = skip_input_data;
00302   cinfo->src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
00303   cinfo->src->term_source = term_source;
00304 }
00305 
00306 
00307 
00308 bool JpegReader::load(const unsigned char * src, unsigned int srcsize)
00309 {
00310         //printf("Reading\n");
00311         /* This struct contains the JPEG decompression parameters and pointers to
00312          * working space (which is allocated as needed by the JPEG library).
00313          */
00314         struct jpeg_decompress_struct cinfo;
00315         /* We use our private extension JPEG error handler.
00316          * Note that this struct must live as long as the main JPEG parameter
00317          * struct, to avoid dangling-pointer problems.
00318          */
00319         struct my_error_mgr jerr;
00320         /* More stuff */
00321         int row_stride;         /* physical row width in output buffer */
00322         JSAMPARRAY lbuffer;             /* Output row buffer */
00323 
00324         /* Step 1: allocate and initialize JPEG decompression object */
00325 
00326         /* We set up the normal JPEG error routines, then override error_exit. */
00327         cinfo.err = jpeg_std_error(&jerr.pub);
00328         jerr.pub.error_exit = my_error_exit;
00329         /* Establish the setjmp return context for my_error_exit to use. */
00330         if (setjmp(jerr.setjmp_buffer)) {
00331                 /* If we get here, the JPEG code has signaled an error.
00332                  * We need to clean up the JPEG object, close the input file, and return.
00333                  */
00334                 jpeg_destroy_decompress(&cinfo);
00335                 return 0;
00336         }
00337         /* Now we can initialize the JPEG decompression object. */
00338         jpeg_create_decompress(&cinfo);
00339 
00340         /* Step 2: specify data source (eg, a file) */
00341 
00342         jpeg_mem_src(&cinfo, src, srcsize);
00343 
00344         /* Step 3: read file parameters with jpeg_read_header() */
00345 
00346         int res = jpeg_read_header(&cinfo, TRUE);
00347         //printf("Header : %d\n",res);
00348         /* We can ignore the return value from jpeg_read_header since
00349          *   (a) suspension is not possible with the stdio data source, and
00350          *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
00351          * See libjpeg.doc for more info.
00352          */
00353 
00354 
00355         width = cinfo.image_width;
00356         height = cinfo.image_height;
00357         size = 0;
00358         switch (reqColorSpace) {
00359                 case cmAuto :
00360                         switch (cinfo.jpeg_color_space) {
00361                                 case JCS_GRAYSCALE:
00362                                         outputColorSpace = cmGray;
00363                                         cinfo.out_color_space = JCS_GRAYSCALE;
00364                                         size = width*height*sizeof(char);
00365                                         break;
00366                                 case JCS_YCbCr:
00367                                         outputColorSpace = cmYUV;
00368                                         cinfo.out_color_space = JCS_YCbCr;
00369                                         size = width*height*sizeof(char)*3;
00370                                         break;
00371                                 default :
00372                                         outputColorSpace = cmRGB;
00373                                         cinfo.out_color_space = JCS_RGB;
00374                                         size = width*height*sizeof(char)*3;
00375                                         break;
00376                         }
00377                         break;
00378                 case cmRGB:
00379                         outputColorSpace = cmRGB;
00380                         cinfo.out_color_space = JCS_RGB;
00381                         size = width*height*sizeof(char)*3;
00382                         break;
00383                 case cmYUV:
00384                         outputColorSpace = cmYUV;
00385                         cinfo.out_color_space = JCS_YCbCr;
00386                         size = width*height*sizeof(char)*3;
00387                         break;
00388                 case cmGray:
00389                 default :
00390                         outputColorSpace = cmGray;
00391                         cinfo.out_color_space = JCS_GRAYSCALE;
00392                         size = width*height*sizeof(char);
00393                         break;
00394                         
00395         }
00396         if (!externaloutput) {
00397                 buffer = (unsigned char*)(realloc(buffer,size));
00398                 assert(buffer != NULL);
00399         }
00400 #if 0
00401         printf("Data stream: %dx%d, %s : %d bytes\n",width,height,
00402                         rgb?"RGB":"GRAY", size);
00403 #endif
00404 
00405         /* Step 4: set parameters for decompression */
00406 
00407         /* In this example, we don't need to change any of the defaults set by
00408          * jpeg_read_header(), so we do nothing here.
00409          */
00410 
00411         /* Step 5: Start decompressor */
00412 
00413         (void) jpeg_start_decompress(&cinfo);
00414         /* We can ignore the return value since suspension is not possible
00415          * with the stdio data source.
00416          */
00417 
00418         /* We may need to do some setup of our own at this point before reading
00419          * the data.  After jpeg_start_decompress() we have the correct scaled
00420          * output image dimensions available, as well as the output colormap
00421          * if we asked for color quantization.
00422          * In this example, we need to make an output work buffer of the right size.
00423          */ 
00424         /* JSAMPLEs per row in output buffer */
00425         row_stride = cinfo.output_width * cinfo.output_components;
00426         /* Make a one-row-high sample array that will go away when done with image */
00427         lbuffer = (*cinfo.mem->alloc_sarray)
00428                 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00429 
00430         /* Step 6: while (scan lines remain to be read) */
00431         /*           jpeg_read_scanlines(...); */
00432 
00433         /* Here we use the library's state variable cinfo.output_scanline as the
00434          * loop counter, so that we don't have to keep track ourselves.
00435          */
00436         while (cinfo.output_scanline < cinfo.output_height) {
00437                 /* jpeg_read_scanlines expects an array of pointers to scanlines.
00438                  * Here the array is only one element long, but you could ask for
00439                  * more than one scanline at a time if that's more convenient.
00440                  */
00441                 res = jpeg_read_scanlines(&cinfo, lbuffer, 1);
00442                 //printf("scanline : %d %d\n",res,cinfo.output_scanline);
00443                 //assert((cinfo.output_scanline+1)*cinfo.output_width <= width*height);
00444                 memcpy(buffer + (cinfo.output_scanline-1)*row_stride, 
00445                                 lbuffer[0], row_stride);
00446         }
00447 
00448         /* Step 7: Finish decompression */
00449 
00450         (void) jpeg_finish_decompress(&cinfo);
00451         /* We can ignore the return value since suspension is not possible
00452          * with the stdio data source.
00453          */
00454 
00455         /* Step 8: Release JPEG decompression object */
00456 
00457         /* This is an important step since it will release a good deal of memory. */
00458         jpeg_destroy_decompress(&cinfo);
00459 
00460         /* At this point you may want to check to see whether any corrupt-data
00461          * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
00462          */
00463 
00464         /* And we're done! */
00465         return true;
00466 }
00467 
00468 void JpegReader::setOutputColorSpace(ColorSpace cspace)
00469 {
00470         reqColorSpace = cspace;
00471 }
00472 


canon_vbc50i
Author(s): Cedric Pradalier
autogenerated on Mon Jan 6 2014 11:18:27