[Gdal-dev] Writing bit interleaved datawith GDALRasterBand::RasterIO

Alain Rist ar at navpoch.com
Wed Jul 7 18:43:53 EDT 2004


Martin,

Just use the code in reverse flow.
Change GF_Read to GF_Write , CreateDIBSection to GetDIBits and get the
dimensions from your DIB.

Alain

 ----- Original Message ----- 
From: "Chapman, Martin" <MChapman at sanz.com>
To: "Alain Rist" <ar at navpoch.com>; "gdal-dev" <gdal-dev at remotesensing.org>
Sent: Wednesday, July 07, 2004 9:20 PM
Subject: RE: [Gdal-dev] Writing bit interleaved datawith
GDALRasterBand::RasterIO


Alain,

Thank you very much for the code, but I am trying to write a dib section
out to a raster file rather than read into a dib section.  I was
wondering if the rasterio() function could handle the data in pixel
interleave versus band interleave.  That way I could just save contents
from the dib section directly into the rasterio() function without
having to take the extra time to reformat the interleaving to be band
interleave.  Frank said that's what the nPixelSpace and nLineSpace
params are for.  Do you have code that can do that?

Thanks again,
Martin

-----Original Message-----
From: Alain Rist [mailto:ar at navpoch.com]
Sent: Wednesday, July 07, 2004 11:11 AM
To: gdal-dev
Cc: Chapman, Martin
Subject: Re: [Gdal-dev] Writing bit interleaved datawith
GDALRasterBand::RasterIO


Hi Martin,
This is what I wrote for GDALView.
Hope it helps.

Alain

----- Original Message ----- 
From: "Chapman, Martin" <MChapman at sanz.com>
To: "Frank Warmerdam" <warmerdam at pobox.com>
Cc: "gdal-dev" <gdal-dev at remotesensing.org>
Sent: Wednesday, July 07, 2004 6:35 PM
Subject: RE: [Gdal-dev] Writing bit interleaved datawith
GDALRasterBand::RasterIO


Frank,

I'm not sure if I mean byte or pixel interleave.  I want to save data
the I have in a windows DIB.  When I create the DIB from a gdal dataset
I interleave the bits into the following structure something like
this...

unsigned char* pCombinedBytes = (unsigned char*)
CPLMalloc(sizeof(unsigned char) * nWidth * nHeight * nSize); //Where
nSize is the number of bands and nWidth and nHeight is the aoi w and
h...

//then I retrieve the bytes for each band something like this...

void** pBandBuffer = (void**) new unsigned char*[nSize];
//for each band
pBandBytes = (unsigned char*) CPLMalloc(sizeof(unsigned char) * nWidth *
nHeight);
pBand->RasterIO(GF_Read, nXOffset, nYOffset, nWidth, nHeight,
pBandBytes, nWidth , nHeight, GDT_Byte, 0, 0);
pBandBuffer[n] = pBandBytes;
//end if

// then I interleave the bytes into one array...

for (long i = 0, long j = 0; i < (nWidth * nHeight * nSize); i += nSize,
j++)
{
int k = i;

for (int m = nSize - 1; m >= 0; m--, k++)
{
unsigned char* pBytes = (unsigned char*) pBandBuffer[m]; ptr_dest =
pCombinedBytes + k; unsigned char b = pBytes[j];

if (pCT != NULL)
{
GDALColorEntry ce;
unsigned int c = (unsigned int) b;
c = pCT->GetColorEntryAsRGB(c, &ce);
if (m == 0) c = ce.c1;
if (m == 1) c = ce.c2;
if (m == 2) c = ce.c3;
b = (unsigned char) c;
}

ptr_src = &b;
memcpy(ptr_dest, ptr_src, 1);
}
}

// then I realign the bytes for a windows DIB...

m_pDIBSection->Create(nWidth ,nHeight, 24);
unsigned int dibwidth = m_pDIBSection->GetTotalWidth();

GByte* dest = (GByte*) m_pDIBSection->GetBits();
GByte* src = (GByte*) pCombinedBytes;

for (int row = 0; row < nHeight; row++)
{
ptr_dest = dest + row * dibwidth * nSize;
ptr_src = src + row * nWidth * nSize;
memcpy(ptr_dest, ptr_src, nWidth * nSize);
}

So I think I am pixel interleaving then?  Anyway, I think the example
you sent me will work if I undo the windows DIB realignment, (which
would be really cool).  I'll let you know if it works.

Thanks for the quick response.

Martin

-----Original Message-----
From: Frank Warmerdam [mailto:warmerdam at pobox.com]
Sent: Wednesday, July 07, 2004 10:02 AM
To: Chapman, Martin
Cc: gdal-dev
Subject: Re: [Gdal-dev] Writing bit interleaved data with
GDALRasterBand::RasterIO


Chapman, Martin wrote:
> All,
>
> If I have raster data stored as bit interleaved
> (r,g,b,r,g,b,r,g,b...), can I use the GDALRasterBand::RasterIO
> function to write this data to disc?  I read that the nPixelSpace and
> nLineSpace parameters allow reading into or writing from unusually
> organized buffers.  If this is possible, could someone please provide
> me a brief example of how to
use
> these parameters with this type of data structure?

Martin,

Do you literally mean bit interleaved?  Or pixel interleaved?

I'll assume you mean pixel interleaved.   To write from a pixel
interleaved
1 line buffer of 8bit data you might use:

poBandRed->RasterIO( GF_Write, 0, line, xsize, 1,
                      pabyRGB + 0, xsize, 1, GDT_Byte,
                      3, xsize * 3 );

poBandGreen->RasterIO( GF_Write, 0, line, xsize, 1,
                      pabyRGB + 1, xsize, 1, GDT_Byte,
                      3, xsize * 3 );
poBandBlue->RasterIO( GF_Write, 0, line, xsize, 1,
                      pabyRGB + 2, xsize, 1, GDT_Byte,
                      3, xsize * 3 );

Note that the buffer pointer you pass in needs to point to the beginning
of the data to be written (hence the +1 and +2 offsets on pabyRGB for
green and blue).  The nPixelSpace is the number of bytes from the
beginning of one pixel to the beginning of the next.  3 in this case
since there are 3 bytes of data for for each pixel written.  The
linespacing is the offset from the beginning of one line to the next, so
xsize * 3 in this case.

I hope this helps. If your data is really "bit" interleaved you will
need to repack stuff before writing.

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

_______________________________________________
Gdal-dev mailing list
Gdal-dev at xserve.flids.com
http://xserve.flids.com/mailman/listinfo/gdal-dev







More information about the Gdal-dev mailing list