[Gdal-dev] featureDataset->RasterIO efficient pixel value reading question

Frank Warmerdam fwarmerdam at gmail.com
Wed Jan 19 00:04:10 EST 2005


On Tue, 18 Jan 2005 22:24:30 CST, Andrew Finley <afinley at gis.umn.edu> wrote:
> Hi Frank,
> Some time ago, you helped me out with some code to speed up multi-band
> image pixel value access.  I was using rasterIO to read one pixel at a
> time.  You suggested the code below to grab a larger block (xsize*bands):
> 
>   // Make sure that lineBuf holds one whole line of data.
>   float *lineBuf;
>   int  xsize = featureDataset->GetRasterXSize();
>   int  ysize = featureDataset->GetRasterYSize();
>   int  bandCount = featureDataset->GetRasterCount();
> 
>   lineBuf = (float *) CPLMalloc(xsize * bandCount);
> 
>   //every row loop
>   for (int row = 0; row < featureDataset->GetRasterYSize(); row++){
>       featureDataset->RasterIO( GF_Read, 0, row, xsize, 1,
>                                 lineBuf, xsize, 1, GDT_Float32,
>                                 bandCount, NULL,
>                                 4 * bandCount, 0, 4 );

Andy,

The last 3 arguments are the pixeloffset, line offset and 
band offset.  In the above case the buffer is "pixel interleaved",
that is if there were 2 bands we would have the values as 
<band1_pixel1> <band2_pixel1> <band1_pixel2> <band2_pixel2>...

The pixel offset is 4*bandCount because when moving from one pixel
to the next for a bandcount bytes (4 is for the size of float).   The line 
offset is 0 because we are operating on one line at a time so we don't
need to set this with a meaningful value since we will never be
advancing a scanline within a call.  The band offset is 4 because 
the second band starts 4 bytes after the place where the first band
starts.

I'm really bad at explaining this, but i hope the above helps.

>       // every pixel in row.
>       for (int col = 0; col < featureDataset->GetRasterXSize(); col++){
>           float *targetBandVec = lineBuf + col;
>           ... perform classification ..
>       }
>   }
> 
> I'm having some trouble understanding the parameters that go into
> featureDataset rasterIO and how it packs the data into the row lineBuf.
> What are the values of 4 you put in the RasterIO above?  Could you take me
> one step further in the above example, so I can see how the pixel bands are
> layed out in the lineBuf.  I took a shot below:
> 
>  // Make sure that lineBuf holds one whole line of data.
>   float *lineBuf;
>   int xsize = featureDataset->GetRasterXSize();
>   int ysize = featureDataset->GetRasterYSize();
>   int bandCount = featureDataset->GetRasterCount();
>   lineBuf = (float *) CPLMalloc(sizeof(float)*xsize*bandCount);
> 
>   //every row loop
>   for (int row = 0; row < featureDataset->GetRasterYSize(); row++){
>     featureDataset->RasterIO( GF_Read, 0, row, xsize, 1, lineBuf, xsize, 1,
> GDT_Float32, bandCount, NULL, 4 * bandCount, 0, 4 );
> 
>     //every pixel in row.
>     for (int col = 0; col < featureDataset->GetRasterXSize(); col++){
>       float *targetBandVec = lineBuf + col;

The above should read "lineBuf + col*bandCount" so that as you
advance one pixel you skip all the band values for the previous
pixel.

>       //every band value in pixel (i.e., each cout row is a pixel and row
> elements are specific band values in that pixel)
>       //I know this part is wrong.
> 
>         for(int band = 0; band < bandCount; band++)
>           cout << targetBandVec[band] <<" ";
>         cout << endl;

The above is fine as long as you compute the targetBandVec
properly.

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



More information about the Gdal-dev mailing list