Fawkes API
Fawkes Development Version
|
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