Exemplo n.º 1
0
void TIFFBuildOverviews( TIFF *hTIFF, int nOverviews, int * panOvList,
                         int bUseSubIFDs, const char *pszResampleMethod,
                         int (*pfnProgress)( double, void * ),
                         void * pProgressData )

{
    TIFFOvrCache	**papoRawBIs;
    uint32		nXSize, nYSize, nBlockXSize, nBlockYSize;
    uint16		nBitsPerPixel, nPhotometric, nCompressFlag, nSamples,
                        nPlanarConfig, nSampleFormat;
    int			bTiled, nSXOff, nSYOff, i;
    unsigned char	*pabySrcTile;
    uint16		*panRedMap, *panGreenMap, *panBlueMap;
    TIFFErrorHandler    pfnWarning;

/* -------------------------------------------------------------------- */
/*      Get the base raster size.                                       */
/* -------------------------------------------------------------------- */
    TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &nXSize );
    TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &nYSize );

    TIFFGetField( hTIFF, TIFFTAG_BITSPERSAMPLE, &nBitsPerPixel );
    TIFFGetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, &nSamples );
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_PLANARCONFIG, &nPlanarConfig );

    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_PHOTOMETRIC, &nPhotometric );
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_COMPRESSION, &nCompressFlag );
    TIFFGetFieldDefaulted( hTIFF, TIFFTAG_SAMPLEFORMAT, &nSampleFormat );

    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",
                   TIFFFileName(hTIFF), nBitsPerPixel );
        return;
    }
    
/* -------------------------------------------------------------------- */
/*      Turn off warnings to avoid alot of repeated warnings while      */
/*      rereading directories.                                          */
/* -------------------------------------------------------------------- */
    pfnWarning = TIFFSetWarningHandler( NULL );

/* -------------------------------------------------------------------- */
/*      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 *) _TIFFmalloc(2*256);
        panGreen2 = (uint16 *) _TIFFmalloc(2*256);
        panBlue2 = (uint16 *) _TIFFmalloc(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 overviews.                                           */
/* -------------------------------------------------------------------- */
    papoRawBIs = (TIFFOvrCache **) _TIFFmalloc(nOverviews*sizeof(void*));

    for( i = 0; i < nOverviews; i++ )
    {
        int	nOXSize, nOYSize, nOBlockXSize, nOBlockYSize;
        uint32  nDirOffset;

        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);
        }

        nDirOffset = TIFF_WriteOverview( hTIFF, nOXSize, nOYSize,
                                         nBitsPerPixel, nSamples,
                                         nOBlockXSize, nOBlockYSize,
                                         bTiled, nCompressFlag, nPhotometric,
                                         nSampleFormat,
                                         panRedMap, panGreenMap, panBlueMap,
                                         bUseSubIFDs );
        
        papoRawBIs[i] = TIFFCreateOvrCache( hTIFF, nDirOffset );
    }

    if( panRedMap != NULL )
    {
        _TIFFfree( panRedMap );
        _TIFFfree( panGreenMap );
        _TIFFfree( panBlueMap );
    }
    
/* -------------------------------------------------------------------- */
/*      Allocate a buffer to hold a source block.                       */
/* -------------------------------------------------------------------- */
    if( bTiled )
        pabySrcTile = (unsigned char *) _TIFFmalloc(TIFFTileSize(hTIFF));
    else
        pabySrcTile = (unsigned char *) _TIFFmalloc(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,
                                      nSampleFormat, pszResampleMethod );
        }
    }

    _TIFFfree( pabySrcTile );

/* -------------------------------------------------------------------- */
/*      Cleanup the rawblockedimage files.                              */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nOverviews; i++ )
    {
        TIFFDestroyOvrCache( papoRawBIs[i] );
    }

    if( papoRawBIs != NULL )
        _TIFFfree( papoRawBIs );

    TIFFSetWarningHandler( pfnWarning );
}
Exemplo n.º 2
0
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 );
    }
}