Panda3D
|
00001 // Filename: pnmFileTypeJPGReader.cxx 00002 // Created by: mike (19Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "pnmFileTypeJPG.h" 00016 00017 #ifdef HAVE_JPEG 00018 00019 #include "config_pnmimagetypes.h" 00020 #include "thread.h" 00021 00022 // 00023 // The following bit of code, for setting up jpeg_istream_src(), was 00024 // lifted from jpeglib, and modified to work with istream instead of 00025 // stdio. 00026 // 00027 00028 /* 00029 * jdatasrc.c 00030 * 00031 * Copyright (C) 1994-1996, Thomas G. Lane. 00032 * This file is part of the Independent JPEG Group's software. 00033 * For conditions of distribution and use, see the accompanying README file. 00034 * 00035 * This file contains decompression data source routines for the case of 00036 * reading JPEG data from a file (or any stdio stream). While these routines 00037 * are sufficient for most applications, some will want to use a different 00038 * source manager. 00039 * IMPORTANT: we assume that fread() will correctly transcribe an array of 00040 * JOCTETs from 8-bit-wide elements on external storage. If char is wider 00041 * than 8 bits on your machine, you may need to do some tweaking. 00042 */ 00043 00044 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 00045 extern "C" { 00046 #include <jpeglib.h> 00047 #include <jerror.h> 00048 } 00049 00050 00051 /* Expanded data source object for stdio input */ 00052 00053 typedef struct { 00054 struct jpeg_source_mgr pub; /* public fields */ 00055 00056 istream * infile; /* source stream */ 00057 JOCTET * buffer; /* start of buffer */ 00058 boolean start_of_file; /* have we gotten any data yet? */ 00059 } my_source_mgr; 00060 00061 typedef my_source_mgr * my_src_ptr; 00062 00063 #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ 00064 00065 00066 /* 00067 * Initialize source --- called by jpeg_read_header 00068 * before any data is actually read. 00069 */ 00070 00071 METHODDEF(void) 00072 init_source (j_decompress_ptr cinfo) 00073 { 00074 my_src_ptr src = (my_src_ptr) cinfo->src; 00075 00076 /* We reset the empty-input-file flag for each image, 00077 * but we don't clear the input buffer. 00078 * This is correct behavior for reading a series of images from one source. 00079 */ 00080 src->start_of_file = TRUE; 00081 } 00082 00083 00084 /* 00085 * Fill the input buffer --- called whenever buffer is emptied. 00086 * 00087 * In typical applications, this should read fresh data into the buffer 00088 * (ignoring the current state of next_input_byte & bytes_in_buffer), 00089 * reset the pointer & count to the start of the buffer, and return TRUE 00090 * indicating that the buffer has been reloaded. It is not necessary to 00091 * fill the buffer entirely, only to obtain at least one more byte. 00092 * 00093 * There is no such thing as an EOF return. If the end of the file has been 00094 * reached, the routine has a choice of ERREXIT() or inserting fake data into 00095 * the buffer. In most cases, generating a warning message and inserting a 00096 * fake EOI marker is the best course of action --- this will allow the 00097 * decompressor to output however much of the image is there. However, 00098 * the resulting error message is misleading if the real problem is an empty 00099 * input file, so we handle that case specially. 00100 * 00101 * In applications that need to be able to suspend compression due to input 00102 * not being available yet, a FALSE return indicates that no more data can be 00103 * obtained right now, but more may be forthcoming later. In this situation, 00104 * the decompressor will return to its caller (with an indication of the 00105 * number of scanlines it has read, if any). The application should resume 00106 * decompression after it has loaded more data into the input buffer. Note 00107 * that there are substantial restrictions on the use of suspension --- see 00108 * the documentation. 00109 * 00110 * When suspending, the decompressor will back up to a convenient restart point 00111 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer 00112 * indicate where the restart point will be if the current call returns FALSE. 00113 * Data beyond this point must be rescanned after resumption, so move it to 00114 * the front of the buffer rather than discarding it. 00115 */ 00116 00117 METHODDEF(boolean) 00118 fill_input_buffer (j_decompress_ptr cinfo) 00119 { 00120 my_src_ptr src = (my_src_ptr) cinfo->src; 00121 size_t nbytes; 00122 00123 src->infile->read((char *)src->buffer, INPUT_BUF_SIZE); 00124 nbytes = src->infile->gcount(); 00125 Thread::consider_yield(); 00126 00127 if (nbytes <= 0) { 00128 if (src->start_of_file) /* Treat empty input file as fatal error */ 00129 ERREXIT(cinfo, JERR_INPUT_EMPTY); 00130 WARNMS(cinfo, JWRN_JPEG_EOF); 00131 /* Insert a fake EOI marker */ 00132 src->buffer[0] = (JOCTET) 0xFF; 00133 src->buffer[1] = (JOCTET) JPEG_EOI; 00134 nbytes = 2; 00135 } 00136 00137 src->pub.next_input_byte = src->buffer; 00138 src->pub.bytes_in_buffer = nbytes; 00139 src->start_of_file = FALSE; 00140 00141 return TRUE; 00142 } 00143 00144 00145 /* 00146 * Skip data --- used to skip over a potentially large amount of 00147 * uninteresting data (such as an APPn marker). 00148 * 00149 * Writers of suspendable-input applications must note that skip_input_data 00150 * is not granted the right to give a suspension return. If the skip extends 00151 * beyond the data currently in the buffer, the buffer can be marked empty so 00152 * that the next read will cause a fill_input_buffer call that can suspend. 00153 * Arranging for additional bytes to be discarded before reloading the input 00154 * buffer is the application writer's problem. 00155 */ 00156 00157 METHODDEF(void) 00158 skip_input_data (j_decompress_ptr cinfo, long num_bytes) 00159 { 00160 my_src_ptr src = (my_src_ptr) cinfo->src; 00161 00162 /* Just a dumb implementation for now. Could use fseek() except 00163 * it doesn't work on pipes. Not clear that being smart is worth 00164 * any trouble anyway --- large skips are infrequent. 00165 */ 00166 if (num_bytes > 0) { 00167 while (num_bytes > (long) src->pub.bytes_in_buffer) { 00168 num_bytes -= (long) src->pub.bytes_in_buffer; 00169 (void) fill_input_buffer(cinfo); 00170 /* note we assume that fill_input_buffer will never return FALSE, 00171 * so suspension need not be handled. 00172 */ 00173 } 00174 src->pub.next_input_byte += (size_t) num_bytes; 00175 src->pub.bytes_in_buffer -= (size_t) num_bytes; 00176 } 00177 } 00178 00179 00180 /* 00181 * An additional method that can be provided by data source modules is the 00182 * resync_to_restart method for error recovery in the presence of RST markers. 00183 * For the moment, this source module just uses the default resync method 00184 * provided by the JPEG library. That method assumes that no backtracking 00185 * is possible. 00186 */ 00187 00188 00189 /* 00190 * Terminate source --- called by jpeg_finish_decompress 00191 * after all data has been read. Often a no-op. 00192 * 00193 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 00194 * application must deal with any cleanup that should happen even 00195 * for error exit. 00196 */ 00197 00198 METHODDEF(void) 00199 term_source (j_decompress_ptr cinfo) 00200 { 00201 /* no work necessary here */ 00202 } 00203 00204 00205 /* 00206 * Prepare for input from a stdio stream. 00207 * The caller must have already opened the stream, and is responsible 00208 * for closing it after finishing decompression. 00209 */ 00210 00211 GLOBAL(void) 00212 jpeg_istream_src (j_decompress_ptr cinfo, istream * infile) 00213 { 00214 my_src_ptr src; 00215 00216 /* The source object and input buffer are made permanent so that a series 00217 * of JPEG images can be read from the same file by calling jpeg_stdio_src 00218 * only before the first one. (If we discarded the buffer at the end of 00219 * one image, we'd likely lose the start of the next one.) 00220 * This makes it unsafe to use this manager and a different source 00221 * manager serially with the same JPEG object. Caveat programmer. 00222 */ 00223 if (cinfo->src == NULL) { /* first time for this JPEG object? */ 00224 cinfo->src = (struct jpeg_source_mgr *) 00225 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 00226 sizeof(my_source_mgr)); 00227 src = (my_src_ptr) cinfo->src; 00228 src->buffer = (JOCTET *) 00229 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 00230 INPUT_BUF_SIZE * sizeof(JOCTET)); 00231 } 00232 00233 src = (my_src_ptr) cinfo->src; 00234 src->pub.init_source = init_source; 00235 src->pub.fill_input_buffer = fill_input_buffer; 00236 src->pub.skip_input_data = skip_input_data; 00237 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ 00238 src->pub.term_source = term_source; 00239 src->infile = infile; 00240 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ 00241 src->pub.next_input_byte = NULL; /* until buffer loaded */ 00242 } 00243 00244 00245 00246 // 00247 // The rest of the code in this file is new to Panda. 00248 // 00249 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: PNMFileTypeJPG::Reader::Constructor 00252 // Access: Public 00253 // Description: 00254 //////////////////////////////////////////////////////////////////// 00255 PNMFileTypeJPG::Reader:: 00256 Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) : 00257 PNMReader(type, file, owns_file) 00258 { 00259 // Hope we can putback() more than one character. 00260 for (string::reverse_iterator mi = magic_number.rbegin(); 00261 mi != magic_number.rend(); 00262 ++mi) { 00263 _file->putback(*mi); 00264 } 00265 if (_file->fail()) { 00266 pnmimage_jpg_cat.error() 00267 << "Unable to put back magic number.\n"; 00268 _is_valid = false; 00269 return; 00270 } 00271 _is_valid = true; 00272 00273 /* Step 1: allocate and initialize JPEG decompression object */ 00274 00275 /* We set up the normal JPEG error routines, then override error_exit. */ 00276 _cinfo.err = jpeg_std_error(&_jerr.pub); 00277 00278 /* Now we can initialize the JPEG decompression object. */ 00279 jpeg_create_decompress(&_cinfo); 00280 00281 /* Step 2: specify data source (eg, a file) */ 00282 jpeg_istream_src(&_cinfo, file); 00283 00284 /* Step 3: let lib jpeg know that we want to read the comment field */ 00285 jpeg_save_markers(&_cinfo, JPEG_COM, 0xffff); 00286 00287 /* Step 4: read file parameters with jpeg_read_header() */ 00288 jpeg_read_header(&_cinfo, TRUE); 00289 /* We can ignore the return value from jpeg_read_header since 00290 * (a) suspension is not possible with the stdio data source, and 00291 * (b) we passed TRUE to reject a tables-only JPEG file as an error. 00292 * See libjpeg.doc for more info. 00293 */ 00294 00295 _num_channels = _cinfo.num_components; 00296 _x_size = (int)_cinfo.image_width; 00297 _y_size = (int)_cinfo.image_height; 00298 _maxval = MAXJSAMPLE; 00299 00300 /* Step 6: set parameters for decompression */ 00301 _cinfo.scale_num = 1; 00302 _cinfo.scale_denom = 1; 00303 } 00304 00305 //////////////////////////////////////////////////////////////////// 00306 // Function: PNMFileTypeJPG::Reader::prepare_read 00307 // Access: Public, Virtual 00308 // Description: This method will be called before read_data() or 00309 // read_row() is called. It instructs the reader to 00310 // initialize its data structures as necessary to 00311 // actually perform the read operation. 00312 // 00313 // After this call, _x_size and _y_size should reflect 00314 // the actual size that will be filled by read_data() 00315 // (as possibly modified by set_read_size()). 00316 //////////////////////////////////////////////////////////////////// 00317 void PNMFileTypeJPG::Reader:: 00318 prepare_read() { 00319 if (_has_read_size && _read_x_size != 0 && _read_y_size != 0) { 00320 // Attempt to get the scale close to our target scale. 00321 int x_reduction = _cinfo.image_width / _read_x_size; 00322 int y_reduction = _cinfo.image_height / _read_y_size; 00323 _cinfo.scale_denom = max(min(x_reduction, y_reduction), 1); 00324 } 00325 00326 /* Step 7: Start decompressor */ 00327 00328 jpeg_start_decompress(&_cinfo); 00329 /* We can ignore the return value since suspension is not possible 00330 * with the stdio data source. 00331 */ 00332 00333 _num_channels = _cinfo.output_components; 00334 _x_size = (int)_cinfo.output_width; 00335 _y_size = (int)_cinfo.output_height; 00336 } 00337 00338 //////////////////////////////////////////////////////////////////// 00339 // Function: PNMFileTypeJPG::Reader::Destructor 00340 // Access: Public 00341 // Description: 00342 //////////////////////////////////////////////////////////////////// 00343 PNMFileTypeJPG::Reader:: 00344 ~Reader() { 00345 if (_is_valid) { 00346 jpeg_destroy_decompress(&_cinfo); 00347 _is_valid = false; 00348 } 00349 } 00350 00351 //////////////////////////////////////////////////////////////////// 00352 // Function: PNMFileTypeJPG::Reader::read_data 00353 // Access: Public, Virtual 00354 // Description: Reads in an entire image all at once, storing it in 00355 // the pre-allocated _x_size * _y_size array and alpha 00356 // pointers. (If the image type has no alpha channel, 00357 // alpha is ignored.) Returns the number of rows 00358 // correctly read. 00359 // 00360 // Derived classes need not override this if they 00361 // instead provide supports_read_row() and read_row(), 00362 // below. 00363 //////////////////////////////////////////////////////////////////// 00364 int PNMFileTypeJPG::Reader:: 00365 read_data(xel *array, xelval *) { 00366 if (!_is_valid) { 00367 return 0; 00368 } 00369 JSAMPARRAY buffer; /* Output row buffer */ 00370 int row_stride; /* physical row width in output buffer */ 00371 00372 nassertr(_cinfo.output_components == 1 || _cinfo.output_components == 3, 0); 00373 00374 /* We may need to do some setup of our own at this point before reading 00375 * the data. After jpeg_start_decompress() we have the correct scaled 00376 * output image dimensions available, as well as the output colormap 00377 * if we asked for color quantization. 00378 * In this example, we need to make an output work buffer of the right size. 00379 */ 00380 /* JSAMPLEs per row in output buffer */ 00381 row_stride = _cinfo.output_width * _cinfo.output_components; 00382 /* Make a one-row-high sample array that will go away when done with image */ 00383 00384 buffer = (*_cinfo.mem->alloc_sarray) 00385 ((j_common_ptr) &_cinfo, JPOOL_IMAGE, row_stride, 1); 00386 00387 /* Step 6: while (scan lines remain to be read) */ 00388 /* jpeg_read_scanlines(...); */ 00389 00390 /* Here we use the library's state variable cinfo.output_scanline as the 00391 * loop counter, so that we don't have to keep track ourselves. 00392 */ 00393 int x = 0; 00394 while (_cinfo.output_scanline < _cinfo.output_height) { 00395 /* jpeg_read_scanlines expects an array of pointers to scanlines. 00396 * Here the array is only one element long, but you could ask for 00397 * more than one scanline at a time if that's more convenient. 00398 */ 00399 jpeg_read_scanlines(&_cinfo, buffer, 1); 00400 /* Assume put_scanline_someplace wants a pointer and sample count. */ 00401 //put_scanline_someplace(buffer[0], row_stride); 00402 JSAMPROW bufptr = buffer[0]; 00403 for (int i = 0; i < row_stride; i += _cinfo.output_components) { 00404 if (_cinfo.output_components == 1) { 00405 xelval val = (xelval)bufptr[i]; 00406 nassertr(x < _x_size * _y_size, 0); 00407 PNM_ASSIGN1(array[x], val); 00408 } else { 00409 xelval red, grn, blu; 00410 red = (xelval)bufptr[i]; 00411 grn = (xelval)bufptr[i+1]; 00412 blu = (xelval)bufptr[i+2]; 00413 nassertr(x < _x_size * _y_size, 0); 00414 PPM_ASSIGN(array[x], red, grn, blu); 00415 } 00416 x++; 00417 } 00418 Thread::consider_yield(); 00419 } 00420 00421 /* Step 7: Finish decompression */ 00422 00423 jpeg_finish_decompress(&_cinfo); 00424 00425 /* We can ignore the return value since suspension is not possible 00426 * with the stdio data source. 00427 */ 00428 00429 /* At this point you may want to check to see whether any corrupt-data 00430 * warnings occurred (test whether jerr.pub.num_warnings is nonzero). 00431 */ 00432 if (_jerr.pub.num_warnings) { 00433 pnmimage_jpg_cat.warning() 00434 << "Jpeg data may be corrupt" << endl; 00435 } 00436 00437 return _y_size; 00438 } 00439 00440 #endif // HAVE_JPEG