Blame contrib/addtiffo/tif_overview.c

Packit 7838c8
/******************************************************************************
Packit 7838c8
 * tif_overview.c,v 1.9 2005/05/25 09:03:16 dron Exp
Packit 7838c8
 *
Packit 7838c8
 * Project:  TIFF Overview Builder
Packit 7838c8
 * Purpose:  Library function for building overviews in a TIFF file.
Packit 7838c8
 * Author:   Frank Warmerdam, warmerdam@pobox.com
Packit 7838c8
 *
Packit 7838c8
 * Notes:
Packit 7838c8
 *  o Currently only images with bits_per_sample of a multiple of eight
Packit 7838c8
 *    will work.
Packit 7838c8
 *
Packit 7838c8
 *  o The downsampler currently just takes the top left pixel from the
Packit 7838c8
 *    source rectangle.  Eventually sampling options of averaging, mode, and
Packit 7838c8
 *    ``center pixel'' should be offered.
Packit 7838c8
 *
Packit 7838c8
 *  o The code will attempt to use the same kind of compression,
Packit 7838c8
 *    photometric interpretation, and organization as the source image, but
Packit 7838c8
 *    it doesn't copy geotiff tags to the reduced resolution images.
Packit 7838c8
 *
Packit 7838c8
 *  o Reduced resolution overviews for multi-sample files will currently
Packit 7838c8
 *    always be generated as PLANARCONFIG_SEPARATE.  This could be fixed
Packit 7838c8
 *    reasonable easily if needed to improve compatibility with other
Packit 7838c8
 *    packages.  Many don't properly support PLANARCONFIG_SEPARATE. 
Packit 7838c8
 * 
Packit 7838c8
 ******************************************************************************
Packit 7838c8
 * Copyright (c) 1999, Frank Warmerdam
Packit 7838c8
 *
Packit 7838c8
 * Permission is hereby granted, free of charge, to any person obtaining a
Packit 7838c8
 * copy of this software and associated documentation files (the "Software"),
Packit 7838c8
 * to deal in the Software without restriction, including without limitation
Packit 7838c8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Packit 7838c8
 * and/or sell copies of the Software, and to permit persons to whom the
Packit 7838c8
 * Software is furnished to do so, subject to the following conditions:
Packit 7838c8
 *
Packit 7838c8
 * The above copyright notice and this permission notice shall be included
Packit 7838c8
 * in all copies or substantial portions of the Software.
Packit 7838c8
 *
Packit 7838c8
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Packit 7838c8
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit 7838c8
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Packit 7838c8
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit 7838c8
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Packit 7838c8
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Packit 7838c8
 * DEALINGS IN THE SOFTWARE.
Packit 7838c8
 ******************************************************************************
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
/* TODO: update notes in header above */
Packit 7838c8
Packit 7838c8
#include <stdio.h>
Packit 7838c8
#include <assert.h>
Packit 7838c8
#include <stdlib.h>
Packit 7838c8
#include <string.h>
Packit 7838c8
Packit 7838c8
#include "tiffio.h"
Packit 7838c8
#include "tif_ovrcache.h"
Packit 7838c8
Packit 7838c8
#ifndef FALSE
Packit 7838c8
#  define FALSE 0
Packit 7838c8
#  define TRUE 1
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
#ifndef MAX
Packit 7838c8
#  define MIN(a,b)      ((a
Packit 7838c8
#  define MAX(a,b)      ((a>b) ? a : b)
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
Packit 7838c8
                         int (*)(double,void*), void * );
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                         TIFF_WriteOverview()                         */
Packit 7838c8
/*                                                                      */
Packit 7838c8
/*      Create a new directory, without any image data for an overview. */
Packit 7838c8
/*      Returns offset of newly created overview directory, but the     */
Packit 7838c8
/*      current directory is reset to be the one in used when this      */
Packit 7838c8
/*      function is called.                                             */
Packit 7838c8
/************************************************************************/
Packit 7838c8
Packit 7838c8
uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
Packit 7838c8
                           int nBitsPerPixel, int nPlanarConfig, int nSamples, 
Packit 7838c8
                           int nBlockXSize, int nBlockYSize,
Packit 7838c8
                           int bTiled, int nCompressFlag, int nPhotometric,
Packit 7838c8
                           int nSampleFormat,
Packit 7838c8
                           unsigned short *panRed,
Packit 7838c8
                           unsigned short *panGreen,
Packit 7838c8
                           unsigned short *panBlue,
Packit 7838c8
                           int bUseSubIFDs,
Packit 7838c8
                           int nHorSubsampling, int nVerSubsampling )
Packit 7838c8
Packit 7838c8
{
Packit 7838c8
    toff_t	nBaseDirOffset;
Packit 7838c8
    toff_t	nOffset;
Packit 7838c8
Packit 7838c8
    (void) bUseSubIFDs;
Packit 7838c8
Packit 7838c8
    nBaseDirOffset = TIFFCurrentDirOffset( hTIFF );
Packit 7838c8
Packit 7838c8
    TIFFCreateDirectory( hTIFF );
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Setup TIFF fields.                                              */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, nXSize );
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, nYSize );
Packit 7838c8
    if( nSamples == 1 )
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
Packit 7838c8
    else
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, nPlanarConfig );
Packit 7838c8
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, nBitsPerPixel );
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, nSamples );
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, nCompressFlag );
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, nPhotometric );
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_SAMPLEFORMAT, nSampleFormat );
Packit 7838c8
Packit 7838c8
    if( bTiled )
Packit 7838c8
    {
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_TILEWIDTH, nBlockXSize );
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_TILELENGTH, nBlockYSize );
Packit 7838c8
    }
Packit 7838c8
    else
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, nBlockYSize );
Packit 7838c8
Packit 7838c8
    TIFFSetField( hTIFF, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE );
Packit 7838c8
Packit 7838c8
    if( nPhotometric == PHOTOMETRIC_YCBCR || nPhotometric == PHOTOMETRIC_ITULAB )
Packit 7838c8
    {
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_YCBCRSUBSAMPLING, nHorSubsampling, nVerSubsampling);
Packit 7838c8
        /* TODO: also write YCbCrPositioning and YCbCrCoefficients tag identical to source IFD */
Packit 7838c8
    }
Packit 7838c8
    /* TODO: add command-line parameter for selecting jpeg compression quality
Packit 7838c8
     * that gets ignored when compression isn't jpeg */
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*	Write color table if one is present.				*/
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    if( panRed != NULL )
Packit 7838c8
    {
Packit 7838c8
        TIFFSetField( hTIFF, TIFFTAG_COLORMAP, panRed, panGreen, panBlue );
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Write directory, and return byte offset.                        */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    if( TIFFWriteCheck( hTIFF, bTiled, "TIFFBuildOverviews" ) == 0 )
Packit 7838c8
        return 0;
Packit 7838c8
Packit 7838c8
    TIFFWriteDirectory( hTIFF );
Packit 7838c8
    TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) );
Packit 7838c8
Packit 7838c8
    nOffset = TIFFCurrentDirOffset( hTIFF );
Packit 7838c8
Packit 7838c8
    TIFFSetSubDirectory( hTIFF, nBaseDirOffset );
Packit 7838c8
Packit 7838c8
    return nOffset;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                       TIFF_GetSourceSamples()                        */
Packit 7838c8
/************************************************************************/
Packit 7838c8
Packit 7838c8
static void 
Packit 7838c8
TIFF_GetSourceSamples( double * padfSamples, unsigned char *pabySrc, 
Packit 7838c8
                       int nPixelBytes, int nSampleFormat, 
Packit 7838c8
                       uint32 nXSize, uint32 nYSize, 
Packit 7838c8
                       int nPixelOffset, int nLineOffset )
Packit 7838c8
{
Packit 7838c8
    uint32  iXOff, iYOff;
Packit 7838c8
    int     iSample;
Packit 7838c8
Packit 7838c8
    iSample = 0;
Packit 7838c8
Packit 7838c8
    for( iYOff = 0; iYOff < nYSize; iYOff++ )
Packit 7838c8
    {
Packit 7838c8
        for( iXOff = 0; iXOff < nXSize; iXOff++ )
Packit 7838c8
        {
Packit 7838c8
            unsigned char *pabyData;
Packit 7838c8
Packit 7838c8
            pabyData = pabySrc + iYOff * nLineOffset + iXOff * nPixelOffset;
Packit 7838c8
Packit 7838c8
            if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 1 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = *pabyData;
Packit 7838c8
            }
Packit 7838c8
            else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 2 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = ((uint16 *) pabyData)[0];
Packit 7838c8
            }
Packit 7838c8
            else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 4 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = ((uint32 *) pabyData)[0];
Packit 7838c8
            }
Packit 7838c8
            else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 2 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = ((int16 *) pabyData)[0];
Packit 7838c8
            }
Packit 7838c8
            else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 32 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = ((int32 *) pabyData)[0];
Packit 7838c8
            }
Packit 7838c8
            else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 4 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = ((float *) pabyData)[0];
Packit 7838c8
            }
Packit 7838c8
            else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 8 )
Packit 7838c8
            {
Packit 7838c8
                padfSamples[iSample++] = ((double *) pabyData)[0];
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
} 
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                           TIFF_SetSample()                           */
Packit 7838c8
/************************************************************************/
Packit 7838c8
Packit 7838c8
static void 
Packit 7838c8
TIFF_SetSample( unsigned char * pabyData, int nPixelBytes, int nSampleFormat, 
Packit 7838c8
                double dfValue )
Packit 7838c8
Packit 7838c8
{
Packit 7838c8
    if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 1 )
Packit 7838c8
    {
Packit 7838c8
        *pabyData = (unsigned char) MAX(0,MIN(255,dfValue));
Packit 7838c8
    }
Packit 7838c8
    else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 2 )
Packit 7838c8
    {
Packit 7838c8
        *((uint16 *)pabyData) = (uint16) MAX(0,MIN(65535,dfValue));
Packit 7838c8
    }
Packit 7838c8
    else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 4 )
Packit 7838c8
    {
Packit 7838c8
        *((uint32 *)pabyData) = (uint32) dfValue;
Packit 7838c8
    }
Packit 7838c8
    else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 2 )
Packit 7838c8
    {
Packit 7838c8
        *((int16 *)pabyData) = (int16) MAX(-32768,MIN(32767,dfValue));
Packit 7838c8
    }
Packit 7838c8
    else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 32 )
Packit 7838c8
    {
Packit 7838c8
        *((int32 *)pabyData) = (int32) dfValue;
Packit 7838c8
    }
Packit 7838c8
    else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 4 )
Packit 7838c8
    {
Packit 7838c8
        *((float *)pabyData) = (float) dfValue;
Packit 7838c8
    }
Packit 7838c8
    else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 8 )
Packit 7838c8
    {
Packit 7838c8
        *((double *)pabyData) = dfValue;
Packit 7838c8
    }
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                          TIFF_DownSample()                           */
Packit 7838c8
/*                                                                      */
Packit 7838c8
/*      Down sample a tile of full res data into a window of a tile     */
Packit 7838c8
/*      of downsampled data.                                            */
Packit 7838c8
/************************************************************************/
Packit 7838c8
Packit 7838c8
static
Packit 7838c8
void TIFF_DownSample( unsigned char *pabySrcTile,
Packit 7838c8
                      uint32 nBlockXSize, uint32 nBlockYSize,
Packit 7838c8
                      int nPixelSkewBits, int nBitsPerPixel,
Packit 7838c8
                      unsigned char * pabyOTile,
Packit 7838c8
                      uint32 nOBlockXSize, uint32 nOBlockYSize,
Packit 7838c8
                      uint32 nTXOff, uint32 nTYOff, int nOMult,
Packit 7838c8
                      int nSampleFormat, const char * pszResampling )
