📄 grfmt_tiff.cpp
字号:
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();
}
}
}
catch( int )
{
}
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 );
}
try
{
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:
CvtRGBToBGR( src, data, m_width );
break;
case 32:
CvtRGBAToBGR( src, data, m_width );
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:
CvtRGBToGray( src, data, m_width );
break;
case 32:
CvtRGBAToGray( src, data, m_width );
break;
default:
assert(0);
goto bad_decoding_end;
}
}
}
else
{
}
result = true;
bad_decoding_end:
;
}
}
catch( int )
{
}
if( src != buffer ) delete src;
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////
GrFmtTiffWriter::GrFmtTiffWriter()
{
m_description = fmtDescrTiff;
}
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 char* filename,
const uchar* data, int step,
int width, int height, bool isColor )
{
bool result = false;
int nch = isColor ? 3 : 1;
int fileStep = width*nch;
assert( data && width > 0 && height > 0 && step >= fileStep);
if( m_strm.Open( filename ) )
{
int rowsPerStrip = (1 << 13)/fileStep;
if( rowsPerStrip < 1 )
rowsPerStrip = 1;
if( rowsPerStrip > height )
rowsPerStrip = height;
int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip;
int uncompressedRowSize = rowsPerStrip * fileStep;
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;
int y = 0;
uncompressedRowSize;
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( isColor ) CvtRGBToBGR( data, buffer, width );
m_strm.PutBytes( isColor ? buffer : data, fileStep );
}
stripCounts[i] = (short)(m_strm.GetPos() - stripOffsets[i]);
assert( stripCounts[i] == uncompressedRowSize ||
stripCounts[i] < uncompressedRowSize &&
i == stripCount - 1);
}
if( stripCount > 1 )
{
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
{
stripOffsetsOffset = stripOffsets[0];
stripCountsOffset = stripCounts[0];
}
if( isColor )
{
bitsPerSample = m_strm.GetPos();
m_strm.PutWord(8);
m_strm.PutWord(8);
m_strm.PutWord(8);
}
directoryOffset = m_strm.GetPos();
// write header
m_strm.PutWord( 9 );
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, nch, bitsPerSample );
WriteTag( TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP );
WriteTag( TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, isColor ? 2 : 1 );
WriteTag( TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, nch );
WriteTag( TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip );
WriteTag( TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG,
stripCount, stripOffsetsOffset );
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( filename, "r+" );
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;
result = true;
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -