📄 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*/
#include "stdwin.h"
#include "grfmt_tiff.h"
#include <assert.h>
#include <string.h>
static const char fmtDescrTiff[] = "TIFF (*.tiff;*.tif)";
static const char fmtSignTiffII[] = "II\x2a\x00";
static const char fmtSignTiffMM[] = "MM\x00\x2a";
static const int tiffMask[] = { 0xff, 0xff, 0xffffffff, 0xffff, 0xffffffff };
/************************ TIFF reader *****************************/
GrFmtTiffReader::GrFmtTiffReader()
{
m_sign_len = 4;
m_signature = fmtSignTiffII;
m_description = fmtDescrTiff;
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;
}
void GrFmtTiffReader::ReadTable( int offset, int count,
TiffFieldType fieldType,
int*& array, int& arraysize )
{
int i;
if( count < 0 )
BAD_HEADER_ERR();
if( fieldType != TIFF_TYPE_SHORT &&
fieldType != TIFF_TYPE_LONG &&
fieldType != TIFF_TYPE_BYTE )
BAD_HEADER_ERR();
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;
}
}
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;
try
{
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();
ReadTable( value, count, fieldType, bpp_arr_ref, count );
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;
ReadTable( value, count, fieldType, m_offsets, m_maxoffsets );
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();
ReadTable( value, count, fieldType,
m_temp_palette, m_max_pal_length );
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*3] >> 3);
m_palette[i].g = (uchar)(m_temp_palette[i*3 + 1] >> 3);
m_palette[i].b = (uchar)(m_temp_palette[i*3 + 2] >> 3);
}
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 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -