grfmt_jpeg.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,652 行 · 第 1/4 页
SVN-BASE
1,652 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_highgui.h"
#include "grfmt_jpeg.h"
// JPEG filter factory
GrFmtJpeg::GrFmtJpeg()
{
m_sign_len = 3;
m_signature = "\xFF\xD8\xFF";
m_description = "JPEG files (*.jpeg;*.jpg;*.jpe)";
}
GrFmtJpeg::~GrFmtJpeg()
{
}
GrFmtReader* GrFmtJpeg::NewReader( const char* filename )
{
return new GrFmtJpegReader( filename );
}
GrFmtWriter* GrFmtJpeg::NewWriter( const char* filename )
{
return new GrFmtJpegWriter( filename );
}
#ifdef HAVE_JPEG
/****************************************************************************************\
This part of the file implements JPEG codec on base of IJG libjpeg library,
in particular, this is the modified example.doc from libjpeg package.
See otherlibs/_graphics/readme.txt for copyright notice.
\****************************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#ifdef WIN32
#define XMD_H // prevent redefinition of INT32
#undef FAR // prevent FAR redefinition
#endif
#if defined WIN32 && defined __GNUC__
typedef unsigned char boolean;
#endif
extern "C" {
#include "jpeglib.h"
}
/////////////////////// Error processing /////////////////////
typedef struct GrFmtJpegErrorMgr
{
struct jpeg_error_mgr pub; /* "parent" structure */
jmp_buf setjmp_buffer; /* jump label */
}
GrFmtJpegErrorMgr;
METHODDEF(void)
error_exit( j_common_ptr cinfo )
{
GrFmtJpegErrorMgr* err_mgr = (GrFmtJpegErrorMgr*)(cinfo->err);
/* Return control to the setjmp point */
longjmp( err_mgr->setjmp_buffer, 1 );
}
/////////////////////// GrFmtJpegReader ///////////////////
GrFmtJpegReader::GrFmtJpegReader( const char* filename ) : GrFmtReader( filename )
{
m_cinfo = 0;
m_f = 0;
}
GrFmtJpegReader::~GrFmtJpegReader()
{
}
void GrFmtJpegReader::Close()
{
if( m_f )
{
fclose( m_f );
m_f = 0;
}
if( m_cinfo )
{
jpeg_decompress_struct* cinfo = (jpeg_decompress_struct*)m_cinfo;
GrFmtJpegErrorMgr* jerr = (GrFmtJpegErrorMgr*)m_jerr;
jpeg_destroy_decompress( cinfo );
delete cinfo;
delete jerr;
m_cinfo = 0;
m_jerr = 0;
}
GrFmtReader::Close();
}
bool GrFmtJpegReader::ReadHeader()
{
bool result = false;
Close();
jpeg_decompress_struct* cinfo = new jpeg_decompress_struct;
GrFmtJpegErrorMgr* jerr = new GrFmtJpegErrorMgr;
cinfo->err = jpeg_std_error(&jerr->pub);
jerr->pub.error_exit = error_exit;
m_cinfo = cinfo;
m_jerr = jerr;
if( setjmp( jerr->setjmp_buffer ) == 0 )
{
jpeg_create_decompress( cinfo );
m_f = fopen( m_filename, "rb" );
if( m_f )
{
jpeg_stdio_src( cinfo, m_f );
jpeg_read_header( cinfo, TRUE );
m_width = cinfo->image_width;
m_height = cinfo->image_height;
m_iscolor = cinfo->num_components > 1;
result = true;
}
}
if( !result )
Close();
return result;
}
bool GrFmtJpegReader::ReadData( uchar* data, int step, int color )
{
bool result = false;
color = color > 0 || (m_iscolor && color < 0);
if( m_cinfo && m_jerr && m_width && m_height )
{
jpeg_decompress_struct* cinfo = (jpeg_decompress_struct*)m_cinfo;
GrFmtJpegErrorMgr* jerr = (GrFmtJpegErrorMgr*)m_jerr;
JSAMPARRAY buffer = 0;
if( setjmp( jerr->setjmp_buffer ) == 0 )
{
int planes = m_iscolor ? 3 : 1;
int width_n = m_width * planes;
jpeg_start_decompress( cinfo );
buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo,
JPOOL_IMAGE, width_n, 1 );
for( ; m_height--; data += step )
{
jpeg_read_scanlines( cinfo, buffer, 1 );
if( color )
{
if( m_iscolor )
CvtRGBToBGR( buffer[0], data, m_width );
else
CvtGrayToBGR( buffer[0], data, m_width );
}
else
{
if( m_iscolor )
CvtRGBToGray( buffer[0], data, m_width );
else
memcpy( data, buffer[0], m_width );
}
}
result = true;
}
jpeg_finish_decompress( cinfo );
}
Close();
return result;
}
/////////////////////// GrFmtJpegWriter ///////////////////
GrFmtJpegWriter::GrFmtJpegWriter( const char* filename ) : GrFmtWriter( filename )
{
}
GrFmtJpegWriter::~GrFmtJpegWriter()
{
}
bool GrFmtJpegWriter::WriteImage( const uchar* data, int step,
int width, int height, bool isColor )
{
const int default_quality = 85;
struct jpeg_compress_struct cinfo;
GrFmtJpegErrorMgr jerr;
bool result = false;
FILE* f = 0;
int channels = isColor ? 3 : 1;
uchar* buffer = 0; // temporary buffer for row flipping
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = error_exit;
if( setjmp( jerr.setjmp_buffer ) == 0 )
{
jpeg_create_compress(&cinfo);
f = fopen( m_filename, "wb" );
if( f )
{
jpeg_stdio_dest( &cinfo, f );
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = channels;
cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
jpeg_set_defaults( &cinfo );
jpeg_set_quality( &cinfo, default_quality,
TRUE /* limit to baseline-JPEG values */ );
jpeg_start_compress( &cinfo, TRUE );
if( channels > 1 )
buffer = new uchar[width*channels];
for( ; height--; data += step )
{
uchar* ptr = (uchar*)data;
if( channels > 1 )
{
CvtRGBToBGR( data, buffer, width );
ptr = buffer;
}
jpeg_write_scanlines( &cinfo, &ptr, 1 );
}
jpeg_finish_compress( &cinfo );
result = true;
}
}
if(f) fclose(f);
jpeg_destroy_compress( &cinfo );
delete buffer;
return result;
}
#else
////////////////////// JPEG-oriented two-level bitstream ////////////////////////
RJpegBitStream::RJpegBitStream()
{
}
RJpegBitStream::~RJpegBitStream()
{
Close();
}
bool RJpegBitStream::Open( const char* filename )
{
Close();
Allocate();
m_is_opened = m_low_strm.Open( filename );
if( m_is_opened ) SetPos(0);
return m_is_opened;
}
void RJpegBitStream::Close()
{
m_low_strm.Close();
m_is_opened = false;
}
void RJpegBitStream::ReadBlock()
{
uchar* end = m_start + m_block_size;
uchar* current = m_start;
if( setjmp( m_low_strm.JmpBuf()) == 0 )
{
int sz = m_unGetsize;
memmove( current - sz, m_end - sz, sz );
while( current < end )
{
int val = m_low_strm.GetByte();
if( val != 0xff )
{
*current++ = (uchar)val;
}
else
{
val = m_low_strm.GetByte();
if( val == 0 )
*current++ = 0xFF;
else if( !(0xD0 <= val && val <= 0xD7) )
{
m_low_strm.SetPos( m_low_strm.GetPos() - 2 );
goto fetch_end;
}
}
}
fetch_end: ;
}
else
{
if( current == m_start && m_jmp_set )
longjmp( m_jmp_buf, RBS_THROW_EOS );
}
m_current = m_start;
m_end = m_start + (((current - m_start) + 3) & -4);
if( !bsIsBigEndian() )
bsBSwapBlock( m_start, m_end );
}
void RJpegBitStream::Flush()
{
m_end = m_start + m_block_size;
m_current = m_end - 4;
m_bit_idx = 0;
}
void RJpegBitStream::AlignOnByte()
{
m_bit_idx &= -8;
}
int RJpegBitStream::FindMarker()
{
int code = m_low_strm.GetWord();
while( (code & 0xFF00) != 0xFF00 || (code == 0xFFFF || code == 0xFF00 ))
{
code = ((code&255) << 8) | m_low_strm.GetByte();
}
return code;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?