X-Git-Url: http://git.maemo.org/git/?p=opencv;a=blobdiff_plain;f=otherlibs%2Fhighgui%2Fgrfmt_tiff.cpp;fp=otherlibs%2Fhighgui%2Fgrfmt_tiff.cpp;h=0000000000000000000000000000000000000000;hp=f69cc30eae1c85655bd62b8d07c3fc101997c27e;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hpb=454138ff8a20f6edb9b65a910101403d8b520643 diff --git a/otherlibs/highgui/grfmt_tiff.cpp b/otherlibs/highgui/grfmt_tiff.cpp deleted file mode 100644 index f69cc30..0000000 --- a/otherlibs/highgui/grfmt_tiff.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/*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; -} -