Packit 7838c8
Packit 7838c8
{
Packit 7838c8
    uint32	i, j;
Packit 7838c8
    int         k, nPixelBytes = (nBitsPerPixel) / 8;
Packit 7838c8
    int		nPixelGroupBytes = (nBitsPerPixel+nPixelSkewBits)/8;
Packit 7838c8
    unsigned char *pabySrc, *pabyDst;
Packit 7838c8
    double      *padfSamples;
Packit 7838c8
    size_t      tpadfSamples_size, padfSamples_size;
Packit 7838c8
Packit 7838c8
    assert( nBitsPerPixel >= 8 );
Packit 7838c8
Packit 7838c8
    /* sizeof(double) * nOMult * nOMult */
Packit 7838c8
    tpadfSamples_size=nOMult*nOMult;
Packit 7838c8
    if ((nOMult != 0) && (tpadfSamples_size/nOMult == (size_t) nOMult)) {
Packit 7838c8
        padfSamples_size=tpadfSamples_size;
Packit 7838c8
        tpadfSamples_size=padfSamples_size*sizeof(double);
Packit 7838c8
        if ((tpadfSamples_size / padfSamples_size) == sizeof(double))
Packit 7838c8
            padfSamples_size=tpadfSamples_size;
Packit 7838c8
        else
Packit 7838c8
            padfSamples_size=0;
Packit 7838c8
    } else {
Packit 7838c8
        padfSamples_size=0;
Packit 7838c8
    }
Packit 7838c8
    if (padfSamples_size == 0) {
Packit 7838c8
        /* TODO: This is an error condition */
Packit 7838c8
        return;
Packit 7838c8
    }
Packit 7838c8
    padfSamples = (double *) malloc(padfSamples_size);
Packit 7838c8
Packit 7838c8
/* ==================================================================== */
Packit 7838c8
/*      Loop over scanline chunks to process, establishing where the    */
Packit 7838c8
/*      data is going.                                                  */
Packit 7838c8
/* ==================================================================== */
Packit 7838c8
    for( j = 0; j*nOMult < nBlockYSize; j++ )
Packit 7838c8
    {
Packit 7838c8
        if( j + nTYOff >= nOBlockYSize )
Packit 7838c8
            break;
Packit 7838c8
Packit 7838c8
        pabyDst = pabyOTile + ((j+nTYOff)*nOBlockXSize + nTXOff)
Packit 7838c8
            * nPixelBytes * nPixelGroupBytes;
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Handler nearest resampling ... we don't even care about the     */
Packit 7838c8
/*      data type, we just do a bytewise copy.                          */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
        if( strncmp(pszResampling,"nearest",4) == 0
Packit 7838c8
            || strncmp(pszResampling,"NEAR",4) == 0 )
Packit 7838c8
        {
Packit 7838c8
            pabySrc = pabySrcTile + j*nOMult*nBlockXSize * nPixelGroupBytes;
Packit 7838c8
Packit 7838c8
            for( i = 0; i*nOMult < nBlockXSize; i++ )
Packit 7838c8
            {
Packit 7838c8
                if( i + nTXOff >= nOBlockXSize )
Packit 7838c8
                    break;
Packit 7838c8
            
Packit 7838c8
                /*
Packit 7838c8
                 * For now use simple subsampling, from the top left corner
Packit 7838c8
                 * of the source block of pixels.
Packit 7838c8
                 */
Packit 7838c8
Packit 7838c8
                for( k = 0; k < nPixelBytes; k++ )
Packit 7838c8
                    pabyDst[k] = pabySrc[k];
Packit 7838c8
Packit 7838c8
                pabyDst += nPixelBytes * nPixelGroupBytes;
Packit 7838c8
                pabySrc += nOMult * nPixelGroupBytes;
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Handle the case of averaging.  For this we also have to         */
Packit 7838c8
/*      handle each sample format we are concerned with.                */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
        else if( strncmp(pszResampling,"averag",6) == 0
Packit 7838c8
                 || strncmp(pszResampling,"AVERAG",6) == 0 )
Packit 7838c8
        {
Packit 7838c8
            pabySrc = pabySrcTile + j*nOMult*nBlockXSize * nPixelGroupBytes;
Packit 7838c8
Packit 7838c8
            for( i = 0; i*nOMult < nBlockXSize; i++ )
Packit 7838c8
            {
Packit 7838c8
                double   dfTotal;
Packit 7838c8
                uint32   nXSize, nYSize, iSample;
Packit 7838c8
Packit 7838c8
                if( i + nTXOff >= nOBlockXSize )
Packit 7838c8
                    break;
Packit 7838c8
Packit 7838c8
                nXSize = MIN((uint32)nOMult,nBlockXSize-i);
Packit 7838c8
                nYSize = MIN((uint32)nOMult,nBlockYSize-j);
Packit 7838c8
Packit 7838c8
                TIFF_GetSourceSamples( padfSamples, pabySrc,
Packit 7838c8
                                       nPixelBytes, nSampleFormat,
Packit 7838c8
                                       nXSize, nYSize,
Packit 7838c8
                                       nPixelGroupBytes,
Packit 7838c8
                                       nPixelGroupBytes * nBlockXSize );
Packit 7838c8
Packit 7838c8
                dfTotal = 0;
Packit 7838c8
                for( iSample = 0; iSample < nXSize*nYSize; iSample++ )
Packit 7838c8
                {
Packit 7838c8
                    dfTotal += padfSamples[iSample];
Packit 7838c8
                }
Packit 7838c8
Packit 7838c8
                TIFF_SetSample( pabyDst, nPixelBytes, nSampleFormat, 
Packit 7838c8
                                dfTotal / (nXSize*nYSize) );
Packit 7838c8
Packit 7838c8
                pabySrc += nOMult * nPixelGroupBytes;
Packit 7838c8
                pabyDst += nPixelBytes;
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    free( padfSamples );
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                     TIFF_DownSample_Subsampled()                     */
Packit 7838c8
/************************************************************************/
Packit 7838c8
static
Packit 7838c8
void TIFF_DownSample_Subsampled( unsigned char *pabySrcTile, int nSample,
Packit 7838c8
                                 uint32 nBlockXSize, uint32 nBlockYSize,
Packit 7838c8
                                 unsigned char * pabyOTile,
Packit 7838c8
                                 uint32 nOBlockXSize, uint32 nOBlockYSize,
Packit 7838c8
                                 uint32 nTXOff, uint32 nTYOff, int nOMult,
Packit 7838c8
                                 const char *pszResampling,
Packit 7838c8
                                 int nHorSubsampling, int nVerSubsampling )
Packit 7838c8
{
Packit 7838c8
    /* TODO: test with variety of subsampling values, and incovinient tile/strip sizes */
Packit 7838c8
    int nSampleBlockSize;
Packit 7838c8
    int nSourceSampleRowSize;
Packit 7838c8
    int nDestSampleRowSize;
Packit 7838c8
    uint32  nSourceX, nSourceY;
Packit 7838c8
    uint32  nSourceXSec, nSourceYSec;
Packit 7838c8
    uint32  nSourceXSecEnd, nSourceYSecEnd;
Packit 7838c8
    uint32  nDestX, nDestY;
Packit 7838c8
    int nSampleOffsetInSampleBlock;
Packit 7838c8
    unsigned int nCummulator;
Packit 7838c8
    unsigned int nCummulatorCount;
Packit 7838c8
Packit 7838c8
    nSampleBlockSize = nHorSubsampling * nVerSubsampling + 2;
Packit 7838c8
    nSourceSampleRowSize = 
Packit 7838c8
        ( ( nBlockXSize + nHorSubsampling - 1 ) / nHorSubsampling ) * nSampleBlockSize;
Packit 7838c8
    nDestSampleRowSize = 
Packit 7838c8
        ( ( nOBlockXSize + nHorSubsampling - 1 ) / nHorSubsampling ) * nSampleBlockSize;
Packit 7838c8
Packit 7838c8
    if( strncmp(pszResampling,"nearest",4) == 0
Packit 7838c8
        || strncmp(pszResampling,"NEAR",4) == 0 )
Packit 7838c8
    {
Packit 7838c8
    	if( nSample == 0 )
Packit 7838c8
        {
Packit 7838c8
            for( nSourceY = 0, nDestY = nTYOff; 
Packit 7838c8
                 nSourceY < nBlockYSize; 
Packit 7838c8
                 nSourceY += nOMult, nDestY ++)
Packit 7838c8
            {
Packit 7838c8
                if( nDestY >= nOBlockYSize )
Packit 7838c8
                    break;
Packit 7838c8
Packit 7838c8
                for( nSourceX = 0, nDestX = nTXOff; 
Packit 7838c8
                     nSourceX < nBlockXSize; 
Packit 7838c8
                     nSourceX += nOMult, nDestX ++)
Packit 7838c8
                {
Packit 7838c8
                    if( nDestX >= nOBlockXSize )
Packit 7838c8
                        break;
Packit 7838c8
Packit 7838c8
                    * ( pabyOTile + ( nDestY / nVerSubsampling ) * nDestSampleRowSize
Packit 7838c8
                        + ( nDestY % nVerSubsampling ) * nHorSubsampling
Packit 7838c8
                        + ( nDestX / nHorSubsampling ) * nSampleBlockSize
Packit 7838c8
                        + ( nDestX % nHorSubsampling ) ) =
Packit 7838c8
                        * ( pabySrcTile + ( nSourceY / nVerSubsampling ) * nSourceSampleRowSize
Packit 7838c8
                            + ( nSourceY % nVerSubsampling ) * nHorSubsampling
Packit 7838c8
                            + ( nSourceX / nHorSubsampling ) * nSampleBlockSize
Packit 7838c8
                            + ( nSourceX % nHorSubsampling ) );
Packit 7838c8
                }
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
        else
Packit 7838c8
        {
Packit 7838c8
            nSampleOffsetInSampleBlock = nHorSubsampling * nVerSubsampling + nSample - 1;
Packit 7838c8
            for( nSourceY = 0, nDestY = ( nTYOff / nVerSubsampling ); 
Packit 7838c8
                 nSourceY < ( nBlockYSize / nVerSubsampling );
Packit 7838c8
                 nSourceY += nOMult, nDestY ++)
Packit 7838c8
            {
Packit 7838c8
                if( nDestY*nVerSubsampling >= nOBlockYSize )
Packit 7838c8
                    break;
Packit 7838c8
Packit 7838c8
            	for( nSourceX = 0, nDestX = ( nTXOff / nHorSubsampling ); 
Packit 7838c8
                     nSourceX < ( nBlockXSize / nHorSubsampling );
Packit 7838c8
                     nSourceX += nOMult, nDestX ++)
Packit 7838c8
                {
Packit 7838c8
                    if( nDestX*nHorSubsampling >= nOBlockXSize )
Packit 7838c8
                        break;
Packit 7838c8
Packit 7838c8
                    * ( pabyOTile + nDestY * nDestSampleRowSize
Packit 7838c8
                        + nDestX * nSampleBlockSize
Packit 7838c8
                        + nSampleOffsetInSampleBlock ) =
Packit 7838c8
                    	* ( pabySrcTile + nSourceY * nSourceSampleRowSize
Packit 7838c8
                            + nSourceX * nSampleBlockSize
Packit 7838c8
                            + nSampleOffsetInSampleBlock );
Packit 7838c8
                }
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
    else if( strncmp(pszResampling,"averag",6) == 0
Packit 7838c8
             || strncmp(pszResampling,"AVERAG",6) == 0 )
Packit 7838c8
    {
Packit 7838c8
    	if( nSample == 0 )
Packit 7838c8
        {
Packit 7838c8
            for( nSourceY = 0, nDestY = nTYOff; nSourceY < nBlockYSize; nSourceY += nOMult, nDestY ++)
Packit 7838c8
            {
Packit 7838c8
                if( nDestY >= nOBlockYSize )
Packit 7838c8
                    break;
Packit 7838c8
Packit 7838c8
                for( nSourceX = 0, nDestX = nTXOff; nSourceX < nBlockXSize; nSourceX += nOMult, nDestX ++)
Packit 7838c8
                {
Packit 7838c8
                    if( nDestX >= nOBlockXSize )
Packit 7838c8
                        break;
Packit 7838c8
Packit 7838c8
                    nSourceXSecEnd = nSourceX + nOMult;
Packit 7838c8
                    if( nSourceXSecEnd > nBlockXSize )
Packit 7838c8
                        nSourceXSecEnd = nBlockXSize;
Packit 7838c8
                    nSourceYSecEnd = nSourceY + nOMult;
Packit 7838c8
                    if( nSourceYSecEnd > nBlockYSize )
Packit 7838c8
                        nSourceYSecEnd = nBlockYSize;
Packit 7838c8
                    nCummulator = 0;
Packit 7838c8
                    for( nSourceYSec = nSourceY; nSourceYSec < nSourceYSecEnd; nSourceYSec ++)
Packit 7838c8
                    {
Packit 7838c8
                        for( nSourceXSec = nSourceX; nSourceXSec < nSourceXSecEnd; nSourceXSec ++)
Packit 7838c8
                        {
Packit 7838c8
                            nCummulator += * ( pabySrcTile + ( nSourceYSec / nVerSubsampling ) * nSourceSampleRowSize
Packit 7838c8
                                               + ( nSourceYSec % nVerSubsampling ) * nHorSubsampling
Packit 7838c8
                                               + ( nSourceXSec / nHorSubsampling ) * nSampleBlockSize
Packit 7838c8
                                               + ( nSourceXSec % nHorSubsampling ) );
Packit 7838c8
                        }
Packit 7838c8
                    }
Packit 7838c8
                    nCummulatorCount = ( nSourceXSecEnd - nSourceX ) * ( nSourceYSecEnd - nSourceY );
Packit 7838c8
                    * ( pabyOTile + ( nDestY / nVerSubsampling ) * nDestSampleRowSize
Packit 7838c8
                        + ( nDestY % nVerSubsampling ) * nHorSubsampling
Packit 7838c8
                        + ( nDestX / nHorSubsampling ) * nSampleBlockSize
Packit 7838c8
                        + ( nDestX % nHorSubsampling ) ) =
Packit 7838c8
                        ( ( nCummulator + ( nCummulatorCount >> 1 ) ) / nCummulatorCount );
Packit 7838c8
                }
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
        else
Packit 7838c8
        {
Packit 7838c8
            nSampleOffsetInSampleBlock = nHorSubsampling * nVerSubsampling + nSample - 1;
Packit 7838c8
            for( nSourceY = 0, nDestY = ( nTYOff / nVerSubsampling ); nSourceY < ( nBlockYSize / nVerSubsampling );
Packit 7838c8
                 nSourceY += nOMult, nDestY ++)
Packit 7838c8
            {
Packit 7838c8
                if( nDestY*nVerSubsampling >= nOBlockYSize )
Packit 7838c8
                    break;
Packit 7838c8
Packit 7838c8
                for( nSourceX = 0, nDestX = ( nTXOff / nHorSubsampling ); nSourceX < ( nBlockXSize / nHorSubsampling );
Packit 7838c8
                     nSourceX += nOMult, nDestX ++)
Packit 7838c8
                {
Packit 7838c8
                    if( nDestX*nHorSubsampling >= nOBlockXSize )
Packit 7838c8
                        break;
Packit 7838c8
Packit 7838c8
                    nSourceXSecEnd = nSourceX + nOMult;
Packit 7838c8
                    if( nSourceXSecEnd > ( nBlockXSize / nHorSubsampling ) )
Packit 7838c8
                        nSourceXSecEnd = ( nBlockXSize / nHorSubsampling );
Packit 7838c8
                    nSourceYSecEnd = nSourceY + nOMult;
Packit 7838c8
                    if( nSourceYSecEnd > ( nBlockYSize / nVerSubsampling ) )
Packit 7838c8
                        nSourceYSecEnd = ( nBlockYSize / nVerSubsampling );
Packit 7838c8
                    nCummulator = 0;
Packit 7838c8
                    for( nSourceYSec = nSourceY; nSourceYSec < nSourceYSecEnd; nSourceYSec ++)
Packit 7838c8
                    {
Packit 7838c8
                        for( nSourceXSec = nSourceX; nSourceXSec < nSourceXSecEnd; nSourceXSec ++)
Packit 7838c8
                        {
Packit 7838c8
                            nCummulator += * ( pabySrcTile + nSourceYSec * nSourceSampleRowSize
Packit 7838c8
                                               + nSourceXSec * nSampleBlockSize
Packit 7838c8
                                               + nSampleOffsetInSampleBlock );
Packit 7838c8
                        }
Packit 7838c8
                    }
Packit 7838c8
                    nCummulatorCount = ( nSourceXSecEnd - nSourceX ) * ( nSourceYSecEnd - nSourceY );
Packit 7838c8
                    * ( pabyOTile + nDestY * nDestSampleRowSize
Packit 7838c8
                        + nDestX * nSampleBlockSize
Packit 7838c8
                        + nSampleOffsetInSampleBlock ) =
Packit 7838c8
                        ( ( nCummulator + ( nCummulatorCount >> 1 ) ) / nCummulatorCount );
Packit 7838c8
                }
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                      TIFF_ProcessFullResBlock()                      */
Packit 7838c8
/*                                                                      */
Packit 7838c8
/*      Process one block of full res data, downsampling into each      */
Packit 7838c8
/*      of the overviews.                                               */
Packit 7838c8
/************************************************************************/
Packit 7838c8
Packit 7838c8
void TIFF_ProcessFullResBlock( TIFF *hTIFF, int nPlanarConfig,
Packit 7838c8
                               int bSubsampled,
Packit 7838c8
                               int nHorSubsampling, int nVerSubsampling,
Packit 7838c8
                               int nOverviews, int * panOvList,
Packit 7838c8
                               int nBitsPerPixel,
Packit 7838c8
                               int nSamples, TIFFOvrCache ** papoRawBIs,
Packit 7838c8
                               uint32 nSXOff, uint32 nSYOff,
Packit 7838c8
                               unsigned char *pabySrcTile,
Packit 7838c8
                               uint32 nBlockXSize, uint32 nBlockYSize,
Packit 7838c8
                               int nSampleFormat, const char * pszResampling )
Packit 7838c8
    
Packit 7838c8
{
Packit 7838c8
    int		iOverview, iSample;
Packit 7838c8
Packit 7838c8
    for( iSample = 0; iSample < nSamples; iSample++ )
Packit 7838c8
    {
Packit 7838c8
        /*
Packit 7838c8
         * We have to read a tile/strip for each sample for
Packit 7838c8
         * PLANARCONFIG_SEPARATE.  Otherwise, we just read all the samples
Packit 7838c8
         * at once when handling the first sample.
Packit 7838c8
         */
Packit 7838c8
        if( nPlanarConfig == PLANARCONFIG_SEPARATE || iSample == 0 )
Packit 7838c8
        {
Packit 7838c8
            if( TIFFIsTiled(hTIFF) )
Packit 7838c8
            {
Packit 7838c8
                TIFFReadEncodedTile( hTIFF,
Packit 7838c8
                                     TIFFComputeTile(hTIFF, nSXOff, nSYOff,
Packit 7838c8
                                                     0, (tsample_t)iSample ),
Packit 7838c8
                                     pabySrcTile,
Packit 7838c8
                                     TIFFTileSize(hTIFF));
Packit 7838c8
            }
Packit 7838c8
            else
Packit 7838c8
            {
Packit 7838c8
                TIFFReadEncodedStrip( hTIFF,
Packit 7838c8
                                      TIFFComputeStrip(hTIFF, nSYOff,
Packit 7838c8
                                                       (tsample_t) iSample),
Packit 7838c8
                                      pabySrcTile,
Packit 7838c8
                                      TIFFStripSize(hTIFF) );
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
Packit 7838c8
        /*        
Packit 7838c8
         * Loop over destination overview layers
Packit 7838c8
         */
Packit 7838c8
        for( iOverview = 0; iOverview < nOverviews; iOverview++ )
Packit 7838c8
        {
Packit 7838c8
            TIFFOvrCache *poRBI = papoRawBIs[iOverview];
Packit 7838c8
            unsigned char *pabyOTile;
Packit 7838c8
            uint32  nTXOff, nTYOff, nOXOff, nOYOff, nOMult;
Packit 7838c8
            uint32  nOBlockXSize = poRBI->nBlockXSize;
Packit 7838c8
            uint32  nOBlockYSize = poRBI->nBlockYSize;
Packit 7838c8
            int     nSkewBits, nSampleByteOffset; 
Packit 7838c8
Packit 7838c8
            /*
Packit 7838c8
             * Fetch the destination overview tile
Packit 7838c8
             */
Packit 7838c8
            nOMult = panOvList[iOverview];
Packit 7838c8
            nOXOff = (nSXOff/nOMult) / nOBlockXSize;
Packit 7838c8
            nOYOff = (nSYOff/nOMult) / nOBlockYSize;
Packit 7838c8
Packit 7838c8
            if( bSubsampled )
Packit 7838c8
            {
Packit 7838c8
                pabyOTile = TIFFGetOvrBlock_Subsampled( poRBI, nOXOff, nOYOff );
Packit 7838c8
Packit 7838c8
                /*
Packit 7838c8
                 * Establish the offset into this tile at which we should
Packit 7838c8
                 * start placing data.
Packit 7838c8
                 */
Packit 7838c8
                nTXOff = (nSXOff - nOXOff*nOMult*nOBlockXSize) / nOMult;
Packit 7838c8
                nTYOff = (nSYOff - nOYOff*nOMult*nOBlockYSize) / nOMult;
Packit 7838c8
Packit 7838c8
Packit 7838c8
#ifdef DBMALLOC
Packit 7838c8
                malloc_chain_check( 1 );
Packit 7838c8
#endif
Packit 7838c8
                TIFF_DownSample_Subsampled( pabySrcTile, iSample,
Packit 7838c8
                                            nBlockXSize, nBlockYSize,
Packit 7838c8
                                            pabyOTile,
Packit 7838c8
                                            poRBI->nBlockXSize, poRBI->nBlockYSize,
Packit 7838c8
                                            nTXOff, nTYOff,
Packit 7838c8
                                            nOMult, pszResampling,
Packit 7838c8
                                            nHorSubsampling, nVerSubsampling );
Packit 7838c8
#ifdef DBMALLOC
Packit 7838c8
                malloc_chain_check( 1 );
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
            }
Packit 7838c8
            else
Packit 7838c8
            {
Packit 7838c8
Packit 7838c8
                pabyOTile = TIFFGetOvrBlock( poRBI, nOXOff, nOYOff, iSample );
Packit 7838c8
Packit 7838c8
                /*
Packit 7838c8
                 * Establish the offset into this tile at which we should
Packit 7838c8
                 * start placing data.
Packit 7838c8
                 */
Packit 7838c8
                nTXOff = (nSXOff - nOXOff*nOMult*nOBlockXSize) / nOMult;
Packit 7838c8
                nTYOff = (nSYOff - nOYOff*nOMult*nOBlockYSize) / nOMult;
Packit 7838c8
Packit 7838c8
                /*
Packit 7838c8
                 * Figure out the skew (extra space between ``our samples'') and
Packit 7838c8
                 * the byte offset to the first sample.
Packit 7838c8
                 */
Packit 7838c8
                assert( (nBitsPerPixel % 8) == 0 );
Packit 7838c8
                if( nPlanarConfig == PLANARCONFIG_SEPARATE )
Packit 7838c8
                {
Packit 7838c8
                    nSkewBits = 0;
Packit 7838c8
                    nSampleByteOffset = 0;
Packit 7838c8
                }
Packit 7838c8
                else
Packit 7838c8
                {
Packit 7838c8
                    nSkewBits = nBitsPerPixel * (nSamples-1);
Packit 7838c8
                    nSampleByteOffset = (nBitsPerPixel/8) * iSample;
Packit 7838c8
                }
Packit 7838c8
Packit 7838c8
                /*
Packit 7838c8
                 * Perform the downsampling.
Packit 7838c8
                 */
Packit 7838c8
#ifdef DBMALLOC
Packit 7838c8
                malloc_chain_check( 1 );
Packit 7838c8
#endif
Packit 7838c8
                TIFF_DownSample( pabySrcTile + nSampleByteOffset,
Packit 7838c8
                               nBlockXSize, nBlockYSize,
Packit 7838c8
                               nSkewBits, nBitsPerPixel, pabyOTile,
Packit 7838c8
                               poRBI->nBlockXSize, poRBI->nBlockYSize,
Packit 7838c8
                               nTXOff, nTYOff,
Packit 7838c8
                               nOMult, nSampleFormat, pszResampling );
Packit 7838c8
#ifdef DBMALLOC
Packit 7838c8
                malloc_chain_check( 1 );
Packit 7838c8
#endif
Packit 7838c8
            }
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/************************************************************************/
Packit 7838c8
/*                        TIFF_BuildOverviews()                         */
Packit 7838c8
/*                                                                      */
Packit 7838c8
/*      Build the requested list of overviews.  Overviews are           */
Packit 7838c8
/*      maintained in a bunch of temporary files and then these are     */
Packit 7838c8
/*      written back to the TIFF file.  Only one pass through the       */
Packit 7838c8
/*      source TIFF file is made for any number of output               */
Packit 7838c8
/*      overviews.                                                      */
Packit 7838c8
/************************************************************************/
Packit 7838c8
Packit 7838c8
void TIFFBuildOverviews( TIFF *hTIFF, int nOverviews, int * panOvList,
Packit 7838c8
                         int bUseSubIFDs, const char *pszResampleMethod,
Packit 7838c8
                         int (*pfnProgress)( double, void * ),
Packit 7838c8
                         void * pProgressData )
Packit 7838c8
Packit 7838c8
{
Packit 7838c8
    TIFFOvrCache	**papoRawBIs;
Packit 7838c8
    uint32		nXSize, nYSize, nBlockXSize, nBlockYSize;
Packit 7838c8
    uint16		nBitsPerPixel, nPhotometric, nCompressFlag, nSamples,
Packit 7838c8
        nPlanarConfig, nSampleFormat;
Packit 7838c8
    int         bSubsampled;
Packit 7838c8
    uint16      nHorSubsampling, nVerSubsampling;
Packit 7838c8
    int			bTiled, nSXOff, nSYOff, i;
Packit 7838c8
    unsigned char	*pabySrcTile;
Packit 7838c8
    uint16		*panRedMap, *panGreenMap, *panBlueMap;
Packit 7838c8
    TIFFErrorHandler    pfnWarning;
Packit 7838c8
Packit 7838c8
    (void) pfnProgress;
Packit 7838c8
    (void) pProgressData;
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Get the base raster size.                                       */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &nXSize );
Packit 7838c8
    TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &nYSize );
Packit 7838c8
Packit 7838c8
    TIFFGetField( hTIFF, TIFFTAG_BITSPERSAMPLE, &nBitsPerPixel );
Packit 7838c8
    /* TODO: nBitsPerPixel seems misnomer and may need renaming to nBitsPerSample */
Packit 7838c8
    TIFFGetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, &nSamples );
Packit 7838c8
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_PLANARCONFIG, &nPlanarConfig );
Packit 7838c8
Packit 7838c8
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_PHOTOMETRIC, &nPhotometric );
Packit 7838c8
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_COMPRESSION, &nCompressFlag );
Packit 7838c8
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_SAMPLEFORMAT, &nSampleFormat );
Packit 7838c8
Packit 7838c8
    if( nPhotometric == PHOTOMETRIC_YCBCR || nPhotometric == PHOTOMETRIC_ITULAB )
Packit 7838c8
    {
Packit 7838c8
        if( nBitsPerPixel != 8 || nSamples != 3 || nPlanarConfig != PLANARCONFIG_CONTIG ||
Packit 7838c8
            nSampleFormat != SAMPLEFORMAT_UINT)
Packit 7838c8
        {
Packit 7838c8
            /* TODO: use of TIFFError is inconsistent with use of fprintf in addtiffo.c, sort out */
Packit 7838c8
            TIFFErrorExt( TIFFClientdata(hTIFF), "TIFFBuildOverviews",
Packit 7838c8
                          "File `%s' has an unsupported subsampling configuration.\n",
Packit 7838c8
                          TIFFFileName(hTIFF) );
Packit 7838c8
            /* If you need support for this particular flavor, please contact either
Packit 7838c8
             * Frank Warmerdam warmerdam@pobox.com
Packit 7838c8
             * Joris Van Damme info@awaresystems.be
Packit 7838c8
             */
Packit 7838c8
            return;
Packit 7838c8
        }
Packit 7838c8
        bSubsampled = 1;
Packit 7838c8
        TIFFGetField( hTIFF, TIFFTAG_YCBCRSUBSAMPLING, &nHorSubsampling, &nVerSubsampling );
Packit 7838c8
        /* TODO: find out if maybe TIFFGetFieldDefaulted is better choice for YCbCrSubsampling tag */
Packit 7838c8
    }
Packit 7838c8
    else
Packit 7838c8
    {
Packit 7838c8
        if( nBitsPerPixel < 8 )
Packit 7838c8
        {
Packit 7838c8
            /* TODO: use of TIFFError is inconsistent with use of fprintf in addtiffo.c, sort out */
Packit 7838c8
            TIFFErrorExt( TIFFClientdata(hTIFF), "TIFFBuildOverviews",
Packit 7838c8
                          "File `%s' has samples of %d bits per sample.  Sample\n"
Packit 7838c8
                          "sizes of less than 8 bits per sample are not supported.\n",
Packit 7838c8
                          TIFFFileName(hTIFF), nBitsPerPixel );
Packit 7838c8
            return;
Packit 7838c8
        }
Packit 7838c8
        bSubsampled = 0;
Packit 7838c8
        nHorSubsampling = 1;
Packit 7838c8
        nVerSubsampling = 1;
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Turn off warnings to avoid alot of repeated warnings while      */
Packit 7838c8
/*      rereading directories.                                          */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    pfnWarning = TIFFSetWarningHandler( NULL );
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Get the base raster block size.                                 */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    if( TIFFGetField( hTIFF, TIFFTAG_ROWSPERSTRIP, &(nBlockYSize) ) )
Packit 7838c8
    {
Packit 7838c8
        nBlockXSize = nXSize;
Packit 7838c8
        bTiled = FALSE;
Packit 7838c8
    }
Packit 7838c8
    else
Packit 7838c8
    {
Packit 7838c8
        TIFFGetField( hTIFF, TIFFTAG_TILEWIDTH, &nBlockXSize );
Packit 7838c8
        TIFFGetField( hTIFF, TIFFTAG_TILELENGTH, &nBlockYSize );
Packit 7838c8
        bTiled = TRUE;
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*	Capture the pallette if there is one.				*/
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    if( TIFFGetField( hTIFF, TIFFTAG_COLORMAP,
Packit 7838c8
                      &panRedMap, &panGreenMap, &panBlueMap ) )
Packit 7838c8
    {
Packit 7838c8
        uint16		*panRed2, *panGreen2, *panBlue2;
Packit 7838c8
        int             nColorCount = 1 << nBitsPerPixel;
Packit 7838c8
Packit 7838c8
        panRed2 = (uint16 *) _TIFFmalloc(2*nColorCount);
Packit 7838c8
        panGreen2 = (uint16 *) _TIFFmalloc(2*nColorCount);
Packit 7838c8
        panBlue2 = (uint16 *) _TIFFmalloc(2*nColorCount);
Packit 7838c8
Packit 7838c8
        memcpy( panRed2, panRedMap, 2 * nColorCount );
Packit 7838c8
        memcpy( panGreen2, panGreenMap, 2 * nColorCount );
Packit 7838c8
        memcpy( panBlue2, panBlueMap, 2 * nColorCount );
Packit 7838c8
Packit 7838c8
        panRedMap = panRed2;
Packit 7838c8
        panGreenMap = panGreen2;
Packit 7838c8
        panBlueMap = panBlue2;
Packit 7838c8
    }
Packit 7838c8
    else
Packit 7838c8
    {
Packit 7838c8
        panRedMap = panGreenMap = panBlueMap = NULL;
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Initialize overviews.                                           */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    papoRawBIs = (TIFFOvrCache **) _TIFFmalloc(nOverviews*sizeof(void*));
Packit 7838c8
Packit 7838c8
    for( i = 0; i < nOverviews; i++ )
Packit 7838c8
    {
Packit 7838c8
        uint32  nOXSize, nOYSize, nOBlockXSize, nOBlockYSize;
Packit 7838c8
        toff_t  nDirOffset;
Packit 7838c8
Packit 7838c8
        nOXSize = (nXSize + panOvList[i] - 1) / panOvList[i];
Packit 7838c8
        nOYSize = (nYSize + panOvList[i] - 1) / panOvList[i];
Packit 7838c8
Packit 7838c8
        nOBlockXSize = MIN(nBlockXSize,nOXSize);
Packit 7838c8
        nOBlockYSize = MIN(nBlockYSize,nOYSize);
Packit 7838c8
Packit 7838c8
        if( bTiled )
Packit 7838c8
        {
Packit 7838c8
            if( (nOBlockXSize % 16) != 0 )
Packit 7838c8
                nOBlockXSize = nOBlockXSize + 16 - (nOBlockXSize % 16);
Packit 7838c8
Packit 7838c8
            if( (nOBlockYSize % 16) != 0 )
Packit 7838c8
                nOBlockYSize = nOBlockYSize + 16 - (nOBlockYSize % 16);
Packit 7838c8
        }
Packit 7838c8
Packit 7838c8
        nDirOffset = TIFF_WriteOverview( hTIFF, nOXSize, nOYSize,
Packit 7838c8
                                         nBitsPerPixel, nPlanarConfig,
Packit 7838c8
                                         nSamples, nOBlockXSize, nOBlockYSize,
Packit 7838c8
                                         bTiled, nCompressFlag, nPhotometric,
Packit 7838c8
                                         nSampleFormat,
Packit 7838c8
                                         panRedMap, panGreenMap, panBlueMap,
Packit 7838c8
                                         bUseSubIFDs,
Packit 7838c8
                                         nHorSubsampling, nVerSubsampling );
Packit 7838c8
        
Packit 7838c8
        papoRawBIs[i] = TIFFCreateOvrCache( hTIFF, nDirOffset );
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    if( panRedMap != NULL )
Packit 7838c8
    {
Packit 7838c8
        _TIFFfree( panRedMap );
Packit 7838c8
        _TIFFfree( panGreenMap );
Packit 7838c8
        _TIFFfree( panBlueMap );
Packit 7838c8
    }
Packit 7838c8
    
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Allocate a buffer to hold a source block.                       */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    if( bTiled )
Packit 7838c8
        pabySrcTile = (unsigned char *) _TIFFmalloc(TIFFTileSize(hTIFF));
Packit 7838c8
    else
Packit 7838c8
        pabySrcTile = (unsigned char *) _TIFFmalloc(TIFFStripSize(hTIFF));
Packit 7838c8
    
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Loop over the source raster, applying data to the               */
Packit 7838c8
/*      destination raster.                                             */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    for( nSYOff = 0; nSYOff < (int) nYSize; nSYOff += nBlockYSize )
Packit 7838c8
    {
Packit 7838c8
        for( nSXOff = 0; nSXOff < (int) nXSize; nSXOff += nBlockXSize )
Packit 7838c8
        {
Packit 7838c8
            /*
Packit 7838c8
             * Read and resample into the various overview images.
Packit 7838c8
             */
Packit 7838c8
            
Packit 7838c8
            TIFF_ProcessFullResBlock( hTIFF, nPlanarConfig,
Packit 7838c8
                                      bSubsampled,nHorSubsampling,nVerSubsampling,
Packit 7838c8
                                      nOverviews, panOvList,
Packit 7838c8
                                      nBitsPerPixel, nSamples, papoRawBIs,
Packit 7838c8
                                      nSXOff, nSYOff, pabySrcTile,
Packit 7838c8
                                      nBlockXSize, nBlockYSize,
Packit 7838c8
                                      nSampleFormat, pszResampleMethod );
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    _TIFFfree( pabySrcTile );
Packit 7838c8
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
/*      Cleanup the rawblockedimage files.                              */
Packit 7838c8
/* -------------------------------------------------------------------- */
Packit 7838c8
    for( i = 0; i < nOverviews; i++ )
Packit 7838c8
    {
Packit 7838c8
        TIFFDestroyOvrCache( papoRawBIs[i] );
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    if( papoRawBIs != NULL )
Packit 7838c8
        _TIFFfree( papoRawBIs );
Packit 7838c8
Packit 7838c8
    TIFFSetWarningHandler( pfnWarning );
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 4
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */