1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
43 #include "grfmt_jpeg.h"
52 #define XMD_H // prevent redefinition of INT32
53 #undef FAR // prevent FAR redefinition
57 #if defined WIN32 && defined __GNUC__
58 typedef unsigned char boolean;
70 struct jpeg_error_mgr pub;
71 jmp_buf setjmp_buffer;
76 struct jpeg_source_mgr pub;
82 jpeg_decompress_struct cinfo; // IJG JPEG codec structure
83 JpegErrorMgr jerr; // error processing manager state
84 JpegSource source; // memory buffer source
87 /////////////////////// Error processing /////////////////////
90 stub(j_decompress_ptr)
95 fill_input_buffer(j_decompress_ptr)
100 // emulating memory input stream
103 skip_input_data(j_decompress_ptr cinfo, long num_bytes)
105 JpegSource* source = (JpegSource*) cinfo->src;
107 if( num_bytes > (long)source->pub.bytes_in_buffer )
109 // We need to skip more data than we have in the buffer.
110 // This will force the JPEG library to suspend decoding.
111 source->skip = num_bytes - source->pub.bytes_in_buffer;
112 source->pub.next_input_byte += source->pub.bytes_in_buffer;
113 source->pub.bytes_in_buffer = 0;
117 // Skip portion of the buffer
118 source->pub.bytes_in_buffer -= num_bytes;
119 source->pub.next_input_byte += num_bytes;
126 jpeg_buffer_src(j_decompress_ptr cinfo, JpegSource* source)
128 cinfo->src = &source->pub;
130 // Prepare for suspending reader
131 source->pub.init_source = stub;
132 source->pub.fill_input_buffer = fill_input_buffer;
133 source->pub.skip_input_data = skip_input_data;
134 source->pub.resync_to_restart = jpeg_resync_to_restart;
135 source->pub.term_source = stub;
136 source->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read
143 error_exit( j_common_ptr cinfo )
145 JpegErrorMgr* err_mgr = (JpegErrorMgr*)(cinfo->err);
147 /* Return control to the setjmp point */
148 longjmp( err_mgr->setjmp_buffer, 1 );
152 /////////////////////// JpegDecoder ///////////////////
155 JpegDecoder::JpegDecoder()
157 m_signature = "\xFF\xD8\xFF";
160 m_buf_supported = true;
164 JpegDecoder::~JpegDecoder()
170 void JpegDecoder::close()
174 JpegState* state = (JpegState*)m_state;
175 jpeg_destroy_decompress( &state->cinfo );
186 m_width = m_height = 0;
190 ImageDecoder JpegDecoder::newDecoder() const
192 return new JpegDecoder;
195 bool JpegDecoder::readHeader()
200 JpegState* state = new JpegState;
202 state->cinfo.err = jpeg_std_error(&state->jerr.pub);
203 state->jerr.pub.error_exit = error_exit;
205 if( setjmp( state->jerr.setjmp_buffer ) == 0 )
207 jpeg_create_decompress( &state->cinfo );
211 jpeg_buffer_src(&state->cinfo, &state->source);
212 state->source.pub.next_input_byte = m_buf.data;
213 state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*m_buf.elemSize();
217 m_f = fopen( m_filename.c_str(), "rb" );
219 jpeg_stdio_src( &state->cinfo, m_f );
221 jpeg_read_header( &state->cinfo, TRUE );
223 m_width = state->cinfo.image_width;
224 m_height = state->cinfo.image_height;
225 m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1;
235 /***************************************************************************
236 * following code is for supporting MJPEG image files
237 * based on a message of Laurent Pinchart on the video4linux mailing list
238 ***************************************************************************/
240 /* JPEG DHT Segment for YCrCb omitted from MJPEG data */
242 unsigned char my_jpeg_odml_dht[0x1a4] = {
243 0xff, 0xc4, 0x01, 0xa2,
245 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
249 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
250 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
253 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
254 0x04, 0x00, 0x00, 0x01, 0x7d,
255 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
256 0x13, 0x51, 0x61, 0x07,
257 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1,
258 0x15, 0x52, 0xd1, 0xf0,
259 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a,
260 0x25, 0x26, 0x27, 0x28,
261 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
262 0x46, 0x47, 0x48, 0x49,
263 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
264 0x66, 0x67, 0x68, 0x69,
265 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
266 0x86, 0x87, 0x88, 0x89,
267 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
268 0xa4, 0xa5, 0xa6, 0xa7,
269 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
270 0xc2, 0xc3, 0xc4, 0xc5,
271 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
272 0xd9, 0xda, 0xe1, 0xe2,
273 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
274 0xf5, 0xf6, 0xf7, 0xf8,
277 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
278 0x04, 0x00, 0x01, 0x02, 0x77,
279 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
280 0x51, 0x07, 0x61, 0x71,
281 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09,
282 0x23, 0x33, 0x52, 0xf0,
283 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17,
284 0x18, 0x19, 0x1a, 0x26,
285 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
286 0x45, 0x46, 0x47, 0x48,
287 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
288 0x65, 0x66, 0x67, 0x68,
289 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83,
290 0x84, 0x85, 0x86, 0x87,
291 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
292 0xa2, 0xa3, 0xa4, 0xa5,
293 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
294 0xb9, 0xba, 0xc2, 0xc3,
295 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
296 0xd7, 0xd8, 0xd9, 0xda,
297 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
298 0xf5, 0xf6, 0xf7, 0xf8,
303 * Parse the DHT table.
304 * This code comes from jpeg6b (jdmarker.c).
307 int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
308 JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
310 unsigned int length = (dht[2] << 8) + dht[3] - 2;
311 unsigned int pos = 4;
312 unsigned int count, i;
316 unsigned char bits[17];
317 unsigned char huffval[256];
324 for (i = 1; i <= 16; ++i)
326 bits[i] = dht[pos++];
331 if (count > 256 || count > length)
334 for (i = 0; i < count; ++i)
335 huffval[i] = dht[pos++];
341 hufftbl = &ac_tables[index];
344 hufftbl = &dc_tables[index];
346 if (index < 0 || index >= NUM_HUFF_TBLS)
349 if (*hufftbl == NULL)
350 *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
351 if (*hufftbl == NULL)
354 memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
355 memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
364 /***************************************************************************
365 * end of code for supportting MJPEG image files
366 * based on a message of Laurent Pinchart on the video4linux mailing list
367 ***************************************************************************/
369 bool JpegDecoder::readData( Mat& img )
372 uchar* data = img.data;
374 bool color = img.channels() > 1;
375 JpegState* state = (JpegState*)m_state;
377 if( state && m_width && m_height )
379 jpeg_decompress_struct* cinfo = &state->cinfo;
380 JpegErrorMgr* jerr = &state->jerr;
381 JSAMPARRAY buffer = 0;
383 if( setjmp( jerr->setjmp_buffer ) == 0 )
385 /* check if this is a mjpeg image format */
386 if ( cinfo->ac_huff_tbl_ptrs[0] == NULL &&
387 cinfo->ac_huff_tbl_ptrs[1] == NULL &&
388 cinfo->dc_huff_tbl_ptrs[0] == NULL &&
389 cinfo->dc_huff_tbl_ptrs[1] == NULL )
391 /* yes, this is a mjpeg image format, so load the correct
393 my_jpeg_load_dht( cinfo,
395 cinfo->ac_huff_tbl_ptrs,
396 cinfo->dc_huff_tbl_ptrs );
401 if( cinfo->num_components != 4 )
403 cinfo->out_color_space = JCS_RGB;
404 cinfo->out_color_components = 3;
408 cinfo->out_color_space = JCS_CMYK;
409 cinfo->out_color_components = 4;
414 if( cinfo->num_components != 4 )
416 cinfo->out_color_space = JCS_GRAYSCALE;
417 cinfo->out_color_components = 1;
421 cinfo->out_color_space = JCS_CMYK;
422 cinfo->out_color_components = 4;
426 jpeg_start_decompress( cinfo );
428 buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
429 JPOOL_IMAGE, m_width*4, 1 );
431 for( ; m_height--; data += step )
433 jpeg_read_scanlines( cinfo, buffer, 1 );
436 if( cinfo->out_color_components == 3 )
437 icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, cvSize(m_width,1) );
439 icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, cvSize(m_width,1) );
443 if( cinfo->out_color_components == 1 )
444 memcpy( data, buffer[0], m_width );
446 icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, cvSize(m_width,1) );
450 jpeg_finish_decompress( cinfo );
459 /////////////////////// JpegEncoder ///////////////////
461 struct JpegDestination
463 struct jpeg_destination_mgr pub;
464 vector<uchar> *buf, *dst;
473 term_destination (j_compress_ptr cinfo)
475 JpegDestination* dest = (JpegDestination*)cinfo->dest;
476 size_t sz = dest->dst->size(), bufsz = dest->buf->size() - dest->pub.free_in_buffer;
479 dest->dst->resize(sz + bufsz);
480 memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
485 empty_output_buffer (j_compress_ptr cinfo)
487 JpegDestination* dest = (JpegDestination*)cinfo->dest;
488 size_t sz = dest->dst->size(), bufsz = dest->buf->size();
489 dest->dst->resize(sz + bufsz);
490 memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
492 dest->pub.next_output_byte = &(*dest->buf)[0];
493 dest->pub.free_in_buffer = bufsz;
498 jpeg_buffer_dest(j_compress_ptr cinfo, JpegDestination* destination)
500 cinfo->dest = &destination->pub;
502 destination->pub.init_destination = stub;
503 destination->pub.empty_output_buffer = empty_output_buffer;
504 destination->pub.term_destination = term_destination;
508 JpegEncoder::JpegEncoder()
510 m_description = "JPEG files (*.jpeg;*.jpg;*.jpe)";
511 m_buf_supported = true;
515 JpegEncoder::~JpegEncoder()
519 ImageEncoder JpegEncoder::newEncoder() const
521 return new JpegEncoder;
524 bool JpegEncoder::write( const Mat& img, const vector<int>& params )
528 for( size_t i = 0; i < params.size(); i += 2 )
530 if( params[i] == CV_IMWRITE_JPEG_QUALITY )
532 quality = params[i+1];
533 quality = MIN(MAX(quality, 0), 100);
539 int _channels = img.channels();
540 int channels = _channels > 1 ? 3 : 1;
541 int width = img.cols, height = img.rows;
543 vector<uchar> out_buf(1 << 12);
544 AutoBuffer<uchar> _buffer;
547 struct jpeg_compress_struct cinfo;
549 JpegDestination dest;
551 jpeg_create_compress(&cinfo);
552 cinfo.err = jpeg_std_error(&jerr.pub);
553 jerr.pub.error_exit = error_exit;
557 f = fopen( m_filename.c_str(), "wb" );
560 jpeg_stdio_dest( &cinfo, f );
567 jpeg_buffer_dest( &cinfo, &dest );
569 dest.pub.next_output_byte = &out_buf[0];
570 dest.pub.free_in_buffer = out_buf.size();
573 if( setjmp( jerr.setjmp_buffer ) == 0 )
575 cinfo.image_width = width;
576 cinfo.image_height = height;
577 cinfo.input_components = channels;
578 cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
580 jpeg_set_defaults( &cinfo );
581 jpeg_set_quality( &cinfo, quality,
582 TRUE /* limit to baseline-JPEG values */ );
583 jpeg_start_compress( &cinfo, TRUE );
586 _buffer.allocate(width*channels);
589 for( int y = 0; y < height; y++ )
591 uchar *data = img.data + img.step*y, *ptr = data;
595 icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, cvSize(width,1) );
598 else if( _channels == 4 )
600 icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, cvSize(width,1), 2 );
604 jpeg_write_scanlines( &cinfo, &ptr, 1 );
607 jpeg_finish_compress( &cinfo );
613 jpeg_destroy_compress( &cinfo );