[Gdal-dev] IRasterIO in Dataset

Fu Chen fchen at ne.rsgs.ac.cn
Mon Oct 27 01:35:02 EST 2003


Hi!
I recently use my image browser to look a large image composited of some small rgb ecw file. I find if i access the data band by band, it will be slow by decompress 3 times. Implementing a method which can get 3 bands once a time will enhance the efficience. 
And i find gdaldataset already has a IRasterIO prototype, which i didn't see in former version.

Now i add IRasterIO in ECWDataset and VRTDataset.

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)
    
{
    int iBandIndex; 
    CPLErr eErr = CE_None;
    if (nBandCount == 3 && nBandSpace == 1)
    {
     UINT32 bands[3];
     bands[0] = panBandMap[0]-1;
     bands[1] = panBandMap[1]-1;
     bands[2] = panBandMap[2]-1;
     
        NCSError     eNCSErr;
        eNCSErr = NCScbmSetFileView( hFileView, 
                                 3, bands,
                                 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;
        }
        for( int iScanline = 0; iScanline < nBufYSize; iScanline++ )
        {
     unsigned char *p = (unsigned char *)pData + nLineSpace * iScanline;
            NCScbmReadViewLineBGR(hFileView, p);
 }
    }
    else 
        GDALDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
                               pData, nBufXSize, nBufYSize,
                               eBufType, 
                               nBandCount, panBandMap,
                               nPixelSpace, nLineSpace, nBandSpace);
    return eErr;
}

//=============================================

CPLErr VRTDataset::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)

{

 CPLErr eErr = CE_None;

 if (bMosaic && nBandCount == 3)
 {
  VRTRasterBand* band = (VRTRasterBand*) papoBands[0];
  CPLDebug("VRTDataset::IRasterIO", "totally %d", band->nSources);
  for (int i = 0; i < band->nSources; i++)
  {
   VRTSimpleSource * source = (VRTSimpleSource *)(band->papoSources[i]);

   // The window we will actually request from the source raster band.
   int nReqXOff, nReqYOff, nReqXSize, nReqYSize;
   // The window we will actual set _within_ the pData buffer.
   int nOutXOff, nOutYOff, nOutXSize, nOutYSize;

   if( source->GetSrcDstWindow( nXOff, nYOff, nXSize, nYSize,
    nBufXSize, nBufYSize, 
    &nReqXOff, &nReqYOff, &nReqXSize, &nReqYSize,
    &nOutXOff, &nOutYOff, &nOutXSize, &nOutYSize ) )
   {
    CPLDebug("VRTDataset::IRasterIO", "access %d", i);
    source->poRasterBand->GetDataset()->RasterIO(
     eRWFlag, 
     nReqXOff, nReqYOff, nReqXSize, nReqYSize,
     ((unsigned char *) pData) 
     + nOutXOff * nPixelSpace
     + nOutYOff * nLineSpace, 
     nOutXSize, nOutYSize, 
     eBufType, 
     nBandCount, panBandMap,
     nPixelSpace, nLineSpace, nBandSpace);
   }
  }
 }
 else 
  GDALDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
  pData, nBufXSize, nBufYSize,
  eBufType, 
  nBandCount, panBandMap,
  nPixelSpace, nLineSpace, nBandSpace);
 return eErr;
}

I add a attribute "mosaic" in the element of VRTDataset in vrt file. if mosaic is set to 1, it will permit Dataset IRasterIO bypass VRTRasterBand.
for example
<VRTDataset rasterXSize="43200" rasterYSize="21600" mosaic="1">

With this change, my program run much quickly :)
I hope this code will benefit other people. But I am not familiar about CVS , so I post here.
Frank, would you like to envaluate my code and merge them in the CVS?



More information about the Gdal-dev mailing list