[gdal-dev] Writing descriptions to GeoTiff bands

Even Rouault even.rouault at spatialys.com
Sat Sep 17 12:52:12 PDT 2016


Le vendredi 16 septembre 2016 23:11:07, Even Rouault a écrit :
> Le vendredi 16 septembre 2016 22:57:13, Andrew Bell a écrit :
> > Hi,
> > 
> > My code for creating a Tiff raster looks something like this:
> > 
> > int nBands = 5;
> > dataset->Create(filename, width, height, nBands, ...);
> > 
> > for (int i = 1; i <= nBands; ++i)
> > {
> > 
> >     GDALRasterBand *band = dataset->GetRasterBand(i);
> >     band->SetDescription(someString);
> >     band->WriteBlock(someData);
> > 
> > }
> > 
> > It appears that only the description to band 1 is written (it's the only
> > one reported by gdalinfo).  A little debugging leads me to believe that
> > what's happening is that WriteBlock() invokes Crystalize() ->
> > WriteMetadata(), which takes care of setting the band description.  But
> > once Crystalize() is called, it sets a flag so as to be a NOOP in future
> > calls.  I'm not using streaming.
> > 
> > I'm trying to understand if this behavior is by design, a limitation that
> > I can't find in the documentation or a bug.
> 
> It's a limitation due to how libtiff works mostly and/or how we use it (but
> mostly how libtiff works, and a bit how the TIFF format itself makes it
> hard). Basically for GTiff, you need to do all operations that affect
> metadata, in a broad meaning, ie georeferencing, description, offsets,
> color table, TIFF & GDAL metadata, etc... before writing any imagery.  If
> we allowed to change metadata after crzystalization, this would require
> rewriting the whole set of TIFF tags at the end of file each time their
> serialized form increase.
> 
> So rewrite your loop into 2: one to set all descriptions, and another one
> to write blocks.
> 
> Other formats may have similar limitations, so it is generally safe to
> proceed this way in general.

Actually the above is partly true & wrong. It is indeed discouraged to change 
metadata after having started writting imagery, but in the case of the band 
description, you can still do it. As I said this will cause the TIFF directory 
to be rewritten, so a bit of storage loss, but nevertheless the descriptions 
are then correctly retrieved.

I used the following Python test script

{{{
from osgeo import gdal
gdal.SetCacheMax(0) # to force Fill() to commit to file immediatly
ds = gdal.GetDriverByName('GTiff').Create('test.tif', 1000, 1000, 5)
for i in range(5):
    ds.GetRasterBand(i+1).SetDescription('foo%d' % i)
    ds.GetRasterBand(i+1).Fill(100)
}}}

Works on latest state of trunk , 2.1 and 2.0 branches


-- 
Spatialys - Geospatial professional services
http://www.spatialys.com


More information about the gdal-dev mailing list