00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "provider_jpeg_generic.h"
00014 #include <setjmp.h>
00015 #include <jerror.h>
00016
00017 #define INPUT_BUF_SIZE 4096
00018
00019 CL_JPEGProvider_Generic::CL_JPEGProvider_Generic(
00020 CL_String name,
00021 CL_InputSourceProvider *_provider,
00022 bool _transparent,
00023 bool _ignore_alphachannel)
00024 {
00025 if (_provider == NULL)
00026 {
00027 input_provider = CL_InputSourceProvider::create_file_provider(".");
00028 }
00029 else
00030 {
00031 input_provider = _provider->clone();
00032 }
00033
00034 ignore_alphachannel = _ignore_alphachannel;
00035 transparent = _transparent;
00036 use_alphapixels = transparent && !ignore_alphachannel;
00037
00038 trans_redcol = 0;
00039 trans_greencol = 0;
00040 trans_bluecol = 0;
00041
00042 locked = 0;
00043 filename = name;
00044 image = NULL;
00045 }
00046
00047 CL_JPEGProvider_Generic::~CL_JPEGProvider_Generic()
00048 {
00049 perform_unlock();
00050 delete input_provider;
00051 }
00052
00053 unsigned int CL_JPEGProvider_Generic::get_red_mask() const
00054 {
00055 return CL_Color::get_red_mask(RGB888);
00056 }
00057
00058 unsigned int CL_JPEGProvider_Generic::get_green_mask() const
00059 {
00060 return CL_Color::get_green_mask(RGB888);
00061 }
00062
00063 unsigned int CL_JPEGProvider_Generic::get_blue_mask() const
00064 {
00065 return CL_Color::get_blue_mask(RGB888);
00066 }
00067
00068 unsigned int CL_JPEGProvider_Generic::get_alpha_mask() const
00069 {
00070 return CL_Color::get_alpha_mask(RGB888);
00071 }
00072
00073 void *CL_JPEGProvider_Generic::get_data() const
00074 {
00075 return image;
00076 }
00077
00078
00079
00080
00081
00082
00083 void CL_JPEGProvider_Generic::perform_lock()
00084 {
00085 if (locked++) return;
00086
00087 struct jpeg_error_mgr jerr;
00088 struct jpeg_decompress_struct cinfo;
00089
00090 JSAMPARRAY buffer;
00091 int row_stride;
00092
00093 input_source = input_provider->open_source(filename);
00094
00095 cinfo.err = jpeg_std_error(&jerr);
00096 jpeg_create_decompress(&cinfo);
00097 jpeg_InputSource_src(&cinfo, this);
00098 jpeg_read_header(&cinfo, TRUE);
00099 jpeg_start_decompress(&cinfo);
00100
00101 row_stride = cinfo.output_width * cinfo.output_components;
00102
00103 width = cinfo.output_width;
00104 height = cinfo.output_height;
00105 pitch = width * 3;
00106
00107
00108 buffer = (*cinfo.mem->alloc_sarray)
00109 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 32);
00110
00111 image = new unsigned char[get_pitch() * cinfo.output_height];
00112
00113
00114 if (cinfo.output_components == 3)
00115 {
00116 while (cinfo.output_scanline < cinfo.output_height)
00117 {
00118 jpeg_read_scanlines(&cinfo, buffer, 1);
00119
00120 for(unsigned int i=0; i < get_pitch(); i += 3)
00121 {
00122 image[pitch * (cinfo.output_scanline - 1) + i + 0] = buffer[0][i + 2];
00123 image[pitch * (cinfo.output_scanline - 1) + i + 1] = buffer[0][i + 1];
00124 image[pitch * (cinfo.output_scanline - 1) + i + 2] = buffer[0][i + 0];
00125 }
00126 }
00127 }
00128
00129 else if (cinfo.output_components == 1)
00130 {
00131 while (cinfo.output_scanline < cinfo.output_height)
00132 {
00133 jpeg_read_scanlines(&cinfo, buffer, 1);
00134
00135 for(int i=0; i < width; i += 1)
00136 {
00137 image[pitch * (cinfo.output_scanline - 1) + 3*i + 0] = buffer[0][i];
00138 image[pitch * (cinfo.output_scanline - 1) + 3*i + 1] = buffer[0][i];
00139 image[pitch * (cinfo.output_scanline - 1) + 3*i + 2] = buffer[0][i];
00140 }
00141 }
00142 }
00143 else
00144 {
00145 std::cout << "CL_JPEGProvider: Unsupported color completion: " << cinfo.output_components << std::endl;
00146 }
00147
00148 jpeg_finish_decompress(&cinfo);
00149 jpeg_destroy_decompress(&cinfo);
00150 delete input_source;
00151 input_source = 0;
00152 }
00153
00154 void CL_JPEGProvider_Generic::perform_unlock()
00155 {
00156 if (!(--locked))
00157 {
00158 delete[] image;
00159 image = NULL;
00160 }
00161 }
00162
00163 void CL_JPEGProvider_Generic::jpeg_InputSource_src (j_decompress_ptr cinfo, CL_JPEGProvider_Generic* provider)
00164 {
00165 InputSource_src_ptr src;
00166
00167 if (cinfo->src == NULL)
00168 {
00169 cinfo->src = (struct jpeg_source_mgr*)
00170 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00171 sizeof(InputSource_source_mgr));
00172 src = (InputSource_src_ptr) cinfo->src;
00173 src->buffer = (JOCTET *)
00174 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00175 INPUT_BUF_SIZE * sizeof(JOCTET));
00176 }
00177
00178 src = (InputSource_src_ptr) cinfo->src;
00179 src->pub.init_source = CL_JPEGProvider_Generic::init_source;
00180 src->pub.fill_input_buffer = CL_JPEGProvider_Generic::fill_input_buffer;
00181 src->pub.skip_input_data = CL_JPEGProvider_Generic::skip_input_data;
00182 src->pub.resync_to_restart = jpeg_resync_to_restart;
00183 src->pub.term_source = CL_JPEGProvider_Generic::term_source;
00184 src->jpeg_provider = provider;
00185 src->pub.bytes_in_buffer = 0;
00186 src->pub.next_input_byte = NULL;
00187 }
00188
00189 void CL_JPEGProvider_Generic::init_source (j_decompress_ptr cinfo)
00190 {
00191 InputSource_src_ptr src = (InputSource_src_ptr) cinfo->src;
00192 src->start_of_file = TRUE;
00193 }
00194
00195 boolean CL_JPEGProvider_Generic::fill_input_buffer (j_decompress_ptr cinfo)
00196 {
00197 InputSource_src_ptr src = (InputSource_src_ptr) cinfo->src;
00198 size_t nbytes;
00199
00200 nbytes = src->jpeg_provider->input_source->read (src->buffer, INPUT_BUF_SIZE);
00201
00202 if (nbytes <= 0)
00203 {
00204 if (src->start_of_file)
00205 ERREXIT(cinfo, JERR_INPUT_EMPTY);
00206 WARNMS(cinfo, JWRN_JPEG_EOF);
00207
00208 src->buffer[0] = (JOCTET) 0xFF;
00209 src->buffer[1] = (JOCTET) JPEG_EOI;
00210 nbytes = 2;
00211 }
00212 src->pub.next_input_byte = src->buffer;
00213 src->pub.bytes_in_buffer = nbytes;
00214 src->start_of_file = FALSE;
00215
00216 return TRUE;
00217 }
00218
00219 void CL_JPEGProvider_Generic::skip_input_data (j_decompress_ptr cinfo, long num_bytes)
00220 {
00221 InputSource_src_ptr src = (InputSource_src_ptr) cinfo->src;
00222
00223
00224
00225
00226
00227 if (num_bytes > 0)
00228 {
00229 while (num_bytes > (long) src->pub.bytes_in_buffer)
00230 {
00231 num_bytes -= (long) src->pub.bytes_in_buffer;
00232 (void) fill_input_buffer(cinfo);
00233
00234
00235
00236 }
00237 src->pub.next_input_byte += (size_t) num_bytes;
00238 src->pub.bytes_in_buffer -= (size_t) num_bytes;
00239 }
00240 }
00241
00242 void CL_JPEGProvider_Generic::term_source (j_decompress_ptr cinfo)
00243 {
00244
00245 }