jpeg_decompressor.cpp

00001 
00002 /***************************************************************************
00003  *  imagedecompressor.h - image de-compressor interface
00004  *
00005  *  Created: July 2007 (Sci-Bono, South Africa, B&B)
00006  *  Copyright  2006-2007  Daniel Beck
00007  *             2007       Tim Niemueller [www.niemueller.de]
00008  *
00009  ****************************************************************************/
00010 
00011 /*  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version. A runtime exception applies to
00015  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00016  *
00017  *  This program is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *  GNU Library General Public License for more details.
00021  *
00022  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00023  */
00024 
00025 #include <fvutils/color/conversions.h>
00026 #include <fvutils/compression/jpeg_decompressor.h>
00027 
00028 #include <sys/types.h>
00029 #include <cstdio>
00030 #include <cstdlib>
00031 
00032 extern "C" {
00033 #include <jpeglib.h>
00034 #include <jerror.h>
00035 }
00036 
00037 namespace firevision {
00038 #if 0 /* just to make Emacs auto-indent happy */
00039 }
00040 #endif
00041 
00042 ///@cond INTERNALS
00043 
00044 typedef struct {
00045   struct jpeg_source_mgr pub;
00046 
00047   JOCTET * buffer;
00048 } my_source_mgr;
00049 
00050 typedef my_source_mgr * my_src_ptr;
00051 
00052 
00053 METHODDEF(void)
00054 init_source (j_decompress_ptr cinfo)
00055 {
00056 }
00057 
00058 
00059 METHODDEF(boolean)
00060 fill_input_buffer (j_decompress_ptr cinfo)
00061 {
00062   return TRUE;
00063 }
00064 
00065 METHODDEF(void)
00066 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
00067 {
00068   my_src_ptr src = (my_src_ptr) cinfo->src;
00069   /* Just a dumb implementation for now.  Could use fseek() except
00070    * it doesn't work on pipes.  Not clear that being smart is worth
00071    * any trouble anyway --- large skips are infrequent.
00072    */
00073   if (num_bytes > 0) {
00074     while (num_bytes > (long) src->pub.bytes_in_buffer) {
00075       num_bytes -= (long) src->pub.bytes_in_buffer;
00076       (void) fill_input_buffer(cinfo);
00077       /* note we assume that fill_input_buffer will never return FALSE,
00078        * so suspension need not be handled.
00079        */
00080     }
00081     src->pub.next_input_byte += (size_t) num_bytes;
00082     src->pub.bytes_in_buffer -= (size_t) num_bytes;
00083   }
00084 }
00085 
00086 METHODDEF(void)
00087 term_source (j_decompress_ptr cinfo)
00088 {
00089   /* no work necessary here */
00090 }
00091 
00092 GLOBAL(void)
00093 my_mem_src (j_decompress_ptr cinfo, JOCTET * buffer, size_t bytes)
00094 {
00095   my_src_ptr src;
00096 
00097  if (cinfo->src == NULL) {      /* first time for this JPEG object? */
00098    cinfo->src = (struct jpeg_source_mgr *)
00099      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00100                                  sizeof(my_source_mgr));
00101    src = (my_src_ptr) cinfo->src;
00102 //    src->buffer = (JOCTET *)
00103 //      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00104 //                               INPUT_BUF_SIZE * SIZEOF(JOCTET));
00105   }
00106 
00107   src = (my_src_ptr) cinfo->src;
00108   src->pub.init_source = init_source;
00109   src->pub.fill_input_buffer = fill_input_buffer;
00110   src->pub.skip_input_data = skip_input_data;
00111   src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
00112   src->pub.term_source = term_source;
00113   src->pub.bytes_in_buffer = bytes;
00114   src->pub.next_input_byte = buffer;
00115 }
00116 
00117 /// @endcond
00118 
00119 /** @class JpegImageDecompressor <fvutils/compression/jpeg_decompressor.h>
00120  * Decompressor for JPEG images.
00121  * @author Daniel Beck
00122  * @author Tim Niemueller
00123  */
00124 
00125 /** Constructor. */
00126 JpegImageDecompressor::JpegImageDecompressor()
00127 {
00128 }
00129 
00130 void
00131 JpegImageDecompressor::decompress()
00132 {
00133   JSAMPROW row_pointer[1];
00134   unsigned long location = 0;
00135   unsigned char *buffer;
00136         
00137   // JPEG decompression
00138   // Allocate and initialize a JPEG decompression object
00139   struct jpeg_decompress_struct cinfo;
00140   struct jpeg_error_mgr jerr;
00141   
00142   cinfo.err = jpeg_std_error(&jerr);
00143   jpeg_create_decompress(&cinfo);
00144 
00145   // Specify the source of the compressed data
00146   my_mem_src(&cinfo, _compressed_buffer, _compressed_buffer_size);
00147 
00148   // Call jpeg_read_header() to obtain image info
00149   jpeg_read_header(&cinfo, TRUE);
00150 
00151   // set output color space
00152   //  cinfo.out_color_space = JCS_YCbCr;
00153   
00154   // Set parameters for decompression
00155   
00156   // jpeg_start_decompress(...);
00157   jpeg_start_decompress(&cinfo);
00158 
00159   buffer = (unsigned char*)malloc( cinfo.output_width * cinfo.output_height * cinfo.num_components );
00160   
00161   row_pointer[0] = (unsigned char *)malloc( cinfo.output_width * cinfo.num_components );
00162   
00163   // while (scan lines remain to be read)
00164   //   jpeg_read_scanlines(...);
00165   while( cinfo.output_scanline < cinfo.image_height )
00166     {
00167       jpeg_read_scanlines( &cinfo, row_pointer, 1 );
00168       for( unsigned int i=0; i < cinfo.image_width * cinfo.num_components; i++)
00169         buffer[location++] = row_pointer[0][i];
00170     }
00171   
00172   // jpeg_finish_decompress(...);
00173   jpeg_finish_decompress(&cinfo);
00174   
00175   // Release the JPEG decompression object
00176   jpeg_destroy_decompress(&cinfo);
00177   
00178   free(row_pointer[0]);
00179   
00180 //   FILE* imagefile = fopen("asdf.ppm", "w");
00181 
00182 //   fprintf(imagefile,"P6\n%u %u\n255\n", image_data.width,
00183 //           image_data.height );
00184 //   fwrite(buffer, 1, cinfo.output_width * cinfo.num_components * cinfo.image_width, imagefile);
00185 //   fclose(imagefile);
00186 
00187   // convert to yuv422packed and store in member frame_buffer
00188   convert(RGB, YUV422_PLANAR, buffer, _decompressed_buffer, cinfo.output_width, cinfo.output_height);
00189 
00190   free(buffer);
00191 
00192 }
00193 
00194 } // end namespace firevision

Generated on 1 Mar 2011 for Fawkes API by  doxygen 1.6.1