From eaad74ed602426add83b8c059140b64500d3d95f Mon Sep 17 00:00:00 2001 From: Frank Warmerdam Date: Fri, 28 Jan 2000 15:02:10 +0000 Subject: [PATCH] obsolete --- contrib/addtiffo/rawblockedimage.cpp | 403 ------------------- contrib/addtiffo/rawblockedimage.h | 108 ------ contrib/addtiffo/tif_overview.cpp | 559 --------------------------- 3 files changed, 1070 deletions(-) delete mode 100644 contrib/addtiffo/rawblockedimage.cpp delete mode 100644 contrib/addtiffo/rawblockedimage.h delete mode 100644 contrib/addtiffo/tif_overview.cpp diff --git a/contrib/addtiffo/rawblockedimage.cpp b/contrib/addtiffo/rawblockedimage.cpp deleted file mode 100644 index 65cde3f4..00000000 --- a/contrib/addtiffo/rawblockedimage.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/****************************************************************************** - * $Id: rawblockedimage.cpp,v 1.1 1999-08-17 01:47:59 warmerda Exp $ - * - * Project: GeoTIFF Overview Builder - * Purpose: Implement the RawBlockedImage class, for holding ``under - * construction'' overviews in a temporary file. - * Author: Frank Warmerdam, warmerda@home.com - * - ****************************************************************************** - * Copyright (c) 1999, Frank Warmerdam - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log: rawblockedimage.cpp,v $ - * Revision 1.1 1999-08-17 01:47:59 warmerda - * New - * - * Revision 1.2 1999/03/12 17:29:34 warmerda - * Use _WIN32 rather than WIN32. - * - */ - -#include -#include - -#include - -#ifndef _WIN32 -# include -#endif - -#include "rawblockedimage.h" - -#ifndef FALSE -# define FALSE 0 -# define TRUE 1 -#endif - -#ifndef MAX -# define MIN(a,b) ((ab) ? a : b) -#endif - -/************************************************************************/ -/* RawBlockedImage() */ -/************************************************************************/ - -RawBlockedImage::RawBlockedImage( int nXSizeIn, int nYSizeIn, - int nBlockXSizeIn, int nBlockYSizeIn, - int nBitsPerPixelIn ) - -{ - static int nTempCounter = 0; - char szFilename[128]; - -/* -------------------------------------------------------------------- */ -/* Initialize stuff. */ -/* -------------------------------------------------------------------- */ - nXSize = nXSizeIn; - nYSize = nYSizeIn; - nBlockXSize = nBlockXSizeIn; - nBlockYSize = nBlockYSizeIn; - nBitsPerPixel = nBitsPerPixelIn; - -/* -------------------------------------------------------------------- */ -/* Create the raw temporary file, trying to verify first that */ -/* it doesn't already exist. */ -/* -------------------------------------------------------------------- */ - fp = NULL; - while( fp == NULL ) - { - sprintf( szFilename, "temp_%d.rbi", nTempCounter++ ); - fp = fopen( szFilename, "r" ); - if( fp != NULL ) - fclose( fp ); - else - fp = fopen( szFilename, "w+b" ); - } - - pszFilename = strdup( szFilename ); - nCurFileSize = 0; - -/* -------------------------------------------------------------------- */ -/* Initialize other stuff. */ -/* -------------------------------------------------------------------- */ - nBlocksPerRow = (nXSize + nBlockXSize - 1) / nBlockXSize; - nBlocksPerColumn = (nYSize + nBlockYSize - 1) / nBlockYSize; - nBytesPerBlock = (nBlockXSize*nBlockYSize*nBitsPerPixel + 7) / 8; - - nBlocks = nBlocksPerRow * nBlocksPerColumn; - nBlocksInCache = 0; - nMaxBlocksInCache = MIN(nBlocks, 2*nBlocksPerRow); - - papoBlocks = (RawBlock **) calloc(sizeof(RawBlock*),nBlocks); - - poLRUHead = NULL; - poLRUTail = NULL; -} - -/************************************************************************/ -/* ~RawBlockedImage() */ -/************************************************************************/ - -RawBlockedImage::~RawBlockedImage() - -{ - int i; - - for( i = 0; i < nBlocks; i++ ) - { - if( papoBlocks[i] != NULL ) - { - if( papoBlocks[i]->pabyData != NULL ) - free( papoBlocks[i]->pabyData ); - - delete papoBlocks[i]; - } - } - - if( papoBlocks != NULL) - free( papoBlocks ); - - fclose( fp ); - - unlink( pszFilename ); /* wrap this? */ - - free( pszFilename ); -} - -/************************************************************************/ -/* InsertInLRUList() */ -/* */ -/* Insert this link at the beginning of the LRU list. First */ -/* removed from it's current position if it is in the list. */ -/************************************************************************/ - -void RawBlockedImage::InsertInLRUList( RawBlock * poBlock ) - -{ -/* -------------------------------------------------------------------- */ -/* Remove from list, if it is currently in it. */ -/* -------------------------------------------------------------------- */ - if( poBlock->poPrevLRU != NULL || poLRUHead == poBlock ) - RemoveFromLRUList( poBlock ); - -/* -------------------------------------------------------------------- */ -/* Add at the head. */ -/* -------------------------------------------------------------------- */ - if( poLRUHead != NULL ) - { - poLRUHead->poPrevLRU = poBlock; - } - - poBlock->poNextLRU = poLRUHead; - poLRUHead = poBlock; - - if( poLRUTail == NULL ) - poLRUTail = poBlock; -} - -/************************************************************************/ -/* RemoveFromLRUList() */ -/* */ -/* Remove this block from the LRU list, if present. */ -/************************************************************************/ - -void RawBlockedImage::RemoveFromLRUList( RawBlock * poBlock ) - -{ -/* -------------------------------------------------------------------- */ -/* Is it even in the list? */ -/* -------------------------------------------------------------------- */ - if( poBlock->poPrevLRU == NULL && poLRUHead != poBlock ) - return; - -/* -------------------------------------------------------------------- */ -/* Fix the link before this in the list (or head pointer). */ -/* -------------------------------------------------------------------- */ - if( poBlock->poPrevLRU == NULL ) - { - poLRUHead = poBlock->poNextLRU; - } - else - { - poBlock->poPrevLRU->poNextLRU = poBlock->poNextLRU; - } - -/* -------------------------------------------------------------------- */ -/* Fix the link after this one, or the tail pointer. */ -/* -------------------------------------------------------------------- */ - if( poBlock->poNextLRU == NULL ) - { - poLRUTail = poBlock->poPrevLRU; - } - else - { - poBlock->poNextLRU->poPrevLRU = poBlock->poPrevLRU; - } - -/* -------------------------------------------------------------------- */ -/* Update this link to indicate it isn't in the list now. */ -/* -------------------------------------------------------------------- */ - poBlock->poPrevLRU = poBlock->poNextLRU = NULL; -} - - -/************************************************************************/ -/* FlushBlock() */ -/************************************************************************/ - -void RawBlockedImage::FlushBlock( RawBlock * poBlock ) - -{ -/* -------------------------------------------------------------------- */ -/* If we aren't given a particular block to flush, then select */ -/* the lest recently used one from the LRU list. */ -/* -------------------------------------------------------------------- */ - if( poBlock == NULL ) - { - if( poLRUTail == NULL ) - return; - - poBlock = poLRUTail; - } - -/* -------------------------------------------------------------------- */ -/* Remove from the LRU list. */ -/* -------------------------------------------------------------------- */ - RemoveFromLRUList( poBlock ); - -/* -------------------------------------------------------------------- */ -/* If the block has no data, then it doesn't really need to be */ -/* flushed. */ -/* -------------------------------------------------------------------- */ - if( poBlock->pabyData == NULL ) - return; - -/* -------------------------------------------------------------------- */ -/* Is this block dirty? If so we will have to try and save it. */ -/* -------------------------------------------------------------------- */ - if( poBlock->nDirty ) - { - if( poBlock->nPositionInFile == -1 ) - poBlock->nPositionInFile = nCurFileSize; - - nCurFileSize += nBytesPerBlock; - if( fseek( fp, poBlock->nPositionInFile, SEEK_SET ) != 0 ) - { - fprintf( stderr, - "Seek to %d in overview spill file %s failed.\n", - poBlock->nPositionInFile, pszFilename ); - exit( 1 ); - } - - if( fwrite( poBlock->pabyData, 1, nBytesPerBlock, fp ) - != (size_t) nBytesPerBlock ) - { - fprintf( stderr, - "Write of %d bytes at %d in overview spill file %s.\n" - "Is the disk full?\n", - nBytesPerBlock, poBlock->nPositionInFile, pszFilename ); - exit( 1 ); - } - - poBlock->nDirty = FALSE; - } - -/* -------------------------------------------------------------------- */ -/* Free the data block, and decrement used count. */ -/* -------------------------------------------------------------------- */ - nBlocksInCache--; - if( poBlock->pabyData != NULL ) - free( poBlock->pabyData ); - poBlock->pabyData = NULL; -} - - -/************************************************************************/ -/* GetRawBlock() */ -/************************************************************************/ - -RawBlock *RawBlockedImage::GetRawBlock( int nXOff, int nYOff ) - -{ - int nBlock = nXOff + nYOff * nBlocksPerRow; - RawBlock *poBlock; - - assert( nBlock >= 0 && nBlock < nBlocks ); - -/* -------------------------------------------------------------------- */ -/* Is this the first request? If so, create the block object, */ -/* initialize the data memory, and return it. */ -/* -------------------------------------------------------------------- */ - poBlock = papoBlocks[nBlock]; - if( poBlock == NULL ) - { - poBlock = papoBlocks[nBlock] = new RawBlock; - poBlock->nDirty = FALSE; - poBlock->poPrevLRU = poBlock->poNextLRU = NULL; - poBlock->nPositionInFile = -1; - poBlock->pabyData = (unsigned char *) calloc(1,nBytesPerBlock); - nBlocksInCache++; - - if( poBlock->pabyData == NULL ) - { - fprintf( stderr, - "RawBlockedImage::GetRawBlock() - out of memory\n" ); - exit( 1 ); - } - } - -/* -------------------------------------------------------------------- */ -/* Does this block need to be read off disk? */ -/* -------------------------------------------------------------------- */ - else if( poBlock->nPositionInFile >= 0 && poBlock->pabyData == NULL ) - { - nBlocksInCache++; - poBlock->pabyData = (unsigned char *) calloc(1,nBytesPerBlock); - fseek( fp, poBlock->nPositionInFile, SEEK_SET ); - fread( poBlock->pabyData, nBytesPerBlock, 1, fp ); - } - -/* -------------------------------------------------------------------- */ -/* Does the data need to be allocated? */ -/* -------------------------------------------------------------------- */ - else if( poBlock->pabyData == NULL ) - { - poBlock->pabyData = (unsigned char *) calloc(1,nBytesPerBlock); - if( poBlock->pabyData == NULL ) - { - fprintf( stderr, - "RawBlockedImage::GetRawBlock() - out of memory\n" ); - exit( 1 ); - } - } - -/* -------------------------------------------------------------------- */ -/* Push on the LRU stack, or pop it back to the top. */ -/* -------------------------------------------------------------------- */ - InsertInLRUList( poBlock ); - -/* -------------------------------------------------------------------- */ -/* If we have exceeded our self imposed caching limit, flush */ -/* one block. */ -/* -------------------------------------------------------------------- */ - if( nBlocksInCache > nMaxBlocksInCache ) - FlushBlock( NULL ); - - return( poBlock ); -} - -/************************************************************************/ -/* GetTile() */ -/************************************************************************/ - -unsigned char *RawBlockedImage::GetTile( int nXOff, int nYOff ) - -{ - RawBlock *poBlock; - - poBlock = GetRawBlock(nXOff,nYOff); - if( poBlock != NULL ) - return poBlock->pabyData; - else - return NULL; -} - -/************************************************************************/ -/* GetTileForUpdate() */ -/************************************************************************/ - -unsigned char *RawBlockedImage::GetTileForUpdate( int nXOff, int nYOff ) - -{ - RawBlock *poBlock; - - poBlock = GetRawBlock(nXOff,nYOff); - if( poBlock != NULL ) - { - poBlock->nDirty = TRUE; - - return poBlock->pabyData; - } - else - return NULL; -} diff --git a/contrib/addtiffo/rawblockedimage.h b/contrib/addtiffo/rawblockedimage.h deleted file mode 100644 index 7696be32..00000000 --- a/contrib/addtiffo/rawblockedimage.h +++ /dev/null @@ -1,108 +0,0 @@ -/****************************************************************************** - * $Id: rawblockedimage.h,v 1.1 1999-08-17 01:47:59 warmerda Exp $ - * - * Project: GeoTIFF Overview Builder - * Purpose: Implement the RawBlockedImage class, for holding ``under - * construction'' overviews in a temporary file. - * Author: Frank Warmerdam, warmerda@home.com - * - ****************************************************************************** - * Copyright (c) 1999, Frank Warmerdam - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log: - */ - -#ifndef RAWBLOCKEDIMAGE_H_INCLUDED -#define RAWBLOCKEDIMAGE_H_INCLUDED - -#include - -/************************************************************************/ -/* ==================================================================== */ -/* RawBlockedImage */ -/* */ -/* The RawBlockedImage class is used to maintain a single band */ -/* raster tiled image on disk. */ -/* ==================================================================== */ -/************************************************************************/ - -class RawBlock -{ -public: - RawBlock *poNextLRU; - RawBlock *poPrevLRU; - - int nDirty; - int nPositionInFile; - - unsigned char *pabyData; -}; - -class RawBlockedImage -{ - int nXSize; - int nYSize; - - int nBlockXSize; - int nBlockYSize; - int nBitsPerPixel; - int nBytesPerBlock; - - int nBlocksPerRow; - int nBlocksPerColumn; - - int nBlocks; - RawBlock **papoBlocks; - - int nBlocksInCache; - int nMaxBlocksInCache; - - FILE *fp; - int nCurFileSize; - char *pszFilename; - - RawBlock *GetRawBlock( int, int ); - void FlushBlock( RawBlock * ); - void InsertInLRUList( RawBlock * ); - void RemoveFromLRUList( RawBlock * ); - - RawBlock *poLRUHead; - RawBlock *poLRUTail; - -public: - RawBlockedImage( int nXSize, int nYSize, - int nBlockXSize, int nBlockYSize, - int nBitsPerPixel ); - - ~RawBlockedImage(); - - unsigned char*GetTile( int, int ); - unsigned char*GetTileForUpdate( int, int ); - - int GetBlockXSize() { return nBlockXSize; } - int GetBlockYSize() { return nBlockYSize; } - int GetXSize() { return nXSize; } - int GetYSize() { return nYSize; } - int GetBitsPerPixel() { return nBitsPerPixel; } -}; - -#endif /* ndef RAWBLOCKEDIMAGE_H_INCLUDED */ diff --git a/contrib/addtiffo/tif_overview.cpp b/contrib/addtiffo/tif_overview.cpp deleted file mode 100644 index ebf1c9b3..00000000 --- a/contrib/addtiffo/tif_overview.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/****************************************************************************** - * $Id: tif_overview.cpp,v 1.1 1999-08-17 01:47:59 warmerda Exp $ - * - * Project: TIFF Overview Builder - * Purpose: Library function for building overviews in a TIFF file. - * Author: Frank Warmerdam, warmerda@home.com - * - * Notes: - * o This module uses the RawBlockedImage class to hold the overviews as - * they are being built since we can't easily be reading from one directory - * in a TIFF file, and writing to a bunch of others. - * - * o RawBlockedImage will create temporary files in the current directory - * to cache the overviews so it doesn't have to hold them all in memory. - * If the application crashes these will not be deleted (*.rbi). - * - * o Currently only images with bits_per_sample of a multiple of eight - * will work. - * - * o The downsampler currently just takes the top left pixel from the - * source rectangle. Eventually sampling options of averaging, mode, and - * ``center pixel'' should be offered. - * - * o The code will attempt to use the same kind of compression, - * photometric interpretation, and organization as the source image, but - * it doesn't copy geotiff tags to the reduced resolution images. - * - * o Reduced resolution overviews for multi-sample files will currently - * always be generated as PLANARCONFIG_SEPARATE. This could be fixed - * reasonable easily if needed to improve compatibility with other - * packages. Many don't properly support PLANARCONFIG_SEPARATE. - * - ****************************************************************************** - * Copyright (c) 1999, Frank Warmerdam - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************** - * - * $Log: tif_overview.cpp,v $ - * Revision 1.1 1999-08-17 01:47:59 warmerda - * New - * - * Revision 1.7 1999/03/12 17:47:26 warmerda - * made independent of CPL - * - * Revision 1.6 1999/02/24 16:24:00 warmerda - * Don't include cpl_string.h - * - * Revision 1.5 1999/02/11 22:27:12 warmerda - * Added multi-sample support - * - * Revision 1.4 1999/02/11 19:23:39 warmerda - * Only fix on multiples of 16 in block size if it is a tiled file. - * - * Revision 1.3 1999/02/11 19:21:14 warmerda - * Limit tile sizes to multiples of 16 - * - * Revision 1.2 1999/02/11 18:37:43 warmerda - * Removed debugging malloc stuff. - * - * Revision 1.1 1999/02/11 18:12:30 warmerda - * New - * - */ - -#include -#include -#include - -#include "tiffio.h" -#include "rawblockedimage.h" - -#ifndef FALSE -# define FALSE 0 -# define TRUE 1 -#endif - -#ifndef MAX -# define MIN(a,b) ((ab) ? a : b) -#endif - -extern "C" { - void TIFFBuildOverviews( const char *, int, int *, int ); -} - -/************************************************************************/ -/* TIFF_WriteOverview() */ -/************************************************************************/ - -static -void TIFF_WriteOverview( TIFF *hTIFF, int nSamples, RawBlockedImage **papoRBI, - int bTiled, int nCompressFlag, int nPhotometric, - unsigned short *panRed, - unsigned short *panGreen, - unsigned short *panBlue, - int bUseSubIFDs ) - -{ - int iSample; - RawBlockedImage *poRBI = papoRBI[0]; - -/* -------------------------------------------------------------------- */ -/* Setup TIFF fields. */ -/* -------------------------------------------------------------------- */ - TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, poRBI->GetXSize() ); - TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, poRBI->GetYSize() ); - TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, - PLANARCONFIG_SEPARATE ); - - TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, poRBI->GetBitsPerPixel() ); - TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, nSamples ); - TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, nCompressFlag ); - TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, nPhotometric ); - - if( bTiled ) - { - TIFFSetField( hTIFF, TIFFTAG_TILEWIDTH, poRBI->GetBlockXSize() ); - TIFFSetField( hTIFF, TIFFTAG_TILELENGTH, poRBI->GetBlockYSize() ); - } - else - TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, poRBI->GetBlockYSize() ); - - TIFFSetField( hTIFF, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE ); - -/* -------------------------------------------------------------------- */ -/* Write color table if one is present. */ -/* -------------------------------------------------------------------- */ - if( panRed != NULL ) - { - TIFFSetField( hTIFF, TIFFTAG_COLORMAP, panRed, panGreen, panBlue ); - } - -/* -------------------------------------------------------------------- */ -/* Write blocks to TIFF file. */ -/* -------------------------------------------------------------------- */ - for( iSample = 0; iSample < nSamples; iSample++ ) - { - int iTileX, iTileY; - - poRBI = papoRBI[iSample]; - - for( iTileY = 0; - iTileY*poRBI->GetBlockYSize() < poRBI->GetYSize(); - iTileY++ ) - { - for( iTileX = 0; - iTileX*poRBI->GetBlockXSize() < poRBI->GetXSize(); - iTileX++ ) - { - unsigned char *pabyData = poRBI->GetTile( iTileX, iTileY ); - int nTileID; - - if( bTiled ) - { - nTileID = - TIFFComputeTile(hTIFF, - iTileX * poRBI->GetBlockXSize(), - iTileY * poRBI->GetBlockYSize(), - 0, iSample ); - TIFFWriteEncodedTile( hTIFF, nTileID, - pabyData, TIFFTileSize(hTIFF) ); - } - else - { - nTileID = - TIFFComputeStrip(hTIFF, iTileY*poRBI->GetBlockYSize(), - iSample); - - TIFFWriteEncodedStrip( hTIFF, nTileID, - pabyData, TIFFStripSize( hTIFF ) ); - } - } - } - } - - TIFFWriteDirectory( hTIFF ); -} - -/************************************************************************/ -/* TIFF_DownSample() */ -/* */ -/* Down sample a tile of full res data into a window of a tile */ -/* of downsampled data. */ -/************************************************************************/ - -static -void TIFF_DownSample( unsigned char *pabySrcTile, - int nBlockXSize, int nBlockYSize, - int nPixelSkewBits, int nBitsPerPixel, - unsigned char * pabyOTile, - int nOBlockXSize, int nOBlockYSize, - int nTXOff, int nTYOff, int nOMult ) - -{ - int i, j, k, nPixelBytes = (nBitsPerPixel) / 8; - int nPixelGroupBytes = (nBitsPerPixel+nPixelSkewBits)/8; - unsigned char *pabySrc, *pabyDst; - - assert( nBitsPerPixel >= 8 ); - -/* -------------------------------------------------------------------- */ -/* Handle case of one or more whole bytes per sample. */ -/* -------------------------------------------------------------------- */ - for( j = 0; j*nOMult < nBlockYSize; j++ ) - { - if( j + nTYOff >= nOBlockYSize ) - break; - - pabySrc = pabySrcTile + j*nOMult*nBlockXSize * nPixelGroupBytes; - pabyDst = pabyOTile - + ((j+nTYOff)*nOBlockXSize + nTXOff) * nPixelBytes; - - for( i = 0; i*nOMult < nBlockXSize; i++ ) - { - if( i + nTXOff >= nOBlockXSize ) - break; - - /* - * For now use simple subsampling, from the top left corner - * of the source block of pixels. - */ - - for( k = 0; k < nPixelBytes; k++ ) - { - *(pabyDst++) = pabySrc[k]; - } - - pabySrc += nOMult * nPixelGroupBytes; - } - } -} - -/************************************************************************/ -/* TIFF_ProcessFullResBlock() */ -/* */ -/* Process one block of full res data, downsampling into each */ -/* of the overviews. */ -/************************************************************************/ - -void TIFF_ProcessFullResBlock( TIFF *hTIFF, int nPlanarConfig, - int nOverviews, int * panOvList, - int nBitsPerPixel, - int nSamples, RawBlockedImage ** papoRawBIs, - int nSXOff, int nSYOff, - unsigned char *pabySrcTile, - int nBlockXSize, int nBlockYSize ) - -{ - int iOverview, iSample; - - for( iSample = 0; iSample < nSamples; iSample++ ) - { - /* - * We have to read a tile/strip for each sample for - * PLANARCONFIG_SEPARATE. Otherwise, we just read all the samples - * at once when handling the first sample. - */ - if( nPlanarConfig == PLANARCONFIG_SEPARATE || iSample == 0 ) - { - if( TIFFIsTiled(hTIFF) ) - { - TIFFReadEncodedTile( hTIFF, - TIFFComputeTile(hTIFF, nSXOff, nSYOff, - 0, iSample ), - pabySrcTile, - TIFFTileSize(hTIFF)); - } - else - { - TIFFReadEncodedStrip( hTIFF, - TIFFComputeStrip(hTIFF, nSYOff, iSample), - pabySrcTile, - TIFFStripSize(hTIFF) ); - } - } - - /* - * Loop over destination overview layers - */ - for( iOverview = 0; iOverview < nOverviews; iOverview++ ) - { - RawBlockedImage *poRBI = papoRawBIs[iOverview*nSamples + iSample]; - unsigned char *pabyOTile; - int nTXOff, nTYOff, nOXOff, nOYOff, nOMult; - int nOBlockXSize = poRBI->GetBlockXSize(); - int nOBlockYSize = poRBI->GetBlockYSize(); - int nSkewBits, nSampleByteOffset; - - /* - * Fetch the destination overview tile - */ - nOMult = panOvList[iOverview]; - nOXOff = (nSXOff/nOMult) / nOBlockXSize; - nOYOff = (nSYOff/nOMult) / nOBlockYSize; - pabyOTile = poRBI->GetTileForUpdate( nOXOff, nOYOff ); - - /* - * Establish the offset into this tile at which we should - * start placing data. - */ - nTXOff = (nSXOff - nOXOff*nOMult*nOBlockXSize) / nOMult; - nTYOff = (nSYOff - nOYOff*nOMult*nOBlockYSize) / nOMult; - - /* - * Figure out the skew (extra space between ``our samples'') and - * the byte offset to the first sample. - */ - assert( (nBitsPerPixel % 8) == 0 ); - if( nPlanarConfig == PLANARCONFIG_SEPARATE ) - { - nSkewBits = 0; - nSampleByteOffset = 0; - } - else - { - nSkewBits = nBitsPerPixel * (nSamples-1); - nSampleByteOffset = (nBitsPerPixel/8) * iSample; - } - - /* - * Perform the downsampling. - */ -#ifdef DBMALLOC - malloc_chain_check( 1 ); -#endif - TIFF_DownSample( pabySrcTile + nSampleByteOffset, - nBlockXSize, nBlockYSize, - nSkewBits, nBitsPerPixel, pabyOTile, - poRBI->GetBlockXSize(), - poRBI->GetBlockYSize(), - nTXOff, nTYOff, - nOMult ); -#ifdef DBMALLOC - malloc_chain_check( 1 ); -#endif - } - } -} - -/************************************************************************/ -/* TIFF_BuildOverviews() */ -/* */ -/* Build the requested list of overviews. Overviews are */ -/* maintained in a bunch of temporary files and then these are */ -/* written back to the TIFF file. Only one pass through the */ -/* source TIFF file is made for any number of output */ -/* overviews. */ -/************************************************************************/ - -void TIFFBuildOverviews( const char * pszTIFFFilename, - int nOverviews, int * panOvList, - int bUseSubIFDs ) - -{ - RawBlockedImage **papoRawBIs; - uint32 nXSize, nYSize, nBlockXSize, nBlockYSize; - uint16 nBitsPerPixel, nPhotometric, nCompressFlag, nSamples, - nPlanarConfig; - int bTiled, nSXOff, nSYOff, i, iSample; - unsigned char *pabySrcTile; - TIFF *hTIFF; - uint16 *panRedMap, *panGreenMap, *panBlueMap; - -/* -------------------------------------------------------------------- */ -/* Get the base raster size. */ -/* -------------------------------------------------------------------- */ - hTIFF = TIFFOpen( pszTIFFFilename, "r" ); - if( hTIFF == NULL ) - { - fprintf( stderr, "TIFFOpen(%s) failed.\n", pszTIFFFilename ); - exit( 1 ); - } - - TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &nXSize ); - TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &nYSize ); - - TIFFGetField( hTIFF, TIFFTAG_BITSPERSAMPLE, &nBitsPerPixel ); - TIFFGetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, &nSamples ); - TIFFGetField( hTIFF, TIFFTAG_PLANARCONFIG, &nPlanarConfig ); - - TIFFGetField( hTIFF, TIFFTAG_PHOTOMETRIC, &nPhotometric ); - TIFFGetField( hTIFF, TIFFTAG_COMPRESSION, &nCompressFlag ); - - if( nBitsPerPixel < 8 ) - { - TIFFError( "TIFFBuildOverviews", - "File `%s' has samples of %d bits per sample. Sample\n" - "sizes of less than 8 bits per sample are not supported.\n", - pszTIFFFilename, nBitsPerPixel ); - return; - } - -/* -------------------------------------------------------------------- */ -/* Get the base raster block size. */ -/* -------------------------------------------------------------------- */ - if( TIFFGetField( hTIFF, TIFFTAG_ROWSPERSTRIP, &(nBlockYSize) ) ) - { - nBlockXSize = nXSize; - bTiled = FALSE; - } - else - { - TIFFGetField( hTIFF, TIFFTAG_TILEWIDTH, &nBlockXSize ); - TIFFGetField( hTIFF, TIFFTAG_TILELENGTH, &nBlockYSize ); - bTiled = TRUE; - } - -/* -------------------------------------------------------------------- */ -/* Capture the pallette if there is one. */ -/* -------------------------------------------------------------------- */ - if( TIFFGetField( hTIFF, TIFFTAG_COLORMAP, - &panRedMap, &panGreenMap, &panBlueMap ) ) - { - uint16 *panRed2, *panGreen2, *panBlue2; - - panRed2 = (uint16 *) calloc(2,256); - panGreen2 = (uint16 *) calloc(2,256); - panBlue2 = (uint16 *) calloc(2,256); - - memcpy( panRed2, panRedMap, 512 ); - memcpy( panGreen2, panGreenMap, 512 ); - memcpy( panBlue2, panBlueMap, 512 ); - - panRedMap = panRed2; - panGreenMap = panGreen2; - panBlueMap = panBlue2; - } - else - { - panRedMap = panGreenMap = panBlueMap = NULL; - } - -/* -------------------------------------------------------------------- */ -/* Initialize the overview raw layers */ -/* -------------------------------------------------------------------- */ - papoRawBIs = (RawBlockedImage **) - calloc(nOverviews*nSamples,sizeof(void*)); - - for( i = 0; i < nOverviews; i++ ) - { - int nOXSize, nOYSize, nOBlockXSize, nOBlockYSize; - - nOXSize = (nXSize + panOvList[i] - 1) / panOvList[i]; - nOYSize = (nYSize + panOvList[i] - 1) / panOvList[i]; - - nOBlockXSize = MIN((int)nBlockXSize,nOXSize); - nOBlockYSize = MIN((int)nBlockYSize,nOYSize); - - if( bTiled ) - { - if( (nOBlockXSize % 16) != 0 ) - nOBlockXSize = nOBlockXSize + 16 - (nOBlockXSize % 16); - - if( (nOBlockYSize % 16) != 0 ) - nOBlockYSize = nOBlockYSize + 16 - (nOBlockYSize % 16); - } - - for( iSample = 0; iSample < nSamples; iSample++ ) - { - papoRawBIs[i*nSamples + iSample] = - new RawBlockedImage( nOXSize, nOYSize, - nOBlockXSize, nOBlockYSize, - nBitsPerPixel ); - } - } - -/* -------------------------------------------------------------------- */ -/* Allocate a buffer to hold a source block. */ -/* -------------------------------------------------------------------- */ - if( bTiled ) - pabySrcTile = (unsigned char *) malloc(TIFFTileSize(hTIFF)); - else - pabySrcTile = (unsigned char *) malloc(TIFFStripSize(hTIFF)); - -/* -------------------------------------------------------------------- */ -/* Loop over the source raster, applying data to the */ -/* destination raster. */ -/* -------------------------------------------------------------------- */ - for( nSYOff = 0; nSYOff < (int) nYSize; nSYOff += nBlockYSize ) - { - for( nSXOff = 0; nSXOff < (int) nXSize; nSXOff += nBlockXSize ) - { - /* - * Read and resample into the various overview images. - */ - - TIFF_ProcessFullResBlock( hTIFF, nPlanarConfig, - nOverviews, panOvList, - nBitsPerPixel, nSamples, papoRawBIs, - nSXOff, nSYOff, pabySrcTile, - nBlockXSize, nBlockYSize ); - } - } - - free( pabySrcTile ); - - TIFFClose( hTIFF ); - -/* ==================================================================== */ -/* We now have the overview rasters built, and held as */ -/* RawBlockedImage's. Now we need to write them to new TIFF */ -/* layers. */ -/* ==================================================================== */ - hTIFF = TIFFOpen( pszTIFFFilename, "a" ); - if( hTIFF == NULL ) - { - fprintf( stderr, - "TIFFOpen(%s,\"a\") failed. No overviews written.\n" - "Do you have write permissions on that file?\n", - pszTIFFFilename ); - } - else - { - for( i = 0; i < nOverviews; i++ ) - { - TIFF_WriteOverview( hTIFF, nSamples, papoRawBIs + i*nSamples, - bTiled, nCompressFlag, nPhotometric, - panRedMap, panGreenMap, panBlueMap, - bUseSubIFDs ); - } - - TIFFClose( hTIFF ); - } - -/* -------------------------------------------------------------------- */ -/* Cleanup the rawblockedimage files. */ -/* -------------------------------------------------------------------- */ - for( i = 0; i < nOverviews*nSamples; i++ ) - { - delete papoRawBIs[i]; - } - - if( papoRawBIs != NULL ) - free( papoRawBIs ); - - if( panRedMap != NULL ) - { - free( panRedMap ); - free( panGreenMap ); - free( panBlueMap ); - } -}