1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*M///////////////////////////////////////////////////////////////////////////////////////
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  By downloading, copying, installing or using the software you agree to this license.
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  If you do not agree to this license, do not download, install,
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  copy or use the software.
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                        Intel License Agreement
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                For Open Source Computer Vision Library
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2000, Intel Corporation, all rights reserved.
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Third party copyrights are property of their respective owners.
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Redistribution and use in source and binary forms, with or without modification,
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// are permitted provided that the following conditions are met:
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's of source code must retain the above copyright notice,
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer.
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's in binary form must reproduce the above copyright notice,
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer in the documentation
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     and/or other materials provided with the distribution.
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * The name of Intel Corporation may not be used to endorse or promote products
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     derived from this software without specific prior written permission.
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// This software is provided by the copyright holders and contributors "as is" and
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// any express or implied warranties, including, but not limited to, the implied
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// warranties of merchantability and fitness for a particular purpose are disclaimed.
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// In no event shall the Intel Corporation or contributors be liable for any direct,
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// indirect, incidental, special, exemplary, or consequential damages
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// (including, but not limited to, procurement of substitute goods or services;
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// loss of use, data, or profits; or business interruption) however caused
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and on any theory of liability, whether in contract, strict liability,
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// or tort (including negligence or otherwise) arising in any way out of
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the use of this software, even if advised of the possibility of such damage.
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//M*/
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "precomp.hpp"
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "grfmt_jpeg.hpp"
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_JPEG
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef _MSC_VER
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//interaction between '_setjmp' and C++ object destruction is non-portable
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#pragma warning(disable: 4611)
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <stdio.h>
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <setjmp.h>
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the following defines are a hack to avoid multiple problems with frame ponter handling and setjmp
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// see http://gcc.gnu.org/ml/gcc/2011-10/msg00324.html for some details
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define mingw_getsp(...) 0
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define __builtin_frame_address(...) 0
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef WIN32
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define XMD_H // prevent redefinition of INT32
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef FAR  // prevent FAR redefinition
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#if defined WIN32 && defined __GNUC__
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef unsigned char boolean;
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef FALSE
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef TRUE
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerextern "C" {
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "jpeglib.h"
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslernamespace cv
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef _MSC_VER
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# pragma warning(push)
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# pragma warning(disable:4324) //structure was padded due to __declspec(align())
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct JpegErrorMgr
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct jpeg_error_mgr pub;
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    jmp_buf setjmp_buffer;
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef _MSC_VER
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# pragma warning(pop)
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct JpegSource
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct jpeg_source_mgr pub;
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int skip;
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct JpegState
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    jpeg_decompress_struct cinfo; // IJG JPEG codec structure
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegErrorMgr jerr; // error processing manager state
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegSource source; // memory buffer source
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////// Error processing /////////////////////
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(void)
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstub(j_decompress_ptr)
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(boolean)
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfill_input_buffer(j_decompress_ptr)
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return FALSE;
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// emulating memory input stream
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(void)
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerskip_input_data(j_decompress_ptr cinfo, long num_bytes)
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegSource* source = (JpegSource*) cinfo->src;
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( num_bytes > (long)source->pub.bytes_in_buffer )
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // We need to skip more data than we have in the buffer.
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // This will force the JPEG library to suspend decoding.
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        source->skip = (int)(num_bytes - source->pub.bytes_in_buffer);
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        source->pub.next_input_byte += source->pub.bytes_in_buffer;
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        source->pub.bytes_in_buffer = 0;
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // Skip portion of the buffer
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        source->pub.bytes_in_buffer -= num_bytes;
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        source->pub.next_input_byte += num_bytes;
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        source->skip = 0;
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void jpeg_buffer_src(j_decompress_ptr cinfo, JpegSource* source)
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cinfo->src = &source->pub;
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // Prepare for suspending reader
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->pub.init_source = stub;
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->pub.fill_input_buffer = fill_input_buffer;
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->pub.skip_input_data = skip_input_data;
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->pub.resync_to_restart = jpeg_resync_to_restart;
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->pub.term_source = stub;
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    source->skip = 0;
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(void)
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslererror_exit( j_common_ptr cinfo )
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegErrorMgr* err_mgr = (JpegErrorMgr*)(cinfo->err);
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* Return control to the setjmp point */
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    longjmp( err_mgr->setjmp_buffer, 1 );
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////// JpegDecoder ///////////////////
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerJpegDecoder::JpegDecoder()
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_signature = "\xFF\xD8\xFF";
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_state = 0;
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_f = 0;
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_buf_supported = true;
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerJpegDecoder::~JpegDecoder()
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    close();
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid  JpegDecoder::close()
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( m_state )
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        JpegState* state = (JpegState*)m_state;
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_destroy_decompress( &state->cinfo );
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        delete state;
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_state = 0;
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( m_f )
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        fclose( m_f );
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_f = 0;
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_width = m_height = 0;
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_type = -1;
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerImageDecoder JpegDecoder::newDecoder() const
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return makePtr<JpegDecoder>();
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool  JpegDecoder::readHeader()
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool result = false;
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    close();
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegState* state = new JpegState;
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_state = state;
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    state->cinfo.err = jpeg_std_error(&state->jerr.pub);
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    state->jerr.pub.error_exit = error_exit;
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( setjmp( state->jerr.setjmp_buffer ) == 0 )
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_create_decompress( &state->cinfo );
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( !m_buf.empty() )
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_buffer_src(&state->cinfo, &state->source);
231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            state->source.pub.next_input_byte = m_buf.ptr();
232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*m_buf.elemSize();
233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m_f = fopen( m_filename.c_str(), "rb" );
237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( m_f )
238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                jpeg_stdio_src( &state->cinfo, m_f );
239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (state->cinfo.src != 0)
242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_read_header( &state->cinfo, TRUE );
244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m_width = state->cinfo.image_width;
246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m_height = state->cinfo.image_height;
247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1;
248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            result = true;
249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !result )
253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        close();
254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return result;
256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/***************************************************************************
259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * following code is for supporting MJPEG image files
260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * based on a message of Laurent Pinchart on the video4linux mailing list
261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ***************************************************************************/
262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* JPEG DHT Segment for YCrCb omitted from MJPEG data */
264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic
265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerunsigned char my_jpeg_odml_dht[0x1a4] = {
266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xff, 0xc4, 0x01, 0xa2,
267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x00, 0x00, 0x00, 0x00, 0x00,
270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x00, 0x00, 0x00, 0x00, 0x00,
274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x04, 0x00, 0x00, 0x01, 0x7d,
278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x13, 0x51, 0x61, 0x07,
280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1,
281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x15, 0x52, 0xd1, 0xf0,
282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a,
283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x25, 0x26, 0x27, 0x28,
284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x46, 0x47, 0x48, 0x49,
286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x66, 0x67, 0x68, 0x69,
288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x86, 0x87, 0x88, 0x89,
290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xa4, 0xa5, 0xa6, 0xa7,
292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xc2, 0xc3, 0xc4, 0xc5,
294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xd9, 0xda, 0xe1, 0xe2,
296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xf5, 0xf6, 0xf7, 0xf8,
298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xf9, 0xfa,
299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x04, 0x00, 0x01, 0x02, 0x77,
302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x51, 0x07, 0x61, 0x71,
304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09,
305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x23, 0x33, 0x52, 0xf0,
306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17,
307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x18, 0x19, 0x1a, 0x26,
308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x45, 0x46, 0x47, 0x48,
310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x65, 0x66, 0x67, 0x68,
312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83,
313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x84, 0x85, 0x86, 0x87,
314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xa2, 0xa3, 0xa4, 0xa5,
316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xb9, 0xba, 0xc2, 0xc3,
318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xd7, 0xd8, 0xd9, 0xda,
320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xf5, 0xf6, 0xf7, 0xf8,
322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    0xf9, 0xfa
323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Parse the DHT table.
327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * This code comes from jpeg6b (jdmarker.c).
328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic
330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned int length = (dht[2] << 8) + dht[3] - 2;
334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned int pos = 4;
335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned int count, i;
336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int index;
337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JHUFF_TBL **hufftbl;
339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char bits[17];
340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char huffval[256];
341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (length > 16)
343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       bits[0] = 0;
345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       index = dht[pos++];
346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       count = 0;
347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       for (i = 1; i <= 16; ++i)
348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       {
349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           bits[i] = dht[pos++];
350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           count += bits[i];
351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       }
352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       length -= 17;
353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       if (count > 256 || count > length)
355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           return -1;
356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       for (i = 0; i < count; ++i)
358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           huffval[i] = dht[pos++];
359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       length -= count;
360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       if (index & 0x10)
362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       {
363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           index -= 0x10;
364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           hufftbl = &ac_tables[index];
365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       }
366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       else
367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           hufftbl = &dc_tables[index];
368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       if (index < 0 || index >= NUM_HUFF_TBLS)
370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           return -1;
371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       if (*hufftbl == NULL)
373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       if (*hufftbl == NULL)
375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           return -1;
376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (length != 0)
382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       return -1;
383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/***************************************************************************
388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * end of code for supportting MJPEG image files
389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * based on a message of Laurent Pinchart on the video4linux mailing list
390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ***************************************************************************/
391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool  JpegDecoder::readData( Mat& img )
393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool result = false;
395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int step = (int)img.step;
396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool color = img.channels() > 1;
397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( m_state && m_width && m_height )
399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_decompress_struct* cinfo = &((JpegState*)m_state)->cinfo;
401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        JpegErrorMgr* jerr = &((JpegState*)m_state)->jerr;
402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        JSAMPARRAY buffer = 0;
403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( setjmp( jerr->setjmp_buffer ) == 0 )
405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* check if this is a mjpeg image format */
407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if ( cinfo->ac_huff_tbl_ptrs[0] == NULL &&
408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo->ac_huff_tbl_ptrs[1] == NULL &&
409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo->dc_huff_tbl_ptrs[0] == NULL &&
410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo->dc_huff_tbl_ptrs[1] == NULL )
411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /* yes, this is a mjpeg image format, so load the correct
413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                huffman table */
414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                my_jpeg_load_dht( cinfo,
415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    my_jpeg_odml_dht,
416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->ac_huff_tbl_ptrs,
417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->dc_huff_tbl_ptrs );
418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( color )
421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( cinfo->num_components != 4 )
423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_space = JCS_RGB;
425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_components = 3;
426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_space = JCS_CMYK;
430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_components = 4;
431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( cinfo->num_components != 4 )
436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_space = JCS_GRAYSCALE;
438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_components = 1;
439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_space = JCS_CMYK;
443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cinfo->out_color_components = 4;
444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_start_decompress( cinfo );
448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              JPOOL_IMAGE, m_width*4, 1 );
451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uchar* data = img.ptr();
453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( ; m_height--; data += step )
454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                jpeg_read_scanlines( cinfo, buffer, 1 );
456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( color )
457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( cinfo->out_color_components == 3 )
459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, cvSize(m_width,1) );
460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else
461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, cvSize(m_width,1) );
462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( cinfo->out_color_components == 1 )
466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        memcpy( data, buffer[0], m_width );
467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else
468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, cvSize(m_width,1) );
469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            result = true;
472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_finish_decompress( cinfo );
473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    close();
477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return result;
478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////// JpegEncoder ///////////////////
482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct JpegDestination
484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct jpeg_destination_mgr pub;
486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::vector<uchar> *buf, *dst;
487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
489793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(void)
490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstub(j_compress_ptr)
491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
494793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(void)
495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerterm_destination (j_compress_ptr cinfo)
496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegDestination* dest = (JpegDestination*)cinfo->dest;
498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t sz = dest->dst->size(), bufsz = dest->buf->size() - dest->pub.free_in_buffer;
499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( bufsz > 0 )
500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        dest->dst->resize(sz + bufsz);
502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
506793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMETHODDEF(boolean)
507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerempty_output_buffer (j_compress_ptr cinfo)
508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegDestination* dest = (JpegDestination*)cinfo->dest;
510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t sz = dest->dst->size(), bufsz = dest->buf->size();
511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dest->dst->resize(sz + bufsz);
512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dest->pub.next_output_byte = &(*dest->buf)[0];
515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dest->pub.free_in_buffer = bufsz;
516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return TRUE;
517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void jpeg_buffer_dest(j_compress_ptr cinfo, JpegDestination* destination)
520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cinfo->dest = &destination->pub;
522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    destination->pub.init_destination = stub;
524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    destination->pub.empty_output_buffer = empty_output_buffer;
525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    destination->pub.term_destination = term_destination;
526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
529793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerJpegEncoder::JpegEncoder()
530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_description = "JPEG files (*.jpeg;*.jpg;*.jpe)";
532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_buf_supported = true;
533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
536793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerJpegEncoder::~JpegEncoder()
537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
540793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerImageEncoder JpegEncoder::newEncoder() const
541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return makePtr<JpegEncoder>();
543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m_last_error.clear();
548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct fileWrapper
550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        FILE* f;
552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        fileWrapper() : f(0) {}
554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ~fileWrapper() { if(f) fclose(f); }
555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    };
556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool result = false;
557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fileWrapper fw;
558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int width = img.cols, height = img.rows;
559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::vector<uchar> out_buf(1 << 12);
561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    AutoBuffer<uchar> _buffer;
562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uchar* buffer;
563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct jpeg_compress_struct cinfo;
565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegErrorMgr jerr;
566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    JpegDestination dest;
567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    jpeg_create_compress(&cinfo);
569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cinfo.err = jpeg_std_error(&jerr.pub);
570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    jerr.pub.error_exit = error_exit;
571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !m_buf )
573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        fw.f = fopen( m_filename.c_str(), "wb" );
575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( !fw.f )
576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            goto _exit_;
577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_stdio_dest( &cinfo, fw.f );
578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        dest.dst = m_buf;
582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        dest.buf = &out_buf;
583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_buffer_dest( &cinfo, &dest );
585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        dest.pub.next_output_byte = &out_buf[0];
587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        dest.pub.free_in_buffer = out_buf.size();
588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( setjmp( jerr.setjmp_buffer ) == 0 )
591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cinfo.image_width = width;
593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cinfo.image_height = height;
594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int _channels = img.channels();
596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int channels = _channels > 1 ? 3 : 1;
597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cinfo.input_components = channels;
598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int quality = 95;
601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int progressive = 0;
602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int optimize = 0;
603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int rst_interval = 0;
604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int luma_quality = -1;
605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int chroma_quality = -1;
606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( size_t i = 0; i < params.size(); i += 2 )
608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( params[i] == CV_IMWRITE_JPEG_QUALITY )
610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                quality = params[i+1];
612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                quality = MIN(MAX(quality, 0), 100);
613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( params[i] == CV_IMWRITE_JPEG_PROGRESSIVE )
616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                progressive = params[i+1];
618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( params[i] == CV_IMWRITE_JPEG_OPTIMIZE )
621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                optimize = params[i+1];
623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( params[i] == CV_IMWRITE_JPEG_LUMA_QUALITY )
626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (params[i+1] >= 0)
628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    luma_quality = MIN(MAX(params[i+1], 0), 100);
630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    quality = luma_quality;
632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if (chroma_quality < 0)
634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        chroma_quality = luma_quality;
636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( params[i] == CV_IMWRITE_JPEG_CHROMA_QUALITY )
641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (params[i+1] >= 0)
643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    chroma_quality = MIN(MAX(params[i+1], 0), 100);
645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( params[i] == CV_IMWRITE_JPEG_RST_INTERVAL )
649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                rst_interval = params[i+1];
651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                rst_interval = MIN(MAX(rst_interval, 0), 65535L);
652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_set_defaults( &cinfo );
656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cinfo.restart_interval = rst_interval;
657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_set_quality( &cinfo, quality,
659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                          TRUE /* limit to baseline-JPEG values */ );
660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( progressive )
661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_simple_progression( &cinfo );
662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( optimize )
663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cinfo.optimize_coding = TRUE;
664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#if JPEG_LIB_VERSION >= 70
666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (luma_quality >= 0 && chroma_quality >= 0)
667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cinfo.q_scale_factor[0] = jpeg_quality_scaling(luma_quality);
669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cinfo.q_scale_factor[1] = jpeg_quality_scaling(chroma_quality);
670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if ( luma_quality != chroma_quality )
671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /* disable subsampling - ref. Libjpeg.txt */
673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo.comp_info[0].v_samp_factor = 1;
674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo.comp_info[0].h_samp_factor = 1;
675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo.comp_info[1].v_samp_factor = 1;
676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cinfo.comp_info[1].h_samp_factor = 1;
677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_default_qtables( &cinfo, TRUE );
679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif // #if JPEG_LIB_VERSION >= 70
681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_start_compress( &cinfo, TRUE );
683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( channels > 1 )
685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            _buffer.allocate(width*channels);
686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        buffer = _buffer;
687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( int y = 0; y < height; y++ )
689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uchar *data = img.data + img.step*y, *ptr = data;
691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( _channels == 3 )
693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, cvSize(width,1) );
695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ptr = buffer;
696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if( _channels == 4 )
698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, cvSize(width,1), 2 );
700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ptr = buffer;
701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            jpeg_write_scanlines( &cinfo, &ptr, 1 );
704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jpeg_finish_compress( &cinfo );
707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        result = true;
708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler_exit_:
711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if(!result)
713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        char jmsg_buf[JMSG_LENGTH_MAX];
715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        jerr.pub.format_message((j_common_ptr)&cinfo, jmsg_buf);
716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m_last_error = jmsg_buf;
717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    jpeg_destroy_compress( &cinfo );
720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return result;
722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* End of file. */
729