Opened 15 years ago
Closed 15 years ago
#3073 closed defect (fixed)
[PATCH - C#] Dataset.ReadRaster()/WriteRaster() doesn't work on multi-band datasets
Reported by: | Even Rouault | Owned by: | tamas |
---|---|---|---|
Priority: | normal | Milestone: | 1.6.2 |
Component: | CSharpBindings | Version: | 1.6.1 |
Severity: | normal | Keywords: | |
Cc: | amanda.m.henneke@… |
Description
Tamas,
The Marshal.AllocHGlobal and Marshal.Copy calls in Dataset.ReadRaster()/WriteRaster() mainly forget to multiply the pixel count by the number of bands, thus only the data for the first band is correctly read/written for pixel-interleaved buffers. Attached a patch that fixes the issue (adapted from gdal_java.i). I've also better taken into account the pixelSpace, lineSpace and bandSpace parameters to compute the number of elements to copy, as done in BandRasterIO_Validate and DatasetRasterIO_Validate in gdal_java.i. Currently, this wouldn't work with exotic values of spacings.
With that patch, the following code snippet does produce a pink image :
using System; using OSGeo.GDAL; class test { public static void Main(string[] args) { Gdal.AllRegister(); Driver drv = Gdal.GetDriverByName("GTiff"); int iWidth = 100; int iHeight = 100; Dataset ds_new = drv.Create("testrgb.tif", iWidth, iHeight, 3, DataType.GDT_Byte, new string[] { }); byte[] buffers = new byte[(iHeight * iWidth) * 3]; int i, j; for(i=0;i<iHeight;i++) { for(j=0;j<iWidth;j++) { buffers[(i*iWidth+j)] = 255; buffers[100*100+(i*iWidth+j)] = 0; buffers[2*100*100+(i*iWidth+j)] = 255; } } int[] iBandMap = { 1, 2, 3 }; ds_new.WriteRaster(0, 0, iWidth, iHeight, buffers, iWidth, iHeight, 3, iBandMap, 0, 0, 0); ds_new = null; } }
Attachments (1)
Change History (5)
by , 15 years ago
Attachment: | patch_3073.patch added |
---|
comment:1 by , 15 years ago
Status: | new → assigned |
---|
comment:2 by , 15 years ago
yes, it would be good if the count estimation could be moved in something common to all bindings. Would be usefull for C# and Java bindings. Python bindings don't need it as they don't provide the spacing parameters. Not sure about other bindings.
comment:3 by , 15 years ago
I've applied a fix to use GC pinned arrays instead of the double copy in r17453, which should make the IO faster and fix this problem as well. If the change seems OK than I'll backport it into the stable branch.
comment:4 by , 15 years ago
Milestone: | → 1.6.2 |
---|---|
Resolution: | → fixed |
Status: | assigned → closed |
It has been backported in branches/1.6 in r17475. So the issue is closed.
I've also moved code used in the Java bindigns to check that the buffer provided by the user is large enough taking into account the buffer width and height and the spacing parameters. This could be used now by the C# bindings. See r17455 and the ComputeBandRasterIOSize() / ComputeDatasetRasterIOSize() methods
Even,
Thank you for showing this up. I'd wonder if that count estimation would be done somewhere at gdal level as it looks like we implement something similar at the target languages. I'm still working on fixing this issue by using a direct copy on GC pinned arrays instead of doing the double copy like now. If the GC pinned array approach doesn't work on all systems (MS.NET/MONO) then I'll apply your patch to fix this issue.
Tamas