完善目录结构
完善了目录结构,添加了以前的web段com组件调用的代码(在/测试目录下)(部署没有使用到)
This commit is contained in:
@@ -0,0 +1,826 @@
|
||||
/*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*/
|
||||
|
||||
/****************************************************************************************\
|
||||
A part of the file implements TIFF reader on base of libtiff library
|
||||
(see otherlibs/_graphics/readme.txt for copyright notice)
|
||||
\****************************************************************************************/
|
||||
|
||||
#include "_highgui.h"
|
||||
#include "grfmt_tiff.h"
|
||||
|
||||
static const char fmtSignTiffII[] = "II\x2a\x00";
|
||||
static const char fmtSignTiffMM[] = "MM\x00\x2a";
|
||||
|
||||
GrFmtTiff::GrFmtTiff()
|
||||
{
|
||||
m_sign_len = 4;
|
||||
m_signature = "";
|
||||
m_description = "TIFF Files (*.tiff;*.tif)";
|
||||
}
|
||||
|
||||
GrFmtTiff::~GrFmtTiff()
|
||||
{
|
||||
}
|
||||
|
||||
bool GrFmtTiff::CheckSignature( const char* signature )
|
||||
{
|
||||
return memcmp( signature, fmtSignTiffII, 4 ) == 0 ||
|
||||
memcmp( signature, fmtSignTiffMM, 4 ) == 0;
|
||||
}
|
||||
|
||||
|
||||
GrFmtReader* GrFmtTiff::NewReader( const char* filename )
|
||||
{
|
||||
return new GrFmtTiffReader( filename );
|
||||
}
|
||||
|
||||
|
||||
GrFmtWriter* GrFmtTiff::NewWriter( const char* filename )
|
||||
{
|
||||
return new GrFmtTiffWriter( filename );
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
#include "tiff.h"
|
||||
#include "tiffio.h"
|
||||
|
||||
static int grfmt_tiff_err_handler_init = 0;
|
||||
|
||||
static void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {}
|
||||
|
||||
GrFmtTiffReader::GrFmtTiffReader( const char* filename ) : GrFmtReader( filename )
|
||||
{
|
||||
m_tif = 0;
|
||||
|
||||
if( !grfmt_tiff_err_handler_init )
|
||||
{
|
||||
grfmt_tiff_err_handler_init = 1;
|
||||
|
||||
TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler );
|
||||
TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GrFmtTiffReader::~GrFmtTiffReader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GrFmtTiffReader::Close()
|
||||
{
|
||||
if( m_tif )
|
||||
{
|
||||
TIFF* tif = (TIFF*)m_tif;
|
||||
TIFFClose( tif );
|
||||
m_tif = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffReader::CheckFormat( const char* signature )
|
||||
{
|
||||
return memcmp( signature, fmtSignTiffII, 4 ) == 0 ||
|
||||
memcmp( signature, fmtSignTiffMM, 4 ) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffReader::ReadHeader()
|
||||
{
|
||||
char errmsg[1024];
|
||||
bool result = false;
|
||||
|
||||
Close();
|
||||
TIFF* tif = TIFFOpen( m_filename, "r" );
|
||||
|
||||
if( tif )
|
||||
{
|
||||
int width = 0, height = 0, photometric = 0, compression = 0;
|
||||
m_tif = tif;
|
||||
|
||||
if( TIFFRGBAImageOK( tif, errmsg ) &&
|
||||
TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &width ) &&
|
||||
TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &height ) &&
|
||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ) &&
|
||||
(!TIFFGetField( tif, TIFFTAG_COMPRESSION, &compression ) ||
|
||||
(compression != COMPRESSION_LZW &&
|
||||
compression != COMPRESSION_OJPEG)))
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_iscolor = photometric > 1;
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !result )
|
||||
Close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffReader::ReadData( uchar* data, int step, int color )
|
||||
{
|
||||
bool result = false;
|
||||
uchar* buffer = 0;
|
||||
|
||||
color = color > 0 || (color < 0 && m_iscolor);
|
||||
|
||||
if( m_tif && m_width && m_height )
|
||||
{
|
||||
TIFF* tif = (TIFF*)m_tif;
|
||||
int tile_width0 = m_width, tile_height0 = 0;
|
||||
int x, y, i;
|
||||
int is_tiled = TIFFIsTiled(tif);
|
||||
|
||||
if( !is_tiled &&
|
||||
TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 ) ||
|
||||
is_tiled &&
|
||||
TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) &&
|
||||
TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 ))
|
||||
{
|
||||
if( tile_width0 <= 0 )
|
||||
tile_width0 = m_width;
|
||||
|
||||
if( tile_height0 <= 0 )
|
||||
tile_height0 = m_height;
|
||||
|
||||
buffer = new uchar[tile_height0*tile_width0*4];
|
||||
|
||||
for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 )
|
||||
{
|
||||
int tile_height = tile_height0;
|
||||
|
||||
if( y + tile_height > m_height )
|
||||
tile_height = m_height - y;
|
||||
|
||||
for( x = 0; x < m_width; x += tile_width0 )
|
||||
{
|
||||
int tile_width = tile_width0, ok;
|
||||
|
||||
if( x + tile_width > m_width )
|
||||
tile_width = m_width - x;
|
||||
|
||||
if( !is_tiled )
|
||||
ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
|
||||
else
|
||||
ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );
|
||||
|
||||
if( !ok )
|
||||
goto exit_func;
|
||||
|
||||
for( i = 0; i < tile_height; i++ )
|
||||
if( color )
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
|
||||
data + x*3 + step*(tile_height - i - 1), 0,
|
||||
cvSize(tile_width,1), 2 );
|
||||
else
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
|
||||
data + x + step*(tile_height - i - 1), 0,
|
||||
cvSize(tile_width,1), 2 );
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
exit_func:
|
||||
|
||||
Close();
|
||||
delete[] buffer;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static const int tiffMask[] = { 0xff, 0xff, 0xffffffff, 0xffff, 0xffffffff };
|
||||
|
||||
/************************ TIFF reader *****************************/
|
||||
|
||||
GrFmtTiffReader::GrFmtTiffReader( const char* filename ) : GrFmtReader( filename )
|
||||
{
|
||||
m_offsets = 0;
|
||||
m_maxoffsets = 0;
|
||||
m_strips = -1;
|
||||
m_max_pal_length = 0;
|
||||
m_temp_palette = 0;
|
||||
}
|
||||
|
||||
|
||||
GrFmtTiffReader::~GrFmtTiffReader()
|
||||
{
|
||||
Close();
|
||||
|
||||
delete[] m_offsets;
|
||||
delete[] m_temp_palette;
|
||||
}
|
||||
|
||||
void GrFmtTiffReader::Close()
|
||||
{
|
||||
m_strm.Close();
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffReader::CheckFormat( const char* signature )
|
||||
{
|
||||
return memcmp( signature, fmtSignTiffII, 4 ) == 0 ||
|
||||
memcmp( signature, fmtSignTiffMM, 4 ) == 0;
|
||||
}
|
||||
|
||||
|
||||
int GrFmtTiffReader::GetWordEx()
|
||||
{
|
||||
int val = m_strm.GetWord();
|
||||
if( m_byteorder == TIFF_ORDER_MM )
|
||||
val = ((val)>>8)|(((val)&0xff)<<8);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int GrFmtTiffReader::GetDWordEx()
|
||||
{
|
||||
int val = m_strm.GetDWord();
|
||||
if( m_byteorder == TIFF_ORDER_MM )
|
||||
val = BSWAP( val );
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int GrFmtTiffReader::ReadTable( int offset, int count,
|
||||
TiffFieldType fieldType,
|
||||
int*& array, int& arraysize )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( count < 0 )
|
||||
return RBS_BAD_HEADER;
|
||||
|
||||
if( fieldType != TIFF_TYPE_SHORT &&
|
||||
fieldType != TIFF_TYPE_LONG &&
|
||||
fieldType != TIFF_TYPE_BYTE )
|
||||
return RBS_BAD_HEADER;
|
||||
|
||||
if( count > arraysize )
|
||||
{
|
||||
delete[] array;
|
||||
arraysize = arraysize*3/2;
|
||||
if( arraysize < count )
|
||||
arraysize = count;
|
||||
array = new int[arraysize];
|
||||
}
|
||||
|
||||
if( count > 1 )
|
||||
{
|
||||
int pos = m_strm.GetPos();
|
||||
m_strm.SetPos( offset );
|
||||
|
||||
if( fieldType == TIFF_TYPE_LONG )
|
||||
{
|
||||
if( m_byteorder == TIFF_ORDER_MM )
|
||||
for( i = 0; i < count; i++ )
|
||||
array[i] = ((RMByteStream&)m_strm).GetDWord();
|
||||
else
|
||||
for( i = 0; i < count; i++ )
|
||||
array[i] = ((RLByteStream&)m_strm).GetDWord();
|
||||
}
|
||||
else if( fieldType == TIFF_TYPE_SHORT )
|
||||
{
|
||||
if( m_byteorder == TIFF_ORDER_MM )
|
||||
for( i = 0; i < count; i++ )
|
||||
array[i] = ((RMByteStream&)m_strm).GetWord();
|
||||
else
|
||||
for( i = 0; i < count; i++ )
|
||||
array[i] = ((RLByteStream&)m_strm).GetWord();
|
||||
}
|
||||
else // fieldType == TIFF_TYPE_BYTE
|
||||
for( i = 0; i < count; i++ )
|
||||
array[i] = m_strm.GetByte();
|
||||
|
||||
m_strm.SetPos(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( (offset & ~tiffMask[fieldType]) == 0 );
|
||||
array[0] = offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffReader::ReadHeader()
|
||||
{
|
||||
bool result = false;
|
||||
int photometric = -1;
|
||||
int channels = 1;
|
||||
int pal_length = -1;
|
||||
|
||||
const int MAX_CHANNELS = 4;
|
||||
int bpp_arr[MAX_CHANNELS];
|
||||
|
||||
assert( strlen(m_filename) != 0 );
|
||||
if( !m_strm.Open( m_filename )) return false;
|
||||
|
||||
m_width = -1;
|
||||
m_height = -1;
|
||||
m_strips = -1;
|
||||
m_bpp = 1;
|
||||
m_compression = TIFF_UNCOMP;
|
||||
m_rows_per_strip = -1;
|
||||
m_iscolor = false;
|
||||
|
||||
if( setjmp( m_strm.JmpBuf()) == 0 )
|
||||
{
|
||||
m_byteorder = (TiffByteOrder)m_strm.GetWord();
|
||||
m_strm.Skip( 2 );
|
||||
int header_offset = GetDWordEx();
|
||||
|
||||
m_strm.SetPos( header_offset );
|
||||
|
||||
// read the first tag directory
|
||||
int i, j, count = GetWordEx();
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
// read tag
|
||||
TiffTag tag = (TiffTag)GetWordEx();
|
||||
TiffFieldType fieldType = (TiffFieldType)GetWordEx();
|
||||
int count = GetDWordEx();
|
||||
int value = GetDWordEx();
|
||||
if( count == 1 )
|
||||
{
|
||||
if( m_byteorder == TIFF_ORDER_MM )
|
||||
{
|
||||
if( fieldType == TIFF_TYPE_SHORT )
|
||||
value = (unsigned)value >> 16;
|
||||
else if( fieldType == TIFF_TYPE_BYTE )
|
||||
value = (unsigned)value >> 24;
|
||||
}
|
||||
|
||||
value &= tiffMask[fieldType];
|
||||
}
|
||||
|
||||
switch( tag )
|
||||
{
|
||||
case TIFF_TAG_WIDTH:
|
||||
m_width = value;
|
||||
break;
|
||||
|
||||
case TIFF_TAG_HEIGHT:
|
||||
m_height = value;
|
||||
break;
|
||||
|
||||
case TIFF_TAG_BITS_PER_SAMPLE:
|
||||
{
|
||||
int* bpp_arr_ref = bpp_arr;
|
||||
|
||||
if( count > MAX_CHANNELS )
|
||||
BAD_HEADER_ERR();
|
||||
|
||||
if( ReadTable( value, count, fieldType, bpp_arr_ref, count ) < 0 )
|
||||
BAD_HEADER_ERR();
|
||||
|
||||
for( j = 1; j < count; j++ )
|
||||
{
|
||||
if( bpp_arr[j] != bpp_arr[0] )
|
||||
BAD_HEADER_ERR();
|
||||
}
|
||||
|
||||
m_bpp = bpp_arr[0];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TIFF_TAG_COMPRESSION:
|
||||
m_compression = (TiffCompression)value;
|
||||
if( m_compression != TIFF_UNCOMP &&
|
||||
m_compression != TIFF_HUFFMAN &&
|
||||
m_compression != TIFF_PACKBITS )
|
||||
BAD_HEADER_ERR();
|
||||
break;
|
||||
|
||||
case TIFF_TAG_PHOTOMETRIC:
|
||||
photometric = value;
|
||||
if( (unsigned)photometric > 3 )
|
||||
BAD_HEADER_ERR();
|
||||
break;
|
||||
|
||||
case TIFF_TAG_STRIP_OFFSETS:
|
||||
m_strips = count;
|
||||
if( ReadTable( value, count, fieldType, m_offsets, m_maxoffsets ) < 0 )
|
||||
BAD_HEADER_ERR();
|
||||
break;
|
||||
|
||||
case TIFF_TAG_SAMPLES_PER_PIXEL:
|
||||
channels = value;
|
||||
if( channels != 1 && channels != 3 && channels != 4 )
|
||||
BAD_HEADER_ERR();
|
||||
break;
|
||||
|
||||
case TIFF_TAG_ROWS_PER_STRIP:
|
||||
m_rows_per_strip = value;
|
||||
break;
|
||||
|
||||
case TIFF_TAG_PLANAR_CONFIG:
|
||||
{
|
||||
int planar_config = value;
|
||||
if( planar_config != 1 )
|
||||
BAD_HEADER_ERR();
|
||||
}
|
||||
break;
|
||||
|
||||
case TIFF_TAG_COLOR_MAP:
|
||||
if( fieldType != TIFF_TYPE_SHORT || count < 2 )
|
||||
BAD_HEADER_ERR();
|
||||
if( ReadTable( value, count, fieldType,
|
||||
m_temp_palette, m_max_pal_length ) < 0 )
|
||||
BAD_HEADER_ERR();
|
||||
pal_length = count / 3;
|
||||
if( pal_length > 256 )
|
||||
BAD_HEADER_ERR();
|
||||
for( i = 0; i < pal_length; i++ )
|
||||
{
|
||||
m_palette[i].r = (uchar)(m_temp_palette[i] >> 8);
|
||||
m_palette[i].g = (uchar)(m_temp_palette[i + pal_length] >> 8);
|
||||
m_palette[i].b = (uchar)(m_temp_palette[i + pal_length*2] >> 8);
|
||||
}
|
||||
break;
|
||||
case TIFF_TAG_STRIP_COUNTS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_strips == 1 && m_rows_per_strip == -1 )
|
||||
m_rows_per_strip = m_height;
|
||||
|
||||
if( m_width > 0 && m_height > 0 && m_strips > 0 &&
|
||||
(m_height + m_rows_per_strip - 1)/m_rows_per_strip == m_strips )
|
||||
{
|
||||
switch( m_bpp )
|
||||
{
|
||||
case 1:
|
||||
if( photometric == 0 || photometric == 1 && channels == 1 )
|
||||
{
|
||||
FillGrayPalette( m_palette, m_bpp, photometric == 0 );
|
||||
result = true;
|
||||
m_iscolor = false;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 8:
|
||||
if( (photometric == 0 || photometric == 1 ||
|
||||
photometric == 3 && pal_length == (1 << m_bpp)) &&
|
||||
m_compression != TIFF_HUFFMAN && channels == 1 )
|
||||
{
|
||||
if( pal_length < 0 )
|
||||
{
|
||||
FillGrayPalette( m_palette, m_bpp, photometric == 0 );
|
||||
m_iscolor = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iscolor = IsColorPalette( m_palette, m_bpp );
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else if( photometric == 2 && pal_length < 0 &&
|
||||
(channels == 3 || channels == 4) &&
|
||||
m_compression == TIFF_UNCOMP )
|
||||
{
|
||||
m_bpp = 8*channels;
|
||||
m_iscolor = true;
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BAD_HEADER_ERR();
|
||||
}
|
||||
}
|
||||
bad_header_exit:
|
||||
;
|
||||
}
|
||||
|
||||
if( !result )
|
||||
{
|
||||
m_strips = -1;
|
||||
m_width = m_height = -1;
|
||||
m_strm.Close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffReader::ReadData( uchar* data, int step, int color )
|
||||
{
|
||||
const int buffer_size = 1 << 12;
|
||||
uchar buffer[buffer_size];
|
||||
uchar gray_palette[256];
|
||||
bool result = false;
|
||||
uchar* src = buffer;
|
||||
int src_pitch = (m_width*m_bpp + 7)/8;
|
||||
int y = 0;
|
||||
|
||||
if( m_strips < 0 || !m_strm.IsOpened())
|
||||
return false;
|
||||
|
||||
if( src_pitch+32 > buffer_size )
|
||||
src = new uchar[src_pitch+32];
|
||||
|
||||
if( !color )
|
||||
if( m_bpp <= 8 )
|
||||
{
|
||||
CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );
|
||||
}
|
||||
|
||||
if( setjmp( m_strm.JmpBuf()) == 0 )
|
||||
{
|
||||
for( int s = 0; s < m_strips; s++ )
|
||||
{
|
||||
int y_limit = m_rows_per_strip;
|
||||
|
||||
y_limit += y;
|
||||
if( y_limit > m_height ) y_limit = m_height;
|
||||
|
||||
m_strm.SetPos( m_offsets[s] );
|
||||
|
||||
if( m_compression == TIFF_UNCOMP )
|
||||
{
|
||||
for( ; y < y_limit; y++, data += step )
|
||||
{
|
||||
m_strm.GetBytes( src, src_pitch );
|
||||
if( color )
|
||||
switch( m_bpp )
|
||||
{
|
||||
case 1:
|
||||
FillColorRow1( data, src, m_width, m_palette );
|
||||
break;
|
||||
case 4:
|
||||
FillColorRow4( data, src, m_width, m_palette );
|
||||
break;
|
||||
case 8:
|
||||
FillColorRow8( data, src, m_width, m_palette );
|
||||
break;
|
||||
case 24:
|
||||
icvCvt_RGB2BGR_8u_C3R( src, 0, data, 0, cvSize(m_width,1) );
|
||||
break;
|
||||
case 32:
|
||||
icvCvt_BGRA2BGR_8u_C4C3R( src, 0, data, 0, cvSize(m_width,1), 2 );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
goto bad_decoding_end;
|
||||
}
|
||||
else
|
||||
switch( m_bpp )
|
||||
{
|
||||
case 1:
|
||||
FillGrayRow1( data, src, m_width, gray_palette );
|
||||
break;
|
||||
case 4:
|
||||
FillGrayRow4( data, src, m_width, gray_palette );
|
||||
break;
|
||||
case 8:
|
||||
FillGrayRow8( data, src, m_width, gray_palette );
|
||||
break;
|
||||
case 24:
|
||||
icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1), 2 );
|
||||
break;
|
||||
case 32:
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, cvSize(m_width,1), 2 );
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
goto bad_decoding_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
bad_decoding_end:
|
||||
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if( src != buffer ) delete[] src;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrFmtTiffWriter::GrFmtTiffWriter( const char* filename ) : GrFmtWriter( filename )
|
||||
{
|
||||
}
|
||||
|
||||
GrFmtTiffWriter::~GrFmtTiffWriter()
|
||||
{
|
||||
}
|
||||
|
||||
void GrFmtTiffWriter::WriteTag( TiffTag tag, TiffFieldType fieldType,
|
||||
int count, int value )
|
||||
{
|
||||
m_strm.PutWord( tag );
|
||||
m_strm.PutWord( fieldType );
|
||||
m_strm.PutDWord( count );
|
||||
m_strm.PutDWord( value );
|
||||
}
|
||||
|
||||
|
||||
bool GrFmtTiffWriter::WriteImage( const uchar* data, int step,
|
||||
int width, int height, int /*depth*/, int channels )
|
||||
{
|
||||
bool result = false;
|
||||
int fileStep = width*channels;
|
||||
|
||||
assert( data && width > 0 && height > 0 && step >= fileStep);
|
||||
|
||||
if( m_strm.Open( m_filename ) )
|
||||
{
|
||||
int rowsPerStrip = (1 << 13)/fileStep;
|
||||
|
||||
if( rowsPerStrip < 1 )
|
||||
rowsPerStrip = 1;
|
||||
|
||||
if( rowsPerStrip > height )
|
||||
rowsPerStrip = height;
|
||||
|
||||
int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip;
|
||||
/*#if defined _DEBUG || !defined WIN32
|
||||
int uncompressedRowSize = rowsPerStrip * fileStep;
|
||||
#endif*/
|
||||
int directoryOffset = 0;
|
||||
|
||||
int* stripOffsets = new int[stripCount];
|
||||
short* stripCounts = new short[stripCount];
|
||||
uchar* buffer = new uchar[fileStep + 32];
|
||||
int stripOffsetsOffset = 0;
|
||||
int stripCountsOffset = 0;
|
||||
int bitsPerSample = 8; // TODO support 16 bit
|
||||
int y = 0;
|
||||
|
||||
m_strm.PutBytes( fmtSignTiffII, 4 );
|
||||
m_strm.PutDWord( directoryOffset );
|
||||
|
||||
// write an image data first (the most reasonable way
|
||||
// for compressed images)
|
||||
for( i = 0; i < stripCount; i++ )
|
||||
{
|
||||
int limit = y + rowsPerStrip;
|
||||
|
||||
if( limit > height )
|
||||
limit = height;
|
||||
|
||||
stripOffsets[i] = m_strm.GetPos();
|
||||
|
||||
for( ; y < limit; y++, data += step )
|
||||
{
|
||||
if( channels == 3 )
|
||||
icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, cvSize(width,1) );
|
||||
else if( channels == 4 )
|
||||
icvCvt_BGRA2RGBA_8u_C4R( data, 0, buffer, 0, cvSize(width,1) );
|
||||
|
||||
m_strm.PutBytes( channels > 1 ? buffer : data, fileStep );
|
||||
}
|
||||
|
||||
stripCounts[i] = (short)(m_strm.GetPos() - stripOffsets[i]);
|
||||
/*assert( stripCounts[i] == uncompressedRowSize ||
|
||||
stripCounts[i] < uncompressedRowSize &&
|
||||
i == stripCount - 1);*/
|
||||
}
|
||||
|
||||
if( stripCount > 2 )
|
||||
{
|
||||
stripOffsetsOffset = m_strm.GetPos();
|
||||
for( i = 0; i < stripCount; i++ )
|
||||
m_strm.PutDWord( stripOffsets[i] );
|
||||
|
||||
stripCountsOffset = m_strm.GetPos();
|
||||
for( i = 0; i < stripCount; i++ )
|
||||
m_strm.PutWord( stripCounts[i] );
|
||||
}
|
||||
else if(stripCount == 2)
|
||||
{
|
||||
stripOffsetsOffset = m_strm.GetPos();
|
||||
for (i = 0; i < stripCount; i++)
|
||||
{
|
||||
m_strm.PutDWord (stripOffsets [i]);
|
||||
}
|
||||
stripCountsOffset = stripCounts [0] + (stripCounts [1] << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
stripOffsetsOffset = stripOffsets[0];
|
||||
stripCountsOffset = stripCounts[0];
|
||||
}
|
||||
|
||||
if( channels > 1 )
|
||||
{
|
||||
bitsPerSample = m_strm.GetPos();
|
||||
m_strm.PutWord(8);
|
||||
m_strm.PutWord(8);
|
||||
m_strm.PutWord(8);
|
||||
if( channels == 4 )
|
||||
m_strm.PutWord(8);
|
||||
}
|
||||
|
||||
directoryOffset = m_strm.GetPos();
|
||||
|
||||
// write header
|
||||
m_strm.PutWord( 9 );
|
||||
|
||||
/* warning: specification 5.0 of Tiff want to have tags in
|
||||
ascending order. This is a non-fatal error, but this cause
|
||||
warning with some tools. So, keep this in ascending order */
|
||||
|
||||
WriteTag( TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width );
|
||||
WriteTag( TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height );
|
||||
WriteTag( TIFF_TAG_BITS_PER_SAMPLE,
|
||||
TIFF_TYPE_SHORT, channels, bitsPerSample );
|
||||
WriteTag( TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP );
|
||||
WriteTag( TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, channels > 1 ? 2 : 1 );
|
||||
|
||||
WriteTag( TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG,
|
||||
stripCount, stripOffsetsOffset );
|
||||
|
||||
WriteTag( TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, channels );
|
||||
WriteTag( TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip );
|
||||
|
||||
WriteTag( TIFF_TAG_STRIP_COUNTS,
|
||||
stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG,
|
||||
stripCount, stripCountsOffset );
|
||||
|
||||
m_strm.PutDWord(0);
|
||||
m_strm.Close();
|
||||
|
||||
// write directory offset
|
||||
FILE* f = fopen( m_filename, "r+b" );
|
||||
buffer[0] = (uchar)directoryOffset;
|
||||
buffer[1] = (uchar)(directoryOffset >> 8);
|
||||
buffer[2] = (uchar)(directoryOffset >> 16);
|
||||
buffer[3] = (uchar)(directoryOffset >> 24);
|
||||
|
||||
fseek( f, 4, SEEK_SET );
|
||||
fwrite( buffer, 1, 4, f );
|
||||
fclose(f);
|
||||
|
||||
delete[] stripOffsets;
|
||||
delete[] stripCounts;
|
||||
delete[] buffer;
|
||||
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user