[Gdal-dev] IRasterIO in Dataset

Frank Warmerdam warmerdam at pobox.com
Mon Oct 27 09:05:04 EST 2003


Fu Chen,

I have completed implementation of a "safe" IRasterIO() for ECWDataset
and checked it in.  This slightly more than doubles the speed of reading
large 3 band files with a single dataset level rasterio.

Best regards,

-- 
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Programmer for Rent


/************************************************************************/
/*                             IRasterIO()                              */
/************************************************************************/

CPLErr ECWDataset::IRasterIO( GDALRWFlag eRWFlag,
                              int nXOff, int nYOff, int nXSize, int nYSize,
                              void * pData, int nBufXSize, int nBufYSize,
                              GDALDataType eBufType,
                              int nBandCount, int *panBandMap,
                              int nPixelSpace, int nLineSpace, int nBandSpace)

{
/* -------------------------------------------------------------------- */
/*      If we are supersampling we need to fall into the general        */
/*      purpose logic.  We also use the general logic if we are in      */
/*      some cases unlikely to benefit from interleaved access.         */
/*                                                                      */
/*      The one case we would like to handle better here is the         */
/*      nBufYSize == 1 case (requesting a scanline at a time).  We      */
/*      should eventually have some logic similiar to the band by       */
/*      band case where we post a big window for the view, and allow    */
/*      sequential reads.                                               */
/* -------------------------------------------------------------------- */
    if( nXSize < nBufXSize || nYSize < nBufYSize || nYSize == 1
        || nBandCount > 100 || nBandCount == 1 || nBufYSize == 1 )
    {
        return
            GDALDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
                                    pData, nBufXSize, nBufYSize,
                                    eBufType,
                                    nBandCount, panBandMap,
                                    nPixelSpace, nLineSpace, nBandSpace);
    }

    CPLDebug( "ECWDataset",
              "RasterIO(%d,%d,%d,%d -> %dx%d) - doing interleaved read.",
              nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize );

/* -------------------------------------------------------------------- */
/*      Setup view.                                                     */
/* -------------------------------------------------------------------- */
    UINT32 anBandIndices[100];
    int    i;
    NCSError     eNCSErr;

    for( i = 0; i < nBandCount; i++ )
        anBandIndices[i] = panBandMap[i] - 1;

    eNCSErr = NCScbmSetFileView( hFileView,
                                 nBandCount, anBandIndices,
                                 nXOff, nYOff,
                                 nXOff + nXSize - 1,
                                 nYOff + nYSize - 1,
                                 nBufXSize, nBufYSize );

    if( eNCSErr != NCS_SUCCESS )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "%s", NCSGetErrorText(eNCSErr) );

        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Setup working scanline, and the pointers into it.               */
/* -------------------------------------------------------------------- */
    GByte *pabyBILScanline = (GByte *) CPLMalloc(nBufXSize * nBandCount);
    GByte **papabyBIL = (GByte **) CPLMalloc(nBandCount * sizeof(void*));

    for( i = 0; i < nBandCount; i++ )
        papabyBIL[i] = pabyBILScanline + i * nBufXSize;

/* -------------------------------------------------------------------- */
/*      Read back all the data for the requested view.                  */
/* -------------------------------------------------------------------- */
    for( int iScanline = 0; iScanline < nBufYSize; iScanline++ )
    {
        NCSEcwReadStatus  eRStatus;
        int  iX;

        eRStatus = NCScbmReadViewLineBIL( hFileView, papabyBIL );
        if( eRStatus != NCSECW_READ_OK )
        {
            CPLFree( pabyBILScanline );
            CPLError( CE_Failure, CPLE_AppDefined,
                      "NCScbmReadViewLineBIL failed." );
            return CE_Failure;
        }


        for( i = 0; i < nBandCount; i++ )
        {
            GByte *pabyThisLine = ((GByte *)pData) + nLineSpace * iScanline +
nBandSpace * i;

            for( iX = 0; iX < nBufXSize; iX++ )
                pabyThisLine[iX * nPixelSpace] =
                    pabyBILScanline[i * nBufXSize + iX];
        }
    }

    CPLFree( papabyBIL );
    CPLFree( pabyBILScanline );

    return CE_None;
}





More information about the Gdal-dev mailing list