📄 grfmt_tiff.cpp
字号:
/*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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -