50 struct jpeg_source_mgr pub;
52 std::istream * infile;
54 boolean start_of_file;
57 typedef my_source_mgr * my_src_ptr;
59 #define INPUT_BUF_SIZE 4096
68 init_source (j_decompress_ptr cinfo)
70 my_src_ptr src = (my_src_ptr) cinfo->src;
76 src->start_of_file = TRUE;
114 fill_input_buffer (j_decompress_ptr cinfo)
116 my_src_ptr src = (my_src_ptr) cinfo->src;
119 src->infile->read((
char *)src->buffer, INPUT_BUF_SIZE);
120 nbytes = src->infile->gcount();
124 if (src->start_of_file)
125 ERREXIT(cinfo, JERR_INPUT_EMPTY);
126 WARNMS(cinfo, JWRN_JPEG_EOF);
128 src->buffer[0] = (JOCTET) 0xFF;
129 src->buffer[1] = (JOCTET) JPEG_EOI;
133 src->pub.next_input_byte = src->buffer;
134 src->pub.bytes_in_buffer = nbytes;
135 src->start_of_file = FALSE;
154 skip_input_data (j_decompress_ptr cinfo,
long num_bytes)
156 my_src_ptr src = (my_src_ptr) cinfo->src;
163 while (num_bytes > (
long) src->pub.bytes_in_buffer) {
164 num_bytes -= (long) src->pub.bytes_in_buffer;
165 (
void) fill_input_buffer(cinfo);
170 src->pub.next_input_byte += (size_t) num_bytes;
171 src->pub.bytes_in_buffer -= (size_t) num_bytes;
195 term_source (j_decompress_ptr cinfo)
208 jpeg_istream_src (j_decompress_ptr cinfo, std::istream * infile)
219 if (cinfo->src ==
nullptr) {
220 cinfo->src = (
struct jpeg_source_mgr *)
221 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
222 sizeof(my_source_mgr));
223 src = (my_src_ptr) cinfo->src;
224 src->buffer = (JOCTET *)
225 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
226 INPUT_BUF_SIZE *
sizeof(JOCTET));
229 src = (my_src_ptr) cinfo->src;
230 src->pub.init_source = init_source;
231 src->pub.fill_input_buffer = fill_input_buffer;
232 src->pub.skip_input_data = skip_input_data;
233 src->pub.resync_to_restart = jpeg_resync_to_restart;
234 src->pub.term_source = term_source;
235 src->infile = infile;
236 src->pub.bytes_in_buffer = 0;
237 src->pub.next_input_byte =
nullptr;
247 PNMFileTypeJPG::Reader::
248 Reader(
PNMFileType *type, std::istream *file,
bool owns_file, std::string magic_number) :
252 for (std::string::reverse_iterator mi = magic_number.rbegin();
253 mi != magic_number.rend();
258 pnmimage_jpg_cat.error()
259 <<
"Unable to put back magic number.\n";
268 _cinfo.err = jpeg_std_error(&_jerr.pub);
271 jpeg_create_decompress(&_cinfo);
274 jpeg_istream_src(&_cinfo, file);
277 jpeg_save_markers(&_cinfo, JPEG_COM, 0xffff);
280 jpeg_read_header(&_cinfo, TRUE);
287 _num_channels = _cinfo.num_components;
288 _x_size = (int)_cinfo.image_width;
289 _y_size = (
int)_cinfo.image_height;
290 _maxval = MAXJSAMPLE;
293 _cinfo.scale_num = 1;
294 _cinfo.scale_denom = 1;
305 void PNMFileTypeJPG::Reader::
307 if (_has_read_size && _read_x_size != 0 && _read_y_size != 0) {
309 int x_reduction = _cinfo.image_width / _read_x_size;
310 int y_reduction = _cinfo.image_height / _read_y_size;
311 _cinfo.scale_denom = std::max(std::min(x_reduction, y_reduction), 1);
316 jpeg_start_decompress(&_cinfo);
321 _num_channels = _cinfo.output_components;
322 _x_size = (int)_cinfo.output_width;
323 _y_size = (
int)_cinfo.output_height;
329 PNMFileTypeJPG::Reader::
332 jpeg_destroy_decompress(&_cinfo);
346 int PNMFileTypeJPG::Reader::
347 read_data(
xel *array, xelval *) {
354 nassertr(_cinfo.output_components == 1 || _cinfo.output_components == 3, 0);
363 row_stride = _cinfo.output_width * _cinfo.output_components;
366 buffer = (*_cinfo.mem->alloc_sarray)
367 ((j_common_ptr) &_cinfo, JPOOL_IMAGE, row_stride, 1);
376 while (_cinfo.output_scanline < _cinfo.output_height) {
381 jpeg_read_scanlines(&_cinfo, buffer, 1);
384 JSAMPROW bufptr = buffer[0];
385 for (
int i = 0; i < row_stride; i += _cinfo.output_components) {
386 if (_cinfo.output_components == 1) {
387 xelval val = (xelval)bufptr[i];
388 nassertr(x < _x_size * _y_size, 0);
389 PNM_ASSIGN1(array[x], val);
391 xelval red, grn, blu;
392 red = (xelval)bufptr[i];
393 grn = (xelval)bufptr[i+1];
394 blu = (xelval)bufptr[i+2];
395 nassertr(x < _x_size * _y_size, 0);
396 PPM_ASSIGN(array[x], red, grn, blu);
405 jpeg_finish_decompress(&_cinfo);
414 if (_jerr.pub.num_warnings) {
415 pnmimage_jpg_cat.warning()
416 <<
"Jpeg data may be corrupt" << std::endl;