16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M/////////////////////////////////////////////////////////////////////////////////////// 26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By downloading, copying, installing or using the software you agree to this license. 66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// If you do not agree to this license, do not download, install, 76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// copy or use the software. 86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Intel License Agreement 116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// For Open Source Computer Vision Library 126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved. 146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners. 156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification, 176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met: 186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's of source code must retain the above copyright notice, 206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer. 216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's in binary form must reproduce the above copyright notice, 236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer in the documentation 246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and/or other materials provided with the distribution. 256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * The name of Intel Corporation may not be used to endorse or promote products 276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// derived from this software without specific prior written permission. 286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and 306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied 316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed. 326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct, 336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages 346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services; 356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused 366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability, 376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of 386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage. 396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/ 416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn A part of the file implements TIFF reader on base of libtiff library 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (see otherlibs/_graphics/readme.txt for copyright notice) 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_highgui.h" 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "grfmt_tiff.h" 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const char fmtSignTiffII[] = "II\x2a\x00"; 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const char fmtSignTiffMM[] = "MM\x00\x2a"; 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiff::GrFmtTiff() 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_sign_len = 4; 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_signature = ""; 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_description = "TIFF Files (*.tiff;*.tif)"; 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiff::~GrFmtTiff() 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiff::CheckSignature( const char* signature ) 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return memcmp( signature, fmtSignTiffII, 4 ) == 0 || 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcmp( signature, fmtSignTiffMM, 4 ) == 0; 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtReader* GrFmtTiff::NewReader( const char* filename ) 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return new GrFmtTiffReader( filename ); 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtWriter* GrFmtTiff::NewWriter( const char* filename ) 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return new GrFmtTiffWriter( filename ); 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef HAVE_TIFF 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "tiff.h" 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "tiffio.h" 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int grfmt_tiff_err_handler_init = 0; 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {} 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiffReader::GrFmtTiffReader( const char* filename ) : GrFmtReader( filename ) 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_tif = 0; 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !grfmt_tiff_err_handler_init ) 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grfmt_tiff_err_handler_init = 1; 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler ); 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler ); 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiffReader::~GrFmtTiffReader() 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid GrFmtTiffReader::Close() 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_tif ) 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFF* tif = (TIFF*)m_tif; 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFClose( tif ); 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_tif = 0; 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffReader::CheckFormat( const char* signature ) 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return memcmp( signature, fmtSignTiffII, 4 ) == 0 || 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcmp( signature, fmtSignTiffMM, 4 ) == 0; 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffReader::ReadHeader() 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char errmsg[1024]; 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool result = false; 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Close(); 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFF* tif = TIFFOpen( m_filename, "r" ); 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( tif ) 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int width = 0, height = 0, photometric = 0, compression = 0; 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_tif = tif; 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( TIFFRGBAImageOK( tif, errmsg ) && 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &width ) && 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &height ) && 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ) && 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (!TIFFGetField( tif, TIFFTAG_COMPRESSION, &compression ) || 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (compression != COMPRESSION_LZW && 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn compression != COMPRESSION_OJPEG))) 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_width = width; 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_height = height; 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_iscolor = photometric > 1; 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !result ) 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Close(); 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffReader::ReadData( uchar* data, int step, int color ) 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool result = false; 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* buffer = 0; 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn color = color > 0 || (color < 0 && m_iscolor); 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_tif && m_width && m_height ) 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFF* tif = (TIFF*)m_tif; 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int tile_width0 = m_width, tile_height0 = 0; 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x, y, i; 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int is_tiled = TIFFIsTiled(tif); 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_tiled && 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 ) || 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn is_tiled && 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) && 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 )) 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( tile_width0 <= 0 ) 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tile_width0 = m_width; 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( tile_height0 <= 0 ) 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tile_height0 = m_height; 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer = new uchar[tile_height0*tile_width0*4]; 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 ) 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int tile_height = tile_height0; 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y + tile_height > m_height ) 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tile_height = m_height - y; 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < m_width; x += tile_width0 ) 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int tile_width = tile_width0, ok; 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( x + tile_width > m_width ) 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tile_width = m_width - x; 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_tiled ) 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer ); 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer ); 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !ok ) 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn goto exit_func; 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < tile_height; i++ ) 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( color ) 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn data + x*3 + step*(tile_height - i - 1), 0, 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSize(tile_width,1), 2 ); 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0, 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn data + x + step*(tile_height - i - 1), 0, 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSize(tile_width,1), 2 ); 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennexit_func: 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Close(); 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] buffer; 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int tiffMask[] = { 0xff, 0xff, 0xffffffff, 0xffff, 0xffffffff }; 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/************************ TIFF reader *****************************/ 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiffReader::GrFmtTiffReader( const char* filename ) : GrFmtReader( filename ) 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_offsets = 0; 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_maxoffsets = 0; 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strips = -1; 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_max_pal_length = 0; 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_temp_palette = 0; 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiffReader::~GrFmtTiffReader() 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Close(); 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] m_offsets; 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] m_temp_palette; 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid GrFmtTiffReader::Close() 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.Close(); 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffReader::CheckFormat( const char* signature ) 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return memcmp( signature, fmtSignTiffII, 4 ) == 0 || 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcmp( signature, fmtSignTiffMM, 4 ) == 0; 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint GrFmtTiffReader::GetWordEx() 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int val = m_strm.GetWord(); 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_byteorder == TIFF_ORDER_MM ) 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val = ((val)>>8)|(((val)&0xff)<<8); 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return val; 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint GrFmtTiffReader::GetDWordEx() 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int val = m_strm.GetDWord(); 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_byteorder == TIFF_ORDER_MM ) 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val = BSWAP( val ); 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return val; 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint GrFmtTiffReader::ReadTable( int offset, int count, 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TiffFieldType fieldType, 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int*& array, int& arraysize ) 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count < 0 ) 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return RBS_BAD_HEADER; 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fieldType != TIFF_TYPE_SHORT && 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fieldType != TIFF_TYPE_LONG && 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fieldType != TIFF_TYPE_BYTE ) 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return RBS_BAD_HEADER; 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count > arraysize ) 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] array; 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn arraysize = arraysize*3/2; 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( arraysize < count ) 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn arraysize = count; 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array = new int[arraysize]; 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count > 1 ) 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int pos = m_strm.GetPos(); 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.SetPos( offset ); 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fieldType == TIFF_TYPE_LONG ) 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_byteorder == TIFF_ORDER_MM ) 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array[i] = ((RMByteStream&)m_strm).GetDWord(); 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array[i] = ((RLByteStream&)m_strm).GetDWord(); 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( fieldType == TIFF_TYPE_SHORT ) 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_byteorder == TIFF_ORDER_MM ) 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array[i] = ((RMByteStream&)m_strm).GetWord(); 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array[i] = ((RLByteStream&)m_strm).GetWord(); 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else // fieldType == TIFF_TYPE_BYTE 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array[i] = m_strm.GetByte(); 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.SetPos(pos); 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( (offset & ~tiffMask[fieldType]) == 0 ); 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn array[0] = offset; 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 0; 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffReader::ReadHeader() 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool result = false; 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int photometric = -1; 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int channels = 1; 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int pal_length = -1; 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int MAX_CHANNELS = 4; 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int bpp_arr[MAX_CHANNELS]; 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( strlen(m_filename) != 0 ); 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !m_strm.Open( m_filename )) return false; 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_width = -1; 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_height = -1; 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strips = -1; 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_bpp = 1; 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_compression = TIFF_UNCOMP; 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_rows_per_strip = -1; 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_iscolor = false; 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( setjmp( m_strm.JmpBuf()) == 0 ) 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_byteorder = (TiffByteOrder)m_strm.GetWord(); 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.Skip( 2 ); 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int header_offset = GetDWordEx(); 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.SetPos( header_offset ); 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // read the first tag directory 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, count = GetWordEx(); 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // read tag 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TiffTag tag = (TiffTag)GetWordEx(); 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TiffFieldType fieldType = (TiffFieldType)GetWordEx(); 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = GetDWordEx(); 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int value = GetDWordEx(); 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count == 1 ) 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_byteorder == TIFF_ORDER_MM ) 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fieldType == TIFF_TYPE_SHORT ) 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn value = (unsigned)value >> 16; 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( fieldType == TIFF_TYPE_BYTE ) 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn value = (unsigned)value >> 24; 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn value &= tiffMask[fieldType]; 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch( tag ) 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_WIDTH: 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_width = value; 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_HEIGHT: 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_height = value; 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_BITS_PER_SAMPLE: 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* bpp_arr_ref = bpp_arr; 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count > MAX_CHANNELS ) 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ReadTable( value, count, fieldType, bpp_arr_ref, count ) < 0 ) 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 1; j < count; j++ ) 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( bpp_arr[j] != bpp_arr[0] ) 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_bpp = bpp_arr[0]; 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_COMPRESSION: 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_compression = (TiffCompression)value; 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_compression != TIFF_UNCOMP && 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_compression != TIFF_HUFFMAN && 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_compression != TIFF_PACKBITS ) 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_PHOTOMETRIC: 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn photometric = value; 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)photometric > 3 ) 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_STRIP_OFFSETS: 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strips = count; 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ReadTable( value, count, fieldType, m_offsets, m_maxoffsets ) < 0 ) 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_SAMPLES_PER_PIXEL: 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn channels = value; 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( channels != 1 && channels != 3 && channels != 4 ) 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_ROWS_PER_STRIP: 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_rows_per_strip = value; 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_PLANAR_CONFIG: 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int planar_config = value; 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( planar_config != 1 ) 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_COLOR_MAP: 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fieldType != TIFF_TYPE_SHORT || count < 2 ) 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ReadTable( value, count, fieldType, 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_temp_palette, m_max_pal_length ) < 0 ) 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pal_length = count / 3; 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pal_length > 256 ) 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < pal_length; i++ ) 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_palette[i].r = (uchar)(m_temp_palette[i] >> 8); 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_palette[i].g = (uchar)(m_temp_palette[i + pal_length] >> 8); 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_palette[i].b = (uchar)(m_temp_palette[i + pal_length*2] >> 8); 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case TIFF_TAG_STRIP_COUNTS: 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_strips == 1 && m_rows_per_strip == -1 ) 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_rows_per_strip = m_height; 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_width > 0 && m_height > 0 && m_strips > 0 && 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (m_height + m_rows_per_strip - 1)/m_rows_per_strip == m_strips ) 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch( m_bpp ) 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 1: 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( photometric == 0 || photometric == 1 && channels == 1 ) 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillGrayPalette( m_palette, m_bpp, photometric == 0 ); 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_iscolor = false; 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 4: 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 8: 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (photometric == 0 || photometric == 1 || 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn photometric == 3 && pal_length == (1 << m_bpp)) && 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_compression != TIFF_HUFFMAN && channels == 1 ) 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pal_length < 0 ) 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillGrayPalette( m_palette, m_bpp, photometric == 0 ); 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_iscolor = false; 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_iscolor = IsColorPalette( m_palette, m_bpp ); 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( photometric == 2 && pal_length < 0 && 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (channels == 3 || channels == 4) && 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_compression == TIFF_UNCOMP ) 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_bpp = 8*channels; 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_iscolor = true; 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default: 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn BAD_HEADER_ERR(); 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbad_header_exit: 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ; 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !result ) 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strips = -1; 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_width = m_height = -1; 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.Close(); 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffReader::ReadData( uchar* data, int step, int color ) 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int buffer_size = 1 << 12; 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar buffer[buffer_size]; 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar gray_palette[256]; 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool result = false; 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* src = buffer; 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int src_pitch = (m_width*m_bpp + 7)/8; 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y = 0; 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_strips < 0 || !m_strm.IsOpened()) 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return false; 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( src_pitch+32 > buffer_size ) 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn src = new uchar[src_pitch+32]; 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !color ) 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_bpp <= 8 ) 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp ); 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( setjmp( m_strm.JmpBuf()) == 0 ) 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( int s = 0; s < m_strips; s++ ) 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y_limit = m_rows_per_strip; 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y_limit += y; 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( y_limit > m_height ) y_limit = m_height; 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.SetPos( m_offsets[s] ); 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_compression == TIFF_UNCOMP ) 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; y < y_limit; y++, data += step ) 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.GetBytes( src, src_pitch ); 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( color ) 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch( m_bpp ) 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 1: 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillColorRow1( data, src, m_width, m_palette ); 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 4: 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillColorRow4( data, src, m_width, m_palette ); 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 8: 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillColorRow8( data, src, m_width, m_palette ); 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 24: 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_RGB2BGR_8u_C3R( src, 0, data, 0, cvSize(m_width,1) ); 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 32: 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGRA2BGR_8u_C4C3R( src, 0, data, 0, cvSize(m_width,1), 2 ); 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default: 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert(0); 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn goto bad_decoding_end; 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch( m_bpp ) 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 1: 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillGrayRow1( data, src, m_width, gray_palette ); 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 4: 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillGrayRow4( data, src, m_width, gray_palette ); 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 8: 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FillGrayRow8( data, src, m_width, gray_palette ); 6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 24: 6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1), 2 ); 6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 32: 6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, cvSize(m_width,1), 2 ); 6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default: 6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert(0); 6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn goto bad_decoding_end; 6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbad_decoding_end: 6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ; 6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( src != buffer ) delete[] src; 6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////////////////////////////////////////////////////////////////////////////////////// 6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiffWriter::GrFmtTiffWriter( const char* filename ) : GrFmtWriter( filename ) 6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennGrFmtTiffWriter::~GrFmtTiffWriter() 6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid GrFmtTiffWriter::WriteTag( TiffTag tag, TiffFieldType fieldType, 6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count, int value ) 6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord( tag ); 6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord( fieldType ); 6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutDWord( count ); 6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutDWord( value ); 6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennbool GrFmtTiffWriter::WriteImage( const uchar* data, int step, 6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int width, int height, int /*depth*/, int channels ) 6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bool result = false; 6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int fileStep = width*channels; 6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( data && width > 0 && height > 0 && step >= fileStep); 6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m_strm.Open( m_filename ) ) 6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int rowsPerStrip = (1 << 13)/fileStep; 6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( rowsPerStrip < 1 ) 6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rowsPerStrip = 1; 6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( rowsPerStrip > height ) 6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn rowsPerStrip = height; 6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip; 7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*#if defined _DEBUG || !defined WIN32 7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int uncompressedRowSize = rowsPerStrip * fileStep; 7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif*/ 7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int directoryOffset = 0; 7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* stripOffsets = new int[stripCount]; 7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn short* stripCounts = new short[stripCount]; 7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* buffer = new uchar[fileStep + 32]; 7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int stripOffsetsOffset = 0; 7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int stripCountsOffset = 0; 7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int bitsPerSample = 8; // TODO support 16 bit 7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int y = 0; 7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutBytes( fmtSignTiffII, 4 ); 7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutDWord( directoryOffset ); 7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // write an image data first (the most reasonable way 7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // for compressed images) 7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < stripCount; i++ ) 7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int limit = y + rowsPerStrip; 7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( limit > height ) 7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn limit = height; 7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripOffsets[i] = m_strm.GetPos(); 7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; y < limit; y++, data += step ) 7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( channels == 3 ) 7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, cvSize(width,1) ); 7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( channels == 4 ) 7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvCvt_BGRA2RGBA_8u_C4R( data, 0, buffer, 0, cvSize(width,1) ); 7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutBytes( channels > 1 ? buffer : data, fileStep ); 7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCounts[i] = (short)(m_strm.GetPos() - stripOffsets[i]); 7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*assert( stripCounts[i] == uncompressedRowSize || 7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCounts[i] < uncompressedRowSize && 7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn i == stripCount - 1);*/ 7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( stripCount > 2 ) 7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripOffsetsOffset = m_strm.GetPos(); 7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < stripCount; i++ ) 7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutDWord( stripOffsets[i] ); 7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCountsOffset = m_strm.GetPos(); 7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < stripCount; i++ ) 7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord( stripCounts[i] ); 7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if(stripCount == 2) 7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripOffsetsOffset = m_strm.GetPos(); 7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < stripCount; i++) 7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutDWord (stripOffsets [i]); 7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCountsOffset = stripCounts [0] + (stripCounts [1] << 16); 7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripOffsetsOffset = stripOffsets[0]; 7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCountsOffset = stripCounts[0]; 7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( channels > 1 ) 7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn bitsPerSample = m_strm.GetPos(); 7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord(8); 7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord(8); 7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord(8); 7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( channels == 4 ) 7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord(8); 7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn directoryOffset = m_strm.GetPos(); 7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // write header 7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutWord( 9 ); 7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* warning: specification 5.0 of Tiff want to have tags in 7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ascending order. This is a non-fatal error, but this cause 7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn warning with some tools. So, keep this in ascending order */ 7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width ); 7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height ); 7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_BITS_PER_SAMPLE, 7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn TIFF_TYPE_SHORT, channels, bitsPerSample ); 7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP ); 7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, channels > 1 ? 2 : 1 ); 7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG, 7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCount, stripOffsetsOffset ); 7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, channels ); 7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip ); 7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn WriteTag( TIFF_TAG_STRIP_COUNTS, 8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG, 8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stripCount, stripCountsOffset ); 8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.PutDWord(0); 8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_strm.Close(); 8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // write directory offset 8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn FILE* f = fopen( m_filename, "r+b" ); 8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[0] = (uchar)directoryOffset; 8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[1] = (uchar)(directoryOffset >> 8); 8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[2] = (uchar)(directoryOffset >> 16); 8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[3] = (uchar)(directoryOffset >> 24); 8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fseek( f, 4, SEEK_SET ); 8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fwrite( buffer, 1, 4, f ); 8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fclose(f); 8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] stripOffsets; 8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] stripCounts; 8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delete[] buffer; 8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = true; 8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 827