00001 /* 00002 This is a mercury driver for the independent jpeg group's jpeglib. 00003 00004 IF YOU WISH TO USE THIS, YOU MUST COMPLY WITH THE TERMS FOUND AT: 00005 http://www.ijg.org/ and get and include the library to use with this 00006 driver. Because of legal linking difficulties, we cannot include 00007 the source to this application by default. 00008 00009 IF YOU DO NOT WISH TO USE THIS, DO NOT COMPILE IT INTO YOUR APP. 00010 Mercury does not need this app to run. 00011 00012 00013 libJPG is Copyright (C) 1991-1997, Thomas G. Lane. 00014 This file is part of the Independent JPEG Group's software. 00015 For conditions of distribution and use, see the accompanying README file. 00016 This file contains additional configuration options that customize the 00017 JPEG software for special applications or support machine-dependent 00018 optimizations. Most users will not need to touch this file. 00019 */ 00020 00021 #include "MercuryTextureManager.h" 00022 #include "MercuryLog.h" 00023 #include <stdio.h> 00024 #include "jpeglib.h" 00025 #include <setjmp.h> 00026 00027 #if !defined(__GNUC__) 00028 #pragma comment(lib, "jpeg.lib") 00029 #endif 00030 00031 struct my_error_mgr { 00032 struct jpeg_error_mgr pub; /* "public" fields */ 00033 jmp_buf setjmp_buffer; /* for return to caller */ 00034 }; 00035 00036 typedef struct my_error_mgr * my_error_ptr; 00037 00038 00039 METHODDEF(void) 00040 my_error_exit (j_common_ptr cinfo) 00041 { 00042 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ 00043 my_error_ptr myerr = (my_error_ptr) cinfo->err; 00044 00045 /* Always display the message. */ 00046 /* We could postpone this until after returning, if we chose. */ 00047 (*cinfo->err->output_message) (cinfo); 00048 00049 LOG.Warn( "JPEG Decompression failed." ); 00050 00051 /* Return control to the setjmp point */ 00052 longjmp(myerr->setjmp_buffer, 1); 00053 } 00054 00055 class DataSource 00056 { 00057 public: 00058 struct jpeg_source_mgr pub;/* public fields */ 00059 00060 DataSource() : pData(0) { } 00061 ~DataSource() { SAFE_DELETE( pData ); } 00062 00063 JOCTET * pData; 00064 int iSize; 00065 int iPlace; 00066 }; 00067 00068 //Get info on these functions from jdatasrc.c 00069 void HGinit_source(j_decompress_ptr cinfo) 00070 { 00071 DataSource * pds = (DataSource*) cinfo->src; 00072 00073 } 00074 00075 unsigned char HGfill_input_buffer( j_decompress_ptr cinfo ) 00076 { 00077 DataSource * pds = (DataSource*) cinfo->src; 00078 00079 if( pds->iSize == pds->iPlace ) 00080 return false; 00081 00082 pds->pub.next_input_byte = pds->pData; 00083 pds->pub.bytes_in_buffer = pds->iSize; 00084 pds->iPlace = pds->iSize; 00085 return true; 00086 } 00087 00088 void HGskip_input_data(j_decompress_ptr cinfo, long num_bytes) 00089 { 00090 DataSource * pds = (DataSource*) cinfo->src; 00091 00092 //This looks queer... maybe we should see if it's ever getting called. 00093 pds->pub.next_input_byte += (size_t) num_bytes; 00094 pds->pub.bytes_in_buffer -= (size_t) num_bytes; 00095 } 00096 00097 unsigned char HGresync_to_restart(j_decompress_ptr cinfo, int desired) 00098 { 00099 return false; 00100 } 00101 00102 void HGterm_source(j_decompress_ptr cinfo) 00103 { 00104 //don't worry our pds gets deleted elsewhere. 00105 } 00106 00107 00108 RawImageData* LoadJPEG( MercuryFile * fp ) 00109 { 00110 RawImageData* rid = new RawImageData; 00111 DataSource pds; 00112 jpeg_decompress_struct cinfo; 00113 my_error_mgr jerr; 00114 // jpeg_source_mgr cmysource; 00115 00116 JSAMPARRAY buffer; /* Output row buffer */ 00117 int row_stride; /* physical row width in output buffer */ 00118 00119 00120 /* Step 1: allocate and initialize JPEG decompression object */ 00121 00122 /* We set up the normal JPEG error routines, then override error_exit. */ 00123 cinfo.err = jpeg_std_error(&jerr.pub); 00124 jerr.pub.error_exit = my_error_exit; 00125 /* Establish the setjmp return context for my_error_exit to use. */ 00126 if (setjmp(jerr.setjmp_buffer)) { 00127 /* If we get here, the JPEG code has signaled an error. 00128 * We need to clean up the JPEG object, close the input file, and return. 00129 */ 00130 jpeg_destroy_decompress(&cinfo); 00131 return 0; 00132 } 00133 /* Now we can initialize the JPEG decompression object. */ 00134 jpeg_create_decompress(&cinfo); 00135 00136 /* Step 2: specify data source (eg, a file) */ 00137 00138 //****************************************************************************// 00139 cinfo.src = (jpeg_source_mgr *)&pds; 00140 pds.pub.init_source = HGinit_source; 00141 pds.pub.fill_input_buffer = HGfill_input_buffer; 00142 pds.pub.skip_input_data = HGskip_input_data; 00143 pds.pub.resync_to_restart = HGresync_to_restart; 00144 pds.pub.term_source = HGterm_source; 00145 pds.pub.next_input_byte = 0; 00146 pds.pub.bytes_in_buffer = 0; 00147 pds.iSize = fp->Length(); 00148 pds.pData = new JOCTET[pds.iSize]; 00149 fp->Read( pds.pData, pds.iSize ); 00150 pds.iPlace = 0; 00151 /* Step 3: read file parameters with jpeg_read_header() */ 00152 00153 (void) jpeg_read_header(&cinfo, TRUE); 00154 /* We can ignore the return value from jpeg_read_header since 00155 * (a) suspension is not possible with the stdio data source, and 00156 * (b) we passed TRUE to reject a tables-only JPEG file as an error. 00157 * See libjpeg.doc for more info. 00158 */ 00159 00160 /* Step 4: set parameters for decompression */ 00161 00162 /* In this example, we don't need to change any of the defaults set by 00163 * jpeg_read_header(), so we do nothing here. 00164 */ 00165 00166 /* Step 5: Start decompressor */ 00167 00168 (void) jpeg_start_decompress(&cinfo); 00169 /* We can ignore the return value since suspension is not possible 00170 * with the stdio data source. 00171 */ 00172 00173 // rid-> 00174 rid->attrs.m_height = cinfo.image_height; 00175 rid->attrs.m_width = cinfo.image_width; 00176 rid->data = new unsigned char[cinfo.image_height * cinfo.image_width * 3]; 00177 00178 //Let's assume 72 dpi 00179 rid->attrs.m_dpi_y = rid->attrs.m_dpi_x = 72; 00180 rid->attrs.m_ColorByteType = RGB; 00181 cinfo.out_color_space = JCS_RGB; 00182 00183 00184 /* We may need to do some setup of our own at this point before reading 00185 * the data. After jpeg_start_decompress() we have the correct scaled 00186 * output image dimensions available, as well as the output colormap 00187 * if we asked for color quantization. 00188 * In this example, we need to make an output work buffer of the right size. 00189 */ 00190 /* JSAMPLEs per row in output buffer */ 00191 row_stride = cinfo.output_width * cinfo.output_components; 00192 /* Make a one-row-high sample array that will go away when done with image */ 00193 buffer = (*cinfo.mem->alloc_sarray) 00194 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); 00195 00196 /* Step 6: while (scan lines remain to be read) */ 00197 /* jpeg_read_scanlines(...); */ 00198 00199 /* Here we use the library's state variable cinfo.output_scanline as the 00200 * loop counter, so that we don't have to keep track ourselves. 00201 */ 00202 00203 while (cinfo.output_scanline < cinfo.output_height) { 00204 /* jpeg_read_scanlines expects an array of pointers to scanlines. 00205 * Here the array is only one element long, but you could ask for 00206 * more than one scanline at a time if that's more convenient. 00207 */ 00208 (void) jpeg_read_scanlines(&cinfo, buffer, 1); 00209 memcpy( rid->data + row_stride * ( cinfo.output_height-cinfo.output_scanline), *buffer, row_stride ); 00210 /* Assume put_scanline_someplace wants a pointer and sample count. */ 00211 //put_scanline_someplace(buffer[0], row_stride); 00212 //*****************************************************************************// 00213 00214 } 00215 00216 /* Step 7: Finish decompression */ 00217 00218 (void) jpeg_finish_decompress(&cinfo); 00219 /* We can ignore the return value since suspension is not possible 00220 * with the stdio data source. 00221 */ 00222 00223 /* Step 8: Release JPEG decompression object */ 00224 00225 /* This is an important step since it will release a good deal of memory. */ 00226 jpeg_destroy_decompress(&cinfo); 00227 00228 /* After finish_decompress, we can close the input file. 00229 * Here we postpone it until after no more JPEG errors are possible, 00230 * so as to simplify the setjmp error logic above. (Actually, I don't 00231 * think that jpeg_destroy can do an error exit, but why assume anything...) 00232 */ 00233 /* And we're done! */ 00234 return rid; 00235 } 00236 00237 RUN_STATEMENT_AT_BOOT( include_jpeg, IMAGEREADERREGISTER.AddDecoder( LoadJPEG, "ÿØÿ" ); ) 00238 00239 /* 00240 * (c) 2006 Charles Lohr 00241 * All rights reserved. 00242 * 00243 * Permission is hereby granted, free of charge, to any person obtaining a 00244 * copy of this software and associated documentation files (the 00245 * "Software"), to deal in the Software without restriction, including 00246 * without limitation the rights to use, copy, modify, merge, publish, 00247 * distribute, and/or sell copies of the Software, and to permit persons to 00248 * whom the Software is furnished to do so, provided that the above 00249 * copyright notice(s) and this permission notice appear in all copies of 00250 * the Software and that both the above copyright notice(s) and this 00251 * permission notice appear in supporting documentation. 00252 * 00253 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00254 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00255 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 00256 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS 00257 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT 00258 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00259 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00260 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00261 * PERFORMANCE OF THIS SOFTWARE. 00262 */ 00263