ImageLoaderJPEG.cpp

Go to the documentation of this file.
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 

Hosted by SourceForge.net Logo