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
00016 struct jpeg_source_mgr pub;
00017
00018
00019 std::vector<unsigned char>* src_vec;
00020 int curr_src_pos;
00021
00022
00023 JOCTET* buffer;
00024
00025 } buff_src_mgr;
00026
00027
00028
00029
00030
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
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
00063
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
00078
00079 METHODDEF(void)
00080 term_source (j_decompress_ptr cinfo)
00081 {
00082
00083 }
00084
00085 }
00086
00087
00088 IceImageDecompressor::IceImageDecompressor()
00089 { }
00090
00091
00092
00093
00094
00095
00096 Image<PixRGB<byte> > IceImageDecompressor::DecompressImage(std::vector<unsigned char> &source_buffer)
00097 {
00098
00099
00100
00101 cinfo.err = jpeg_std_error(&jerr);
00102
00103
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
00138
00139
00140
00141 GLOBAL(void) IceImageDecompressor::InitImageIceSource(std::vector<unsigned char>* source_buffer)
00142 {
00143 IIDC_NS::buff_src_mgr* src;
00144
00145
00146 if (cinfo.src == NULL)
00147 {
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;
00166 src->pub.term_source = IIDC_NS::term_source;
00167 src->pub.bytes_in_buffer = 0;
00168 src->pub.next_input_byte = NULL;
00169
00170 src->src_vec = source_buffer;
00171 src->curr_src_pos = 0;
00172
00173 }
00174 #endif