IceImageDecompressor.C

00001 #ifndef ICEIMAGEDECOMPRESSOR_C
00002 #define ICEIMAGEDECOMPRESSOR_C
00003 
00004 #include "Ice/IceImageDecompressor.H"
00005 #include <vector>
00006 #include <jpeglib.h>
00007 #include <jerror.h>
00008 
00009 #define INPUT_BUF_SIZE  4096LU
00010 
00011 namespace IIDC_NS
00012 {
00013   typedef struct
00014   {
00015     //The public fields common to source managers
00016     struct jpeg_source_mgr pub;
00017 
00018     //The compressed image source base pointer
00019     std::vector<unsigned char>* src_vec;
00020     int curr_src_pos;
00021 
00022     //The output buffer pointer
00023     JOCTET* buffer;
00024 
00025   } buff_src_mgr;
00026 
00027 
00028   ////////////////////////////////////////////////////////////////
00029   // Initialize the source -- called by jpeg_read_header before
00030   // any data is actually read
00031   ////////////////////////////////////////////////////////////////
00032   METHODDEF(void)
00033     init_source (j_decompress_ptr cinfo)
00034     {
00035       buff_src_mgr* src = (buff_src_mgr*) cinfo->src;
00036       src->curr_src_pos = 0;
00037     }
00038 
00039   ////////////////////////////////////////////////////////////////
00040   // Fill the input buffer -- called whenever bytes_in_buffer is 0
00041   ////////////////////////////////////////////////////////////////
00042   METHODDEF(boolean)
00043     fill_input_buffer (j_decompress_ptr cinfo)
00044     {
00045 
00046       buff_src_mgr* src = (buff_src_mgr*) cinfo->src;
00047 
00048       size_t nbytes;
00049 
00050       nbytes = std::min(INPUT_BUF_SIZE, src->src_vec->size() - src->curr_src_pos);
00051       unsigned char* src_base = &((*(src->src_vec))[0]);
00052 
00053 
00054       src->pub.next_input_byte =  src_base + src->curr_src_pos;
00055       src->pub.bytes_in_buffer = nbytes;
00056       src->curr_src_pos += nbytes;
00057 
00058       return TRUE;
00059     }
00060 
00061   ////////////////////////////////////////////////////////////////
00062   // Skip input data -- Skips num_bytes worth of data without
00063   // putting it into the buffer
00064   ////////////////////////////////////////////////////////////////
00065   METHODDEF(void)
00066     skip_input_data (j_decompress_ptr cinfo, long num_bytes)
00067     {
00068       buff_src_mgr* src = (buff_src_mgr*) cinfo->src;
00069 
00070       src->curr_src_pos += num_bytes;
00071 
00072       src->pub.next_input_byte += (size_t) num_bytes;
00073       src->pub.bytes_in_buffer -= (size_t) num_bytes;
00074     }
00075 
00076   ////////////////////////////////////////////////////////////////
00077   // Terminate source -- Nothing to do here
00078   ////////////////////////////////////////////////////////////////
00079   METHODDEF(void)
00080     term_source (j_decompress_ptr cinfo)
00081     {
00082       /* no work necessary here */
00083     }
00084 
00085 }
00086 
00087 // constuctor does nothing, maybe that needs FIXME
00088 IceImageDecompressor::IceImageDecompressor()
00089 { }
00090 
00091 ////////////////////////////////////////////////////////////////
00092 // Decompress an Image -- Pass this function an std::vector
00093 // filled with data from a compressed jpeg image, and it will
00094 // return to you an uncompressed Image< PixRGB<byte> >
00095 ////////////////////////////////////////////////////////////////
00096 Image<PixRGB<byte> > IceImageDecompressor::DecompressImage(std::vector<unsigned char> &source_buffer)
00097 {
00098   //Initialize our jpeg error handler to the default
00099   //(spit out non-fatal error messages on cerr, and
00100   // exit() on fatal errors)
00101   cinfo.err = jpeg_std_error(&jerr);
00102 
00103   //Create our jpeg decompression object
00104   jpeg_create_decompress(&cinfo);
00105 
00106   InitImageIceSource(&source_buffer);
00107 
00108   (void) jpeg_read_header(&cinfo, TRUE);
00109   (void) jpeg_start_decompress(&cinfo);
00110 
00111 
00112   assert(cinfo.output_components == 3);
00113   Image<PixRGB<byte> > outputImg(cinfo.output_width, cinfo.output_height, NO_INIT);
00114   JSAMPLE* img_ptr = reinterpret_cast<JSAMPLE*>(outputImg.getArrayPtr());
00115 
00116   int row_stride = cinfo.output_width * cinfo.output_components;
00117 
00118   JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)
00119     ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00120 
00121   while(cinfo.output_scanline < cinfo.output_height)
00122   {
00123     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
00124     std::memcpy(img_ptr, *buffer, row_stride);
00125     img_ptr+=row_stride;
00126   }
00127 
00128 
00129   (void) jpeg_finish_decompress(&cinfo);
00130   jpeg_destroy_decompress(&cinfo);
00131 
00132   return outputImg;
00133 }
00134 
00135 
00136 ////////////////////////////////////////////////////////////////
00137 // Initialize image source -- Just set up some variables and
00138 // allocate some buffer space (if necessary) for the
00139 // decompressor
00140 ////////////////////////////////////////////////////////////////
00141 GLOBAL(void) IceImageDecompressor::InitImageIceSource(std::vector<unsigned char>* source_buffer)
00142 {
00143   IIDC_NS::buff_src_mgr* src;
00144 
00145   //Allocate the source buffer
00146   if (cinfo.src == NULL)
00147   {        /* first time for this JPEG object? */
00148 
00149     cinfo.src = (struct jpeg_source_mgr *)
00150       (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
00151           sizeof(IIDC_NS::buff_src_mgr));
00152 
00153     src = (IIDC_NS::buff_src_mgr*) cinfo.src;
00154 
00155     src->buffer = (JOCTET *)
00156       (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
00157           INPUT_BUF_SIZE * sizeof(JOCTET));
00158   }
00159 
00160 
00161   src = (IIDC_NS::buff_src_mgr*) cinfo.src;
00162   src->pub.init_source = IIDC_NS::init_source;
00163   src->pub.fill_input_buffer = IIDC_NS::fill_input_buffer;
00164   src->pub.skip_input_data = IIDC_NS::skip_input_data;
00165   src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
00166   src->pub.term_source = IIDC_NS::term_source;
00167   src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
00168   src->pub.next_input_byte = NULL; /* until buffer loaded */
00169 
00170   src->src_vec      = source_buffer;
00171   src->curr_src_pos = 0;
00172 
00173 }
00174 #endif
Generated on Sun May 8 08:40:44 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3