<div dir="ltr">(I apologize if this is a repost. I signed up the for the list yesterday and it appeared the first attempt to post was rejected, but I don't know how to be sure.)<div><div class="gmail_quote"><br><div dir="ltr"><div>I am using GDAL through the C++ api.</div><div><br></div><div>I want to be able to read an arbitrary raster file (in particular I'm interested in (geo)tiff files and jpeg2000 files) into an RGB buffer, where each value is a byte.</div><div><br></div><div>I was hoping to see an API like dataset->GetRasterRectToBuffer() that would operate on the image level (not the band level) and would let me specify that my buffer was an RGB byte buffer, and the library would do all the right conversions, regardless of the data type and number of bands of the source file. For instance, the source file could have CMYK bands with float values, and it would still extract correctly to my RGB buffer.</div><div><br></div><div>Looking at: <a href="http://www.gdal.org/gdal_tutorial.html" target="_blank">http://www.gdal.org/gdal_tutorial.html</a></div><div><br></div><div>I'm told that the main API to use to read data in GDAL is RasterIO().</div><div><br></div><div>But I'm scared by RasterIO() because it operates on a band. So that means I already have to do my own logic to determine the number of bands in the source file and map them to bands in my output RBG file. That seems complicated in the general case. It seems like handling all the possibilities of RGB, BGR, CMYK, HSL, etc. is exactly the kind of thing a data abstraction raster library could save you from having to worry about. As I say, I was hoping to find an API that operated at the whole image level, not the band level, and could do whatever is best to get an RGB image from whatever source. Maybe if it's not part of the GDAL library still someone has put together some code to handle arbitrary source image to RBG image mapping?<br></div><div><br></div><div>A lesser question is that I'm confused about the design of RasterIO() itself. I see from its API description that it does a lot of nice conversion as needed:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)">This method allows reading a region of a </span><a href="http://www.gdal.org/classGDALRasterBand.html" title="A single raster band (or channel)." style="color:rgb(70,101,162);font-weight:bold;font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)" target="_blank">GDALRasterBand</a><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)"> into a buffer, or writing data from a buffer into a region of a </span><a href="http://www.gdal.org/classGDALRasterBand.html" title="A single raster band (or channel)." style="color:rgb(70,101,162);font-weight:bold;font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)" target="_blank">GDALRasterBand</a><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)">. It automatically takes care of data type translation if the data type (eBufType) of the buffer is different than that of the </span><a href="http://www.gdal.org/classGDALRasterBand.html" title="A single raster band (or channel)." style="color:rgb(70,101,162);font-weight:bold;font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)" target="_blank">GDALRasterBand</a><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)">. The method also takes care of image decimation / replication if the buffer size (nBufXSize x nBufYSize) is different than the size of the region being accessed (nXSize x nYSize).</span></div></div></blockquote><div><div><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)"><br></span></div><div><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)">But then reading the intro tutorial (</span><a href="http://www.gdal.org/gdal_tutorial.html" target="_blank">http://www.gdal.org/gdal_tutorial.html</a><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)">) I see:</span></div><div><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px;background-color:rgb(251,252,253)"><br></span></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><span style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px">The pData is the memory buffer the data is read into, or written from. It's real type must be whatever is passed as eBufType, such as GDT_Float32, or GDT_Byte. The RasterIO() call will take care of converting between the buffer's data type and the data type of the band. Note that when converting floating point data to integer RasterIO() rounds down, and when converting source values outside the legal range of the output the nearest legal value is used. This implies, for instance, that 16bit data read into a GDT_Byte buffer will map all values greater than 255 to 255, </span><b style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px">the data is not scaled!</b></div></div></blockquote><div><b style="color:rgb(0,0,0);font-family:'Lucida Grande',Verdana,Geneva,Arial,sans-serif;font-size:12px"><br></b></div><div>Not scaling seems really strange to me, and seems to make RasterIO() much less useful. It seems like if I want to get byte values out, I'll need to have code that checks the source data type, then allocates a buffer of that GDALDataType's size, then does the read, then goes through and copies-and-scales each value into my destination RGB buffer, with a different case for handling each GDALDataType. I'm just wondering, since RasterIO() "automatically takes care of data type translation", why it would pin (i.e., destroy) all the data, instead of scaling it. Are 16 bit values pinned to byte values (as in the example the tutorial cites) useful to anyone?</div><div><br></div></div></div></div></div>