microsoft/onnxruntime-extensions

Public

mirrored fromhttps://github.com/microsoft/onnxruntime-extensionsAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
skottmckay/BuildInfra_AndTestImageLibs

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

operators/vision/impl/jpeg_encoder_decoder.cc

765lines · modecode

1///*M///////////////////////////////////////////////////////////////////////////////////////
2////
3//// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4////
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.
8////
9////
10//// Intel License Agreement
11//// For Open Source Computer Vision Library
12////
13//// Copyright (C) 2000, Intel Corporation, all rights reserved.
14//// Third party copyrights are property of their respective owners.
15////
16//// Redistribution and use in source and binary forms, with or without modification,
17//// are permitted provided that the following conditions are met:
18////
19//// * Redistribution's of source code must retain the above copyright notice,
20//// this list of conditions and the following disclaimer.
21////
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.
25////
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.
28////
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.
39////
40////M*/
41//
42// #include "precomp.hpp"
43// #include "grfmt_jpeg.hpp"
44//
45// #ifdef HAVE_JPEG
46//
47// #ifdef _MSC_VER
48////interaction between '_setjmp' and C++ object destruction is non-portable
49// #pragma warning(disable: 4611)
50// #endif
51//
52// #include <stdio.h>
53// #include <setjmp.h>
54//
55//// the following defines are a hack to avoid multiple problems with frame pointer handling and setjmp
56//// see http://gcc.gnu.org/ml/gcc/2011-10/msg00324.html for some details
57// #define mingw_getsp(...) 0
58// #define __builtin_frame_address(...) 0
59//
60// #ifdef _WIN32
61//
62// #define XMD_H // prevent redefinition of INT32
63// #undef FAR // prevent FAR redefinition
64//
65// #endif
66//
67// #if defined _WIN32 && defined __GNUC__
68// typedef unsigned char boolean;
69// #endif
70//
71// #undef FALSE
72// #undef TRUE
73//
74// extern "C" {
75// #include "jpeglib.h"
76// }
77//
78// #ifndef CV_MANUAL_JPEG_STD_HUFF_TABLES
79// #if defined(LIBJPEG_TURBO_VERSION_NUMBER) && LIBJPEG_TURBO_VERSION_NUMBER >= 1003090
80// #define CV_MANUAL_JPEG_STD_HUFF_TABLES 0 // libjpeg-turbo handles standard huffman tables itself (jstdhuff.c)
81// #else
82// #define CV_MANUAL_JPEG_STD_HUFF_TABLES 1
83// #endif
84// #endif
85// #if CV_MANUAL_JPEG_STD_HUFF_TABLES == 0
86// #undef CV_MANUAL_JPEG_STD_HUFF_TABLES
87// #endif
88//
89// namespace cv
90//{
91//
92// struct JpegErrorMgr
93//{
94// struct jpeg_error_mgr pub;
95// jmp_buf setjmp_buffer;
96// };
97//
98// struct JpegSource
99//{
100// struct jpeg_source_mgr pub;
101// int skip;
102// };
103//
104// struct JpegState
105//{
106// jpeg_decompress_struct cinfo; // IJG JPEG codec structure
107// JpegErrorMgr jerr; // error processing manager state
108// JpegSource source; // memory buffer source
109// };
110//
111///////////////////////// Error processing /////////////////////
112//
113// METHODDEF(void)
114// stub(j_decompress_ptr)
115//{
116//}
117//
118// METHODDEF(boolean)
119// fill_input_buffer(j_decompress_ptr)
120//{
121// return FALSE;
122//}
123//
124//// emulating memory input stream
125//
126// METHODDEF(void)
127// skip_input_data(j_decompress_ptr cinfo, long num_bytes)
128//{
129// JpegSource* source = (JpegSource*) cinfo->src;
130//
131// if( num_bytes > (long)source->pub.bytes_in_buffer )
132// {
133// // We need to skip more data than we have in the buffer.
134// // This will force the JPEG library to suspend decoding.
135// source->skip = (int)(num_bytes - source->pub.bytes_in_buffer);
136// source->pub.next_input_byte += source->pub.bytes_in_buffer;
137// source->pub.bytes_in_buffer = 0;
138// }
139// else
140// {
141// // Skip portion of the buffer
142// source->pub.bytes_in_buffer -= num_bytes;
143// source->pub.next_input_byte += num_bytes;
144// source->skip = 0;
145// }
146//}
147//
148//
149// static void jpeg_buffer_src(j_decompress_ptr cinfo, JpegSource* source)
150//{
151// cinfo->src = &source->pub;
152//
153// // Prepare for suspending reader
154// source->pub.init_source = stub;
155// source->pub.fill_input_buffer = fill_input_buffer;
156// source->pub.skip_input_data = skip_input_data;
157// source->pub.resync_to_restart = jpeg_resync_to_restart;
158// source->pub.term_source = stub;
159// source->pub.bytes_in_buffer = 0; // forces fill_input_buffer on first read
160//
161// source->skip = 0;
162//}
163//
164//
165// METHODDEF(void)
166// error_exit( j_common_ptr cinfo )
167//{
168// JpegErrorMgr* err_mgr = (JpegErrorMgr*)(cinfo->err);
169//
170// /* Return control to the setjmp point */
171// longjmp( err_mgr->setjmp_buffer, 1 );
172//}
173//
174//
175///////////////////////// JpegDecoder ///////////////////
176//
177//
178// JpegDecoder::JpegDecoder()
179//{
180// m_signature = "\xFF\xD8\xFF";
181// m_state = 0;
182// m_f = 0;
183// m_buf_supported = true;
184//}
185//
186//
187// JpegDecoder::~JpegDecoder()
188//{
189// close();
190//}
191//
192//
193// void JpegDecoder::close()
194//{
195// if( m_state )
196// {
197// JpegState* state = (JpegState*)m_state;
198// jpeg_destroy_decompress( &state->cinfo );
199// delete state;
200// m_state = 0;
201// }
202//
203// if( m_f )
204// {
205// fclose( m_f );
206// m_f = 0;
207// }
208//
209// m_width = m_height = 0;
210// m_type = -1;
211//}
212//
213// ImageDecoder JpegDecoder::newDecoder() const
214//{
215// return makePtr<JpegDecoder>();
216//}
217//
218// bool JpegDecoder::readHeader()
219//{
220// volatile bool result = false;
221// close();
222//
223// JpegState* state = new JpegState;
224// m_state = state;
225// state->cinfo.err = jpeg_std_error(&state->jerr.pub);
226// state->jerr.pub.error_exit = error_exit;
227//
228// if( setjmp( state->jerr.setjmp_buffer ) == 0 )
229// {
230// jpeg_create_decompress( &state->cinfo );
231//
232// if( !m_buf.empty() )
233// {
234// jpeg_buffer_src(&state->cinfo, &state->source);
235// state->source.pub.next_input_byte = m_buf.ptr();
236// state->source.pub.bytes_in_buffer = m_buf.cols*m_buf.rows*m_buf.elemSize();
237// }
238// else
239// {
240// m_f = fopen( m_filename.c_str(), "rb" );
241// if( m_f )
242// jpeg_stdio_src( &state->cinfo, m_f );
243// }
244//
245// if (state->cinfo.src != 0)
246// {
247// jpeg_save_markers(&state->cinfo, APP1, 0xffff);
248// jpeg_read_header( &state->cinfo, TRUE );
249//
250// state->cinfo.scale_num=1;
251// state->cinfo.scale_denom = m_scale_denom;
252// m_scale_denom=1; // trick! to know which decoder used scale_denom see imread_
253// jpeg_calc_output_dimensions(&state->cinfo);
254// m_width = state->cinfo.output_width;
255// m_height = state->cinfo.output_height;
256// m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1;
257// result = true;
258// }
259// }
260//
261// if( !result )
262// close();
263//
264// return result;
265//}
266//
267// #ifdef CV_MANUAL_JPEG_STD_HUFF_TABLES
268///***************************************************************************
269// * following code is for supporting MJPEG image files
270// * based on a message of Laurent Pinchart on the video4linux mailing list
271// ***************************************************************************/
272//
273///* JPEG DHT Segment for YCrCb omitted from MJPEG data */
274// static
275// unsigned char my_jpeg_odml_dht[0x1a4] = {
276// 0xff, 0xc4, 0x01, 0xa2,
277//
278// 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
279// 0x00, 0x00, 0x00, 0x00, 0x00,
280// 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
281//
282// 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
283// 0x00, 0x00, 0x00, 0x00, 0x00,
284// 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
285//
286// 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
287// 0x04, 0x00, 0x00, 0x01, 0x7d,
288// 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
289// 0x13, 0x51, 0x61, 0x07,
290// 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1,
291// 0x15, 0x52, 0xd1, 0xf0,
292// 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a,
293// 0x25, 0x26, 0x27, 0x28,
294// 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
295// 0x46, 0x47, 0x48, 0x49,
296// 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
297// 0x66, 0x67, 0x68, 0x69,
298// 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85,
299// 0x86, 0x87, 0x88, 0x89,
300// 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
301// 0xa4, 0xa5, 0xa6, 0xa7,
302// 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
303// 0xc2, 0xc3, 0xc4, 0xc5,
304// 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
305// 0xd9, 0xda, 0xe1, 0xe2,
306// 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
307// 0xf5, 0xf6, 0xf7, 0xf8,
308// 0xf9, 0xfa,
309//
310// 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
311// 0x04, 0x00, 0x01, 0x02, 0x77,
312// 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
313// 0x51, 0x07, 0x61, 0x71,
314// 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09,
315// 0x23, 0x33, 0x52, 0xf0,
316// 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17,
317// 0x18, 0x19, 0x1a, 0x26,
318// 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
319// 0x45, 0x46, 0x47, 0x48,
320// 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
321// 0x65, 0x66, 0x67, 0x68,
322// 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83,
323// 0x84, 0x85, 0x86, 0x87,
324// 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
325// 0xa2, 0xa3, 0xa4, 0xa5,
326// 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
327// 0xb9, 0xba, 0xc2, 0xc3,
328// 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
329// 0xd7, 0xd8, 0xd9, 0xda,
330// 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
331// 0xf5, 0xf6, 0xf7, 0xf8,
332// 0xf9, 0xfa
333// };
334//
335///*
336// * Parse the DHT table.
337// * This code comes from jpeg6b (jdmarker.c).
338// */
339// static
340// int my_jpeg_load_dht (struct jpeg_decompress_struct *info, unsigned char *dht,
341// JHUFF_TBL *ac_tables[], JHUFF_TBL *dc_tables[])
342//{
343// unsigned int length = (dht[2] << 8) + dht[3] - 2;
344// unsigned int pos = 4;
345// unsigned int count, i;
346// int index;
347//
348// JHUFF_TBL **hufftbl;
349// unsigned char bits[17];
350// unsigned char huffval[256] = {0};
351//
352// while (length > 16)
353// {
354// bits[0] = 0;
355// index = dht[pos++];
356// count = 0;
357// for (i = 1; i <= 16; ++i)
358// {
359// bits[i] = dht[pos++];
360// count += bits[i];
361// }
362// length -= 17;
363//
364// if (count > 256 || count > length)
365// return -1;
366//
367// for (i = 0; i < count; ++i)
368// huffval[i] = dht[pos++];
369// length -= count;
370//
371// if (index & 0x10)
372// {
373// index &= ~0x10;
374// hufftbl = &ac_tables[index];
375// }
376// else
377// hufftbl = &dc_tables[index];
378//
379// if (index < 0 || index >= NUM_HUFF_TBLS)
380// return -1;
381//
382// if (*hufftbl == NULL)
383// *hufftbl = jpeg_alloc_huff_table ((j_common_ptr)info);
384// if (*hufftbl == NULL)
385// return -1;
386//
387// memcpy ((*hufftbl)->bits, bits, sizeof (*hufftbl)->bits);
388// memcpy ((*hufftbl)->huffval, huffval, sizeof (*hufftbl)->huffval);
389// }
390//
391// if (length != 0)
392// return -1;
393//
394// return 0;
395//}
396//
397///***************************************************************************
398// * end of code for supportting MJPEG image files
399// * based on a message of Laurent Pinchart on the video4linux mailing list
400// ***************************************************************************/
401// #endif // CV_MANUAL_JPEG_STD_HUFF_TABLES
402//
403// bool JpegDecoder::readData( Mat& img )
404//{
405// volatile bool result = false;
406// size_t step = img.step;
407// bool color = img.channels() > 1;
408//
409// if( m_state && m_width && m_height )
410// {
411// jpeg_decompress_struct* cinfo = &((JpegState*)m_state)->cinfo;
412// JpegErrorMgr* jerr = &((JpegState*)m_state)->jerr;
413// JSAMPARRAY buffer = 0;
414//
415// if( setjmp( jerr->setjmp_buffer ) == 0 )
416// {
417// #ifdef CV_MANUAL_JPEG_STD_HUFF_TABLES
418// /* check if this is a mjpeg image format */
419// if ( cinfo->ac_huff_tbl_ptrs[0] == NULL &&
420// cinfo->ac_huff_tbl_ptrs[1] == NULL &&
421// cinfo->dc_huff_tbl_ptrs[0] == NULL &&
422// cinfo->dc_huff_tbl_ptrs[1] == NULL )
423// {
424// /* yes, this is a mjpeg image format, so load the correct
425// huffman table */
426// my_jpeg_load_dht( cinfo,
427// my_jpeg_odml_dht,
428// cinfo->ac_huff_tbl_ptrs,
429// cinfo->dc_huff_tbl_ptrs );
430// }
431// #endif
432//
433// if( color )
434// {
435// if( cinfo->num_components != 4 )
436// {
437// cinfo->out_color_space = JCS_RGB;
438// cinfo->out_color_components = 3;
439// }
440// else
441// {
442// cinfo->out_color_space = JCS_CMYK;
443// cinfo->out_color_components = 4;
444// }
445// }
446// else
447// {
448// if( cinfo->num_components != 4 )
449// {
450// cinfo->out_color_space = JCS_GRAYSCALE;
451// cinfo->out_color_components = 1;
452// }
453// else
454// {
455// cinfo->out_color_space = JCS_CMYK;
456// cinfo->out_color_components = 4;
457// }
458// }
459//
460// // Check for Exif marker APP1
461// jpeg_saved_marker_ptr exif_marker = NULL;
462// jpeg_saved_marker_ptr cmarker = cinfo->marker_list;
463// while( cmarker && exif_marker == NULL )
464// {
465// if (cmarker->marker == APP1)
466// exif_marker = cmarker;
467//
468// cmarker = cmarker->next;
469// }
470//
471// // Parse Exif data
472// if( exif_marker )
473// {
474// const std::streamsize offsetToTiffHeader = 6; //bytes from Exif size field to the first TIFF header
475//
476// if (exif_marker->data_length > offsetToTiffHeader)
477// {
478// m_exif.parseExif(exif_marker->data + offsetToTiffHeader, exif_marker->data_length - offsetToTiffHeader);
479// }
480// }
481//
482//
483// jpeg_start_decompress( cinfo );
484//
485// buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
486// JPOOL_IMAGE, m_width*4, 1 );
487//
488// uchar* data = img.ptr();
489// for( ; m_height--; data += step )
490// {
491// jpeg_read_scanlines( cinfo, buffer, 1 );
492// if( color )
493// {
494// if( cinfo->out_color_components == 3 )
495// icvCvt_RGB2BGR_8u_C3R( buffer[0], 0, data, 0, Size(m_width,1) );
496// else
497// icvCvt_CMYK2BGR_8u_C4C3R( buffer[0], 0, data, 0, Size(m_width,1) );
498// }
499// else
500// {
501// if( cinfo->out_color_components == 1 )
502// memcpy( data, buffer[0], m_width );
503// else
504// icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, Size(m_width,1) );
505// }
506// }
507//
508// result = true;
509// jpeg_finish_decompress( cinfo );
510// }
511// }
512//
513// close();
514// return result;
515//}
516//
517//
518///////////////////////// JpegEncoder ///////////////////
519//
520// struct JpegDestination
521//{
522// struct jpeg_destination_mgr pub;
523// std::vector<uchar> *buf, *dst;
524//};
525//
526// METHODDEF(void)
527// stub(j_compress_ptr)
528//{
529//}
530//
531// METHODDEF(void)
532// term_destination (j_compress_ptr cinfo)
533//{
534// JpegDestination* dest = (JpegDestination*)cinfo->dest;
535// size_t sz = dest->dst->size(), bufsz = dest->buf->size() - dest->pub.free_in_buffer;
536// if( bufsz > 0 )
537// {
538// dest->dst->resize(sz + bufsz);
539// memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
540// }
541//}
542//
543// METHODDEF(boolean)
544// empty_output_buffer (j_compress_ptr cinfo)
545//{
546// JpegDestination* dest = (JpegDestination*)cinfo->dest;
547// size_t sz = dest->dst->size(), bufsz = dest->buf->size();
548// dest->dst->resize(sz + bufsz);
549// memcpy( &(*dest->dst)[0] + sz, &(*dest->buf)[0], bufsz);
550//
551// dest->pub.next_output_byte = &(*dest->buf)[0];
552// dest->pub.free_in_buffer = bufsz;
553// return TRUE;
554//}
555//
556// static void jpeg_buffer_dest(j_compress_ptr cinfo, JpegDestination* destination)
557//{
558// cinfo->dest = &destination->pub;
559//
560// destination->pub.init_destination = stub;
561// destination->pub.empty_output_buffer = empty_output_buffer;
562// destination->pub.term_destination = term_destination;
563//}
564//
565//
566// JpegEncoder::JpegEncoder()
567//{
568// m_description = "JPEG files (*.jpeg;*.jpg;*.jpe)";
569// m_buf_supported = true;
570//}
571//
572//
573// JpegEncoder::~JpegEncoder()
574//{
575//}
576//
577// ImageEncoder JpegEncoder::newEncoder() const
578//{
579// return makePtr<JpegEncoder>();
580//}
581//
582// bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
583//{
584// m_last_error.clear();
585//
586// struct fileWrapper
587// {
588// FILE* f;
589//
590// fileWrapper() : f(0) {}
591// ~fileWrapper() { if(f) fclose(f); }
592// };
593// volatile bool result = false;
594// fileWrapper fw;
595// int width = img.cols, height = img.rows;
596//
597// std::vector<uchar> out_buf(1 << 12);
598// AutoBuffer<uchar> _buffer;
599// uchar* buffer;
600//
601// struct jpeg_compress_struct cinfo;
602// JpegErrorMgr jerr;
603// JpegDestination dest;
604//
605// jpeg_create_compress(&cinfo);
606// cinfo.err = jpeg_std_error(&jerr.pub);
607// jerr.pub.error_exit = error_exit;
608//
609// if( !m_buf )
610// {
611// fw.f = fopen( m_filename.c_str(), "wb" );
612// if( !fw.f )
613// goto _exit_;
614// jpeg_stdio_dest( &cinfo, fw.f );
615// }
616// else
617// {
618// dest.dst = m_buf;
619// dest.buf = &out_buf;
620//
621// jpeg_buffer_dest( &cinfo, &dest );
622//
623// dest.pub.next_output_byte = &out_buf[0];
624// dest.pub.free_in_buffer = out_buf.size();
625// }
626//
627// if( setjmp( jerr.setjmp_buffer ) == 0 )
628// {
629// cinfo.image_width = width;
630// cinfo.image_height = height;
631//
632// int _channels = img.channels();
633// int channels = _channels > 1 ? 3 : 1;
634// cinfo.input_components = channels;
635// cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
636//
637// int quality = 95;
638// int progressive = 0;
639// int optimize = 0;
640// int rst_interval = 0;
641// int luma_quality = -1;
642// int chroma_quality = -1;
643//
644// for( size_t i = 0; i < params.size(); i += 2 )
645// {
646// if( params[i] == CV_IMWRITE_JPEG_QUALITY )
647// {
648// quality = params[i+1];
649// quality = MIN(MAX(quality, 0), 100);
650// }
651//
652// if( params[i] == CV_IMWRITE_JPEG_PROGRESSIVE )
653// {
654// progressive = params[i+1];
655// }
656//
657// if( params[i] == CV_IMWRITE_JPEG_OPTIMIZE )
658// {
659// optimize = params[i+1];
660// }
661//
662// if( params[i] == CV_IMWRITE_JPEG_LUMA_QUALITY )
663// {
664// if (params[i+1] >= 0)
665// {
666// luma_quality = MIN(MAX(params[i+1], 0), 100);
667//
668// quality = luma_quality;
669//
670// if (chroma_quality < 0)
671// {
672// chroma_quality = luma_quality;
673// }
674// }
675// }
676//
677// if( params[i] == CV_IMWRITE_JPEG_CHROMA_QUALITY )
678// {
679// if (params[i+1] >= 0)
680// {
681// chroma_quality = MIN(MAX(params[i+1], 0), 100);
682// }
683// }
684//
685// if( params[i] == CV_IMWRITE_JPEG_RST_INTERVAL )
686// {
687// rst_interval = params[i+1];
688// rst_interval = MIN(MAX(rst_interval, 0), 65535L);
689// }
690// }
691//
692// jpeg_set_defaults( &cinfo );
693// cinfo.restart_interval = rst_interval;
694//
695// jpeg_set_quality( &cinfo, quality,
696// TRUE /* limit to baseline-JPEG values */ );
697// if( progressive )
698// jpeg_simple_progression( &cinfo );
699// if( optimize )
700// cinfo.optimize_coding = TRUE;
701//
702// #if JPEG_LIB_VERSION >= 70
703// if (luma_quality >= 0 && chroma_quality >= 0)
704// {
705// cinfo.q_scale_factor[0] = jpeg_quality_scaling(luma_quality);
706// cinfo.q_scale_factor[1] = jpeg_quality_scaling(chroma_quality);
707// if ( luma_quality != chroma_quality )
708// {
709// /* disable subsampling - ref. Libjpeg.txt */
710// cinfo.comp_info[0].v_samp_factor = 1;
711// cinfo.comp_info[0].h_samp_factor = 1;
712// cinfo.comp_info[1].v_samp_factor = 1;
713// cinfo.comp_info[1].h_samp_factor = 1;
714// }
715// jpeg_default_qtables( &cinfo, TRUE );
716// }
717// #endif // #if JPEG_LIB_VERSION >= 70
718//
719// jpeg_start_compress( &cinfo, TRUE );
720//
721// if( channels > 1 )
722// _buffer.allocate(width*channels);
723// buffer = _buffer.data();
724//
725// for( int y = 0; y < height; y++ )
726// {
727// uchar *data = img.data + img.step*y, *ptr = data;
728//
729// if( _channels == 3 )
730// {
731// icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, Size(width,1) );
732// ptr = buffer;
733// }
734// else if( _channels == 4 )
735// {
736// icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, Size(width,1), 2 );
737// ptr = buffer;
738// }
739//
740// jpeg_write_scanlines( &cinfo, &ptr, 1 );
741// }
742//
743// jpeg_finish_compress( &cinfo );
744// result = true;
745// }
746//
747//_exit_:
748//
749// if(!result)
750// {
751// char jmsg_buf[JMSG_LENGTH_MAX];
752// jerr.pub.format_message((j_common_ptr)&cinfo, jmsg_buf);
753// m_last_error = jmsg_buf;
754// }
755//
756// jpeg_destroy_compress( &cinfo );
757//
758// return result;
759//}
760//
761//}
762//
763// #endif
764//
765///* End of file. */
766