⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tif_ovrcache.c

📁 TIFF文件格式读取及生成的源代码
💻 C
字号:
/****************************************************************************** * $Id: tif_ovrcache.c,v 1.4 2005/06/07 14:26:04 dron Exp $ * * Project:  TIFF Overview Builder * Purpose:  Library functions to maintain two rows of tiles or two strips *           of data for output overviews as an output cache.  * Author:   Frank Warmerdam, warmerda@home.com * ****************************************************************************** * Copyright (c) 2000, 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. ****************************************************************************** */#include "tiffiop.h"#include "tif_ovrcache.h"#include <assert.h>/************************************************************************//*                         TIFFCreateOvrCache()                         *//*                                                                      *//*      Create an overview cache to hold two rows of blocks from an     *//*      existing TIFF directory.                                        *//************************************************************************/TIFFOvrCache *TIFFCreateOvrCache( TIFF *hTIFF, int nDirOffset ){    TIFFOvrCache	*psCache;    uint32		nBaseDirOffset;    psCache = (TIFFOvrCache *) _TIFFmalloc(sizeof(TIFFOvrCache));    psCache->nDirOffset = nDirOffset;    psCache->hTIFF = hTIFF;    /* -------------------------------------------------------------------- *//*      Get definition of this raster from the TIFF file itself.        *//* -------------------------------------------------------------------- */    nBaseDirOffset = TIFFCurrentDirOffset( psCache->hTIFF );    TIFFSetSubDirectory( hTIFF, nDirOffset );        TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &(psCache->nXSize) );    TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &(psCache->nYSize) );    TIFFGetField( hTIFF, TIFFTAG_BITSPERSAMPLE, &(psCache->nBitsPerPixel) );    TIFFGetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, &(psCache->nSamples) );    TIFFGetField( hTIFF, TIFFTAG_PLANARCONFIG, &(psCache->nPlanarConfig) );    if( !TIFFIsTiled( hTIFF ) )    {        TIFFGetField( hTIFF, TIFFTAG_ROWSPERSTRIP, &(psCache->nBlockYSize) );        psCache->nBlockXSize = psCache->nXSize;        psCache->nBytesPerBlock = TIFFStripSize(hTIFF);        psCache->bTiled = FALSE;    }    else    {        TIFFGetField( hTIFF, TIFFTAG_TILEWIDTH, &(psCache->nBlockXSize) );        TIFFGetField( hTIFF, TIFFTAG_TILELENGTH, &(psCache->nBlockYSize) );        psCache->nBytesPerBlock = TIFFTileSize(hTIFF);        psCache->bTiled = TRUE;    }/* -------------------------------------------------------------------- *//*      Compute some values from this.                                  *//* -------------------------------------------------------------------- */    psCache->nBlocksPerRow = (psCache->nXSize + psCache->nBlockXSize - 1)        		/ psCache->nBlockXSize;    psCache->nBlocksPerColumn = (psCache->nYSize + psCache->nBlockYSize - 1)        		/ psCache->nBlockYSize;    if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)        psCache->nBytesPerRow = psCache->nBytesPerBlock            * psCache->nBlocksPerRow * psCache->nSamples;    else        psCache->nBytesPerRow =            psCache->nBytesPerBlock * psCache->nBlocksPerRow;/* -------------------------------------------------------------------- *//*      Allocate and initialize the data buffers.                       *//* -------------------------------------------------------------------- */    psCache->pabyRow1Blocks =        (unsigned char *) _TIFFmalloc(psCache->nBytesPerRow);    psCache->pabyRow2Blocks =        (unsigned char *) _TIFFmalloc(psCache->nBytesPerRow);    if( psCache->pabyRow1Blocks == NULL        || psCache->pabyRow2Blocks == NULL )    {        TIFFError( hTIFF->tif_name,                   "Can't allocate memory for overview cache." );        return NULL;    }    _TIFFmemset( psCache->pabyRow1Blocks, 0, psCache->nBytesPerRow );    _TIFFmemset( psCache->pabyRow2Blocks, 0, psCache->nBytesPerRow );    psCache->nBlockOffset = 0;    TIFFSetSubDirectory( psCache->hTIFF, nBaseDirOffset );        return psCache;}/************************************************************************//*                          TIFFWriteOvrRow()                           *//*                                                                      *//*      Write one entire row of blocks (row 1) to the tiff file, and    *//*      then rotate the block buffers, essentially moving things        *//*      down by one block.                                              *//************************************************************************/static void TIFFWriteOvrRow( TIFFOvrCache * psCache ){    int		nRet, iTileX, iTileY = psCache->nBlockOffset;    unsigned char *pabyData;    uint32	nBaseDirOffset;    /* -------------------------------------------------------------------- *//*	If the output cache is multi-byte per sample, and the file	*//*	being written to is of a different byte order than the current	*//*	platform, we will need to byte swap the data. 			*//* -------------------------------------------------------------------- */    if( TIFFIsByteSwapped(psCache->hTIFF) )    {        if( psCache->nBitsPerPixel == 16 )            TIFFSwabArrayOfShort( (uint16 *) psCache->pabyRow1Blocks,                      (psCache->nBytesPerBlock * psCache->nSamples) / 2 );        else if( psCache->nBitsPerPixel == 32 )            TIFFSwabArrayOfLong( (uint32 *) psCache->pabyRow1Blocks,                         (psCache->nBytesPerBlock * psCache->nSamples) / 4 );        else if( psCache->nBitsPerPixel == 64 )            TIFFSwabArrayOfDouble( (double *) psCache->pabyRow1Blocks,                         (psCache->nBytesPerBlock * psCache->nSamples) / 8 );    }/* -------------------------------------------------------------------- *//*      Record original directory position, so we can restore it at     *//*      end.                                                            *//* -------------------------------------------------------------------- */    nBaseDirOffset = TIFFCurrentDirOffset( psCache->hTIFF );    nRet = TIFFSetSubDirectory( psCache->hTIFF, psCache->nDirOffset );    assert( nRet == 1 );/* -------------------------------------------------------------------- *//*      Write blocks to TIFF file.                                      *//* -------------------------------------------------------------------- */    for( iTileX = 0; iTileX < psCache->nBlocksPerRow; iTileX++ )    {        int nTileID;        if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)        {            int iSample;            for( iSample = 0; iSample < psCache->nSamples; iSample++ )            {                pabyData = TIFFGetOvrBlock( psCache, iTileX, iTileY, iSample );                if( psCache->bTiled )                {                    nTileID =                        TIFFComputeTile( psCache->hTIFF,                                         iTileX * psCache->nBlockXSize,                                         iTileY * psCache->nBlockYSize,                                         0, (tsample_t) iSample );                    TIFFWriteEncodedTile( psCache->hTIFF, nTileID,                                           pabyData,                                          TIFFTileSize(psCache->hTIFF) );                }                else                {                    nTileID =                        TIFFComputeStrip( psCache->hTIFF,                                          iTileY * psCache->nBlockYSize,                                          (tsample_t) iSample );                    TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,                                           pabyData,                                           TIFFStripSize(psCache->hTIFF) );                }            }        }        else        {            pabyData = TIFFGetOvrBlock( psCache, iTileX, iTileY, 0 );            if( psCache->bTiled )            {                nTileID =                    TIFFComputeTile( psCache->hTIFF,                                     iTileX * psCache->nBlockXSize,                                     iTileY * psCache->nBlockYSize,                                     0, 0 );                TIFFWriteEncodedTile( psCache->hTIFF, nTileID,                                       pabyData,                                      TIFFTileSize(psCache->hTIFF) );            }            else            {                nTileID =                    TIFFComputeStrip( psCache->hTIFF,                                      iTileY * psCache->nBlockYSize,                                      0 );                TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,                                       pabyData,                                       TIFFStripSize(psCache->hTIFF) );            }        }    }/* -------------------------------------------------------------------- *//*      Rotate buffers.                                                 *//* -------------------------------------------------------------------- */    pabyData = psCache->pabyRow1Blocks;    psCache->pabyRow1Blocks = psCache->pabyRow2Blocks;    psCache->pabyRow2Blocks = pabyData;    _TIFFmemset( pabyData, 0, psCache->nBytesPerRow );    psCache->nBlockOffset++;/* -------------------------------------------------------------------- *//*      Restore access to original directory.                           *//* -------------------------------------------------------------------- */    TIFFFlush( psCache->hTIFF );        TIFFSetSubDirectory( psCache->hTIFF, nBaseDirOffset );}/************************************************************************//*                          TIFFGetOvrBlock()                           *//************************************************************************/unsigned char *TIFFGetOvrBlock( TIFFOvrCache *psCache, int iTileX, int iTileY,                                int iSample ){    int		nRowOffset;        if( iTileY > psCache->nBlockOffset + 1 )        TIFFWriteOvrRow( psCache );    assert( iTileX >= 0 && iTileX < psCache->nBlocksPerRow );    assert( iTileY >= 0 && iTileY < psCache->nBlocksPerColumn );    assert( iTileY >= psCache->nBlockOffset            && iTileY < psCache->nBlockOffset+2 );    assert( iSample >= 0 && iSample < psCache->nSamples );    if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)        nRowOffset = ((iTileX * psCache->nSamples) + iSample)            * psCache->nBytesPerBlock;    else        nRowOffset = iTileX * psCache->nBytesPerBlock +            (psCache->nBitsPerPixel + 7) / 8 * iSample;    if( iTileY == psCache->nBlockOffset )        return psCache->pabyRow1Blocks + nRowOffset;    else        return psCache->pabyRow2Blocks + nRowOffset;}/************************************************************************//*                        TIFFDestroyOvrCache()                         *//************************************************************************/void TIFFDestroyOvrCache( TIFFOvrCache * psCache ){    while( psCache->nBlockOffset < psCache->nBlocksPerColumn )        TIFFWriteOvrRow( psCache );    _TIFFfree( psCache->pabyRow1Blocks );    _TIFFfree( psCache->pabyRow2Blocks );    _TIFFfree( psCache );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -