[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