[Gdal-dev] C# Bindings
sy at perkins.net
Sun Nov 5 12:47:04 EST 2006
Frank Warmerdam wrote:
>> So how does this work? i.e. where does the unmanaged buffer that
>> GDALRasterIO initially reads into get allocated? In C code somewhere?
>> Or is there some way of getting an IntPtr pointing to an allocated
>> buffer in C#? And then you copy it into a C# array in some CS code?
>> And then switch back to C to free the unmanaged memory? And you can
>> do all this without using the unsafe keyword? Guess it'll be easier
>> to visualize it when you've written it.
> Tamas just did "IntPtr buf = bitmapData.Scan0". I assumed Scan0 was
> a buffer in the bitmapData object, and that it was previously allocated.
> So there is no apparent copying of the buffer, or allocation within
> the rasterio. I could be missing lots of stuff though.
I think we're talking about two different things here. Tamas and I have
no disagreement over the "low level" version of the Read/WriteRaster()
method that uses an IntPtr and a GDALDataType flag (which corresponds
very closely to the original C GDALRasterIO() function). As you say,
this involves no copying. However, the question is how to provide more
typesafe versions of this method that allow one to read directly into
arrays of bytes, ints, and so on. If I understand correctly, Tamas has
proposed a solution that involves invoking the low level
Read/WriteRaster() method to read/write data from/into an intermediate
buffer, and then to copy the data from there to the array. I prefer a
solution that uses the "fixed" keyword to read/write data directly
from/to the buffer without any intermediate copying. The drawback to
this is that the method would have to be declared with the "unsafe"
keyword, and code using this method would have to be compiled with the
/UNSAFE flag. So that's the tradeoff: efficiency vs. /UNSAFE. My
personal feeling is that in reality, both methods are equally "unsafe"
in the C# sense, so I don't mind using the /UNSAFE flag. But I can also
see Tamas' point of view that this is aesthetically less appealing.
Anyone else have any opinons on this?
>> For convenience, it would be nice to have overloads that assume
>> default values for the last three parameters (bufferOffset,
>> pixelSpace and lineSpace) for the common case where we're not dealing
>> with packed buffers. In these cases, bufferOffset = 0, pixelSpace =
>> sizeof(datatype), and lineSpace = bufXSize * pixelSpace.
> The default should be all zeros and then values are computed internally.
> This should already be documented in the rasterio docs.
Yes, that would be the sensible way to do it. I was just trying to be
explicit about what the zero defaults are actually equivalent to.
> By the way, if there is a way of doing pointer arithmetic with the
> IntPtr, then I think you should avoid this BufOffset idea. It seems
> like a hack to me.
The pointer arithmetic with IntPtr() is a bit ugly. You have to do
something like "new IntPtr(ptr.ToInt64() + 1)" to get a pointer one
greater than ptr, for instance. I thought that the bufferOffset would be
a neat way of hiding this.
But more significantly, if we're going to have versons of
Read/WriteRaster() that use arrays as buffers, then you can't do pointer
arithmetic with the array variable. So the only way to work with packed
pixel buffer formats (i.e. "pixel interleaved" / BIP formats) is to
specify a bufferOffset. What do you think?
More information about the Gdal-dev