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
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;
00045
00046 jmp_buf setjmp_buffer;
00047 };
00048
00049 typedef struct my_error_mgr * my_error_ptr;
00050
00051
00052
00053
00054
00055 void my_error_exit (j_common_ptr cinfo)
00056 {
00057
00058 my_error_ptr myerr = (my_error_ptr) cinfo->err;
00059
00060
00061
00062 (*cinfo->err->output_message) (cinfo);
00063
00064
00065 longjmp(myerr->setjmp_buffer, 1);
00066 }
00067
00068
00069 bool JpegReader::load(char * filename)
00070 {
00071
00072
00073
00074
00075 struct jpeg_decompress_struct cinfo;
00076
00077
00078
00079
00080 struct my_error_mgr jerr;
00081
00082 FILE * infile;
00083 int row_stride;
00084 JSAMPARRAY lbuffer;
00085
00086
00087
00088
00089
00090
00091
00092 if ((infile = fopen(filename, "rb")) == NULL) {
00093 fprintf(stderr, "can't open %s\n", filename);
00094 return false;
00095 }
00096
00097
00098
00099
00100
00101 cinfo.err = jpeg_std_error(&jerr.pub);
00102 jerr.pub.error_exit = my_error_exit;
00103
00104 if (setjmp(jerr.setjmp_buffer)) {
00105
00106
00107
00108 jpeg_destroy_decompress(&cinfo);
00109 fclose(infile);
00110 return 0;
00111 }
00112
00113 jpeg_create_decompress(&cinfo);
00114
00115
00116
00117 jpeg_stdio_src(&cinfo, infile);
00118
00119
00120
00121 int res = jpeg_read_header(&cinfo, TRUE);
00122
00123
00124
00125
00126
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
00173
00174
00175
00176
00177
00178
00179
00180 (void) jpeg_start_decompress(&cinfo);
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 row_stride = cinfo.output_width * cinfo.output_components;
00193
00194
00195
00196 lbuffer = (*cinfo.mem->alloc_sarray)
00197 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00198
00199
00200
00201
00202
00203
00204
00205 while (cinfo.output_scanline < cinfo.output_height) {
00206
00207
00208
00209
00210 res = jpeg_read_scanlines(&cinfo, lbuffer, 1);
00211
00212
00213 memcpy(buffer + (cinfo.output_scanline-1)*row_stride,
00214 lbuffer[0], row_stride);
00215 }
00216
00217
00218
00219 (void) jpeg_finish_decompress(&cinfo);
00220
00221
00222
00223
00224
00225
00226
00227 jpeg_destroy_decompress(&cinfo);
00228
00229
00230
00231
00232
00233
00234 fclose(infile);
00235
00236
00237
00238
00239
00240
00241 return true;
00242 }
00243
00244
00245
00246
00247
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
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 static void jpeg_mem_src (j_decompress_ptr cinfo,
00282 const unsigned char * src, unsigned int srcsize)
00283 {
00284
00285
00286
00287
00288
00289
00290
00291 if (cinfo->src == NULL) {
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;
00303 cinfo->src->term_source = term_source;
00304 }
00305
00306
00307
00308 bool JpegReader::load(const unsigned char * src, unsigned int srcsize)
00309 {
00310
00311
00312
00313
00314 struct jpeg_decompress_struct cinfo;
00315
00316
00317
00318
00319 struct my_error_mgr jerr;
00320
00321 int row_stride;
00322 JSAMPARRAY lbuffer;
00323
00324
00325
00326
00327 cinfo.err = jpeg_std_error(&jerr.pub);
00328 jerr.pub.error_exit = my_error_exit;
00329
00330 if (setjmp(jerr.setjmp_buffer)) {
00331
00332
00333
00334 jpeg_destroy_decompress(&cinfo);
00335 return 0;
00336 }
00337
00338 jpeg_create_decompress(&cinfo);
00339
00340
00341
00342 jpeg_mem_src(&cinfo, src, srcsize);
00343
00344
00345
00346 int res = jpeg_read_header(&cinfo, TRUE);
00347
00348
00349
00350
00351
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
00406
00407
00408
00409
00410
00411
00412
00413 (void) jpeg_start_decompress(&cinfo);
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 row_stride = cinfo.output_width * cinfo.output_components;
00426
00427 lbuffer = (*cinfo.mem->alloc_sarray)
00428 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00429
00430
00431
00432
00433
00434
00435
00436 while (cinfo.output_scanline < cinfo.output_height) {
00437
00438
00439
00440
00441 res = jpeg_read_scanlines(&cinfo, lbuffer, 1);
00442
00443
00444 memcpy(buffer + (cinfo.output_scanline-1)*row_stride,
00445 lbuffer[0], row_stride);
00446 }
00447
00448
00449
00450 (void) jpeg_finish_decompress(&cinfo);
00451
00452
00453
00454
00455
00456
00457
00458 jpeg_destroy_decompress(&cinfo);
00459
00460
00461
00462
00463
00464
00465 return true;
00466 }
00467
00468 void JpegReader::setOutputColorSpace(ColorSpace cspace)
00469 {
00470 reqColorSpace = cspace;
00471 }
00472