Hi Andrew, Even,

On Sat, Sep 17, 2016 at 9:52 PM, Even Rouault <even.roua...@spatialys.com>
wrote:

> 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
>

I am so grateful you asked this question, Andrew.

Even, two follow up questions, one concrete, one more abstract. Is
"crystalized" a state of all raster datasets, no matter the driver, and is
there a method of determining whether the dataset is crystalized? Could
this situation be made less complicated or be made more safe for developers
by splitting the existing update access mode into update-metadata and
update-imagery access modes?

-- 
Sean Gillies
_______________________________________________
gdal-dev mailing list
gdal-dev@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/gdal-dev

Reply via email to