static void TIFFWriteOvrRow( TIFFOvrCache * psCache )

{
    int		nRet, iTileX, iTileY = psCache->nBlockOffset;
    unsigned char *pabyData;
    uint32	nBaseDirOffset;
    uint32 RowsInStrip;

/* -------------------------------------------------------------------- */
/*      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 );
					RowsInStrip=psCache->nBlockYSize;
					if ((iTileY+1)*psCache->nBlockYSize>psCache->nYSize)
						RowsInStrip=psCache->nYSize-iTileY*psCache->nBlockYSize;
					TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,
					    pabyData,
					    TIFFVStripSize(psCache->hTIFF,RowsInStrip) );
				}
			}

		}
		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 );
				RowsInStrip=psCache->nBlockYSize;
				if ((iTileY+1)*psCache->nBlockYSize>psCache->nYSize)
					RowsInStrip=psCache->nYSize-iTileY*psCache->nBlockYSize;
				TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,
				    pabyData,
				    TIFFVStripSize(psCache->hTIFF,RowsInStrip) );
			}
		}
	}
	/* TODO: add checks on error status return of TIFFWriteEncodedTile and TIFFWriteEncodedStrip */

/* -------------------------------------------------------------------- */
/*      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 );
    /* TODO: add checks on error status return of TIFFFlush */
    TIFFSetSubDirectory( psCache->hTIFF, nBaseDirOffset );
    /* TODO: add checks on error status return of TIFFSetSubDirectory */
}
Exemplo n.º 2
0
void TIFF_ProcessFullResBlock( TIFF *hTIFF, int nPlanarConfig,
                               int nOverviews, int * panOvList,
                               int nBitsPerPixel, 
                               int nSamples, TIFFOvrCache ** papoRawBIs,
                               int nSXOff, int nSYOff,
                               unsigned char *pabySrcTile,
                               int nBlockXSize, int nBlockYSize,
                               int nSampleFormat, const char * pszResampling )
    
{
    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++ )
        {
            TIFFOvrCache *poRBI = papoRawBIs[iOverview];
            unsigned char *pabyOTile;
            int	nTXOff, nTYOff, nOXOff, nOYOff, nOMult;
            int	nOBlockXSize = poRBI->nBlockXSize;
            int	nOBlockYSize = poRBI->nBlockYSize;
            int	nSkewBits, nSampleByteOffset; 

            /*
             * Fetch the destination overview tile
             */
            nOMult = panOvList[iOverview];
            nOXOff = (nSXOff/nOMult) / nOBlockXSize;
            nOYOff = (nSYOff/nOMult) / nOBlockYSize;
            pabyOTile = TIFFGetOvrBlock( poRBI, nOXOff, nOYOff, iSample );
                
            /*
             * 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->nBlockXSize, poRBI->nBlockYSize,
                             nTXOff, nTYOff,
                             nOMult, nSampleFormat, pszResampling );
#ifdef DBMALLOC
            malloc_chain_check( 1 );
#endif            
        }
    }
}