Opened 11 years ago

Closed 11 years ago

Last modified 10 years ago

#4679 closed defect (fixed)

NODATA value is only used in the first overview for paletted rasterband (AVERAGE algorithm)

Reported by: ralcazar Owned by: warmerdam
Priority: normal Milestone: 1.10.0
Component: GDAL_Raster Version: 1.9.0
Severity: normal Keywords: overview palette average nodata
Cc:

Description

I have a NTIF raster with a RGB palette, and with NODATA value. The gdalinfo output is

Driver: RPFTOC/Raster Product Format TOC format .... Size is 50688, 6144 .... Band 1 Block=128x128 Type=Byte, ColorInterp=Palette

NoData Value=216 Color Table (RGB with 217 entries)

0: 3,17,168,255 1: 247,243,243,255 2: 0,0,0,255

...

216: 0,0,0,0

(the raster has 13 subdatasets, and the problem happens in all subdatasets. I do the testing with the first one).

When I try to generate the overviews using the "AVERAGE" algorithm (when there are 0 overviews), the NODATA value is used in the first overview (the one with size 25344x3072), that is, the overview data contains the entry "216" for those pixels that are NODATA. Perfect

However all other overviews (sizes 12672x1536, 6336x768, 3168x384, etc.) do not provide the entry "216" for the pixels in the NODATA area as I would expect, but instead they provide the value "2".

The consecuence of this error is that I am getting black values (entry #2) instead of NODATA mark.

After debugging gdal code, I think there is something wrong in the manner how the NODATA value is managed when building overviews. The NODATA value is obtained from the previous band. (overview.cpp, line 1659: fNoDataValue = (float) poSrcBand->GetNoDataValue(&bHasNoData);) This only works properly for the first overview because the "previous band" is the actual data.

When the first overview is finished, the NODATA values is not stored in any place of the first overview. When building the second overview as it will try to retrieve the NODATA value from the first overview, it will get bHasNoData as FALSE and fNoDataValue as -1e10.

Later in the average code, as it has no NODATA value, it will get the "best entry" from the palette (overview.cpp, line 454: pDstScanline[iDstPixel] = (T)iBestEntry;). (see http://trac.osgeo.org/gdal/ticket/2408)

In my case the best entry is the 2 instead of the 216, that explains the black color.

In the case of the first overview, as the NODATA value is properly configured, the correct code is executed: (File overview.cpp. line 436): pDstScanline[iDstPixel] = tNoDataValue;

There are two possible solutions to this: 1) When processing an overview, store the NODATA value in the band so it can be used in future levels 2) Only read the NODATA value from the raster source band once, instead of reading it for every overview. For me this is the simplest one.

PD: My code for invoking the overview creation is:

Create overviews, if they are not already in the file. if (overviewsCount == 0) {

Ignore errors if the overview building fail #define OVERVIEWS_LEVEL_COUNT 10 int levels[OVERVIEWS_LEVEL_COUNT] = { 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 }; CPLErr err = gdalDataset->BuildOverviews(

"AVERAGE", Overview algorithm: one of "NEAREST", "GAUSS", "AVERAGE", "AVERAGE_MAGPHASE" or "NONE" controlling the downsampling method applied. OVERVIEWS_LEVEL_COUNT, levels, How many overviews do we want (array size + array of 2-powers) 0,NULL, Control to which bands are the overviews applied (all in our case) (GDALProgressFunc)GDALBuildOverviewsProgress, buildOverviewProgress Progress function );

if (err != CE_None) {

return true;

}

}

Change History (2)

comment:1 by Even Rouault, 11 years ago

Milestone: 2.0.0
Resolution: fixed
Status: newclosed

Good analysis. I fixed it a bit differently in gt_overview.cpp in setting the nodata value when building the overview bands.

r24525 /trunk/ (autotest/gcore/tiff_ovr.py gdal/frmts/gtiff/gt_overview.cpp): Set nodata value when creating external overviews so that AVERAGE algorithm works as expected (#4679)

comment:2 by ralcazar, 10 years ago

Just tested your change with my raster files and it works as expected now!

Many thanks!

Note: See TracTickets for help on using tickets.