00001 // Filename: pnmFileTypeJPGReader.cxx 00002 // Created by: mike (19Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "pnmFileTypeJPG.h" 00020 #include "config_pnmimagetypes.h" 00021 00022 00023 // 00024 // The following bit of code, for setting up jpeg_istream_src(), was 00025 // lifted from jpeglib, and modified to work with istream instead of 00026 // stdio. 00027 // 00028 00029 /* 00030 * jdatasrc.c 00031 * 00032 * Copyright (C) 1994-1996, Thomas G. Lane. 00033 * This file is part of the Independent JPEG Group's software. 00034 * For conditions of distribution and use, see the accompanying README file. 00035 * 00036 * This file contains decompression data source routines for the case of 00037 * reading JPEG data from a file (or any stdio stream). While these routines 00038 * are sufficient for most applications, some will want to use a different 00039 * source manager. 00040 * IMPORTANT: we assume that fread() will correctly transcribe an array of 00041 * JOCTETs from 8-bit-wide elements on external storage. If char is wider 00042 * than 8 bits on your machine, you may need to do some tweaking. 00043 */ 00044 00045 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 00046 extern "C" { 00047 #include <jpeglib.h> 00048 #include <jerror.h> 00049 } 00050 00051 00052 /* Expanded data source object for stdio input */ 00053 00054 typedef struct { 00055 struct jpeg_source_mgr pub; /* public fields */ 00056 00057 istream * infile; /* source stream */ 00058 JOCTET * buffer; /* start of buffer */ 00059 boolean start_of_file; /* have we gotten any data yet? */ 00060 } my_source_mgr; 00061 00062 typedef my_source_mgr * my_src_ptr; 00063 00064 #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ 00065 00066 00067 /* 00068 * Initialize source --- called by jpeg_read_header 00069 * before any data is actually read. 00070 */ 00071 00072 METHODDEF(void) 00073 init_source (j_decompress_ptr cinfo) 00074 { 00075 my_src_ptr src = (my_src_ptr) cinfo->src; 00076 00077 /* We reset the empty-input-file flag for each image, 00078 * but we don't clear the input buffer. 00079 * This is correct behavior for reading a series of images from one source. 00080 */ 00081 src->start_of_file = TRUE; 00082 } 00083 00084 00085 /* 00086 * Fill the input buffer --- called whenever buffer is emptied. 00087 * 00088 * In typical applications, this should read fresh data into the buffer 00089 * (ignoring the current state of next_input_byte & bytes_in_buffer), 00090 * reset the pointer & count to the start of the buffer, and return TRUE 00091 * indicating that the buffer has been reloaded. It is not necessary to 00092 * fill the buffer entirely, only to obtain at least one more byte. 00093 * 00094 * There is no such thing as an EOF return. If the end of the file has been 00095 * reached, the routine has a choice of ERREXIT() or inserting fake data into 00096 * the buffer. In most cases, generating a warning message and inserting a 00097 * fake EOI marker is the best course of action --- this will allow the 00098 * decompressor to output however much of the image is there. However, 00099 * the resulting error message is misleading if the real problem is an empty 00100 * input file, so we handle that case specially. 00101 * 00102 * In applications that need to be able to suspend compression due to input 00103 * not being available yet, a FALSE return indicates that no more data can be 00104 * obtained right now, but more may be forthcoming later. In this situation, 00105 * the decompressor will return to its caller (with an indication of the 00106 * number of scanlines it has read, if any). The application should resume 00107 * decompression after it has loaded more data into the input buffer. Note 00108 * that there are substantial restrictions on the use of suspension --- see 00109 * the documentation. 00110 * 00111 * When suspending, the decompressor will back up to a convenient restart point 00112 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer 00113 * indicate where the restart point will be if the current call returns FALSE. 00114 * Data beyond this point must be rescanned after resumption, so move it to 00115 * the front of the buffer rather than discarding it. 00116 */ 00117 00118 METHODDEF(boolean) 00119 fill_input_buffer (j_decompress_ptr cinfo) 00120 { 00121 my_src_ptr src = (my_src_ptr) cinfo->src; 00122 size_t nbytes; 00123 00124 src->infile->read((char *)src->buffer, INPUT_BUF_SIZE); 00125 nbytes = src->infile->gcount(); 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: read file parameters with jpeg_read_header() */ 00285 00286 jpeg_read_header(&_cinfo, TRUE); 00287 /* We can ignore the return value from jpeg_read_header since 00288 * (a) suspension is not possible with the stdio data source, and 00289 * (b) we passed TRUE to reject a tables-only JPEG file as an error. 00290 * See libjpeg.doc for more info. 00291 */ 00292 00293 /* Step 4: set parameters for decompression */ 00294 _cinfo.scale_num = jpeg_scale_num; 00295 _cinfo.scale_denom = jpeg_scale_denom; 00296 00297 /* Step 5: Start decompressor */ 00298 00299 jpeg_start_decompress(&_cinfo); 00300 /* We can ignore the return value since suspension is not possible 00301 * with the stdio data source. 00302 */ 00303 00304 _num_channels = _cinfo.output_components; 00305 _x_size = (int)_cinfo.output_width; 00306 _y_size = (int)_cinfo.output_height; 00307 _maxval = MAXJSAMPLE; 00308 } 00309 00310 //////////////////////////////////////////////////////////////////// 00311 // Function: PNMFileTypeJPG::Reader::Destructor 00312 // Access: Public 00313 // Description: 00314 //////////////////////////////////////////////////////////////////// 00315 PNMFileTypeJPG::Reader:: 00316 ~Reader() { 00317 if (_is_valid) { 00318 jpeg_destroy_decompress(&_cinfo); 00319 _is_valid = false; 00320 } 00321 } 00322 00323 //////////////////////////////////////////////////////////////////// 00324 // Function: PNMFileTypeJPG::Reader::read_data 00325 // Access: Public, Virtual 00326 // Description: Reads in an entire image all at once, storing it in 00327 // the pre-allocated _x_size * _y_size array and alpha 00328 // pointers. (If the image type has no alpha channel, 00329 // alpha is ignored.) Returns the number of rows 00330 // correctly read. 00331 // 00332 // Derived classes need not override this if they 00333 // instead provide supports_read_row() and read_row(), 00334 // below. 00335 //////////////////////////////////////////////////////////////////// 00336 int PNMFileTypeJPG::Reader:: 00337 read_data(xel *array, xelval *) { 00338 if (!_is_valid) { 00339 return 0; 00340 } 00341 JSAMPARRAY buffer; /* Output row buffer */ 00342 int row_stride; /* physical row width in output buffer */ 00343 00344 nassertr(_cinfo.output_components == 1 || _cinfo.output_components == 3, 0); 00345 00346 /* We may need to do some setup of our own at this point before reading 00347 * the data. After jpeg_start_decompress() we have the correct scaled 00348 * output image dimensions available, as well as the output colormap 00349 * if we asked for color quantization. 00350 * In this example, we need to make an output work buffer of the right size. 00351 */ 00352 /* JSAMPLEs per row in output buffer */ 00353 row_stride = _cinfo.output_width * _cinfo.output_components; 00354 /* Make a one-row-high sample array that will go away when done with image */ 00355 00356 buffer = (*_cinfo.mem->alloc_sarray) 00357 ((j_common_ptr) &_cinfo, JPOOL_IMAGE, row_stride, 1); 00358 00359 /* Step 6: while (scan lines remain to be read) */ 00360 /* jpeg_read_scanlines(...); */ 00361 00362 /* Here we use the library's state variable cinfo.output_scanline as the 00363 * loop counter, so that we don't have to keep track ourselves. 00364 */ 00365 int x = 0; 00366 while (_cinfo.output_scanline < _cinfo.output_height) { 00367 /* jpeg_read_scanlines expects an array of pointers to scanlines. 00368 * Here the array is only one element long, but you could ask for 00369 * more than one scanline at a time if that's more convenient. 00370 */ 00371 jpeg_read_scanlines(&_cinfo, buffer, 1); 00372 /* Assume put_scanline_someplace wants a pointer and sample count. */ 00373 //put_scanline_someplace(buffer[0], row_stride); 00374 JSAMPROW bufptr = buffer[0]; 00375 for (int i = 0; i < row_stride; i += _cinfo.output_components) { 00376 if (_cinfo.output_components == 1) { 00377 xelval val = (xelval)bufptr[i]; 00378 nassertr(x < _x_size * _y_size, 0); 00379 PNM_ASSIGN1(array[x], val); 00380 } else { 00381 xelval red, grn, blu; 00382 red = (xelval)bufptr[i]; 00383 grn = (xelval)bufptr[i+1]; 00384 blu = (xelval)bufptr[i+2]; 00385 nassertr(x < _x_size * _y_size, 0); 00386 PPM_ASSIGN(array[x], red, grn, blu); 00387 } 00388 x++; 00389 } 00390 } 00391 00392 /* Step 7: Finish decompression */ 00393 00394 jpeg_finish_decompress(&_cinfo); 00395 00396 /* We can ignore the return value since suspension is not possible 00397 * with the stdio data source. 00398 */ 00399 00400 /* At this point you may want to check to see whether any corrupt-data 00401 * warnings occurred (test whether jerr.pub.num_warnings is nonzero). 00402 */ 00403 if (_jerr.pub.num_warnings) { 00404 pnmimage_jpg_cat.warning() 00405 << "Jpeg data may be corrupt" << endl; 00406 } 00407 00408 return _y_size; 00409 }