[Gdal-dev] A few libtiff4 changes

Frank Warmerdam warmerdam at pobox.com
Fri Aug 24 17:08:52 EDT 2007


Joris / Andrey,

I made a few changes in libtiff4 to get GDAL overview and multi-directory
support working smoothly again.  These changes are now all in CVS.

This change just added a runtime check for a check that was
only an assertion before.  I don't know if it is strictly useful,
but it seemed prudent.

Index: tif_dirread.c
===================================================================
RCS file: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dirread.c,v
retrieving revision 1.129
diff -r1.129 tif_dirread.c
4504a4505,4511
 >         if( fii == 0xFFFFFFFF )
 >         {
 >             TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag",
 >                          "No definition found for tag %d",
 >                          dp->tdir_tag);
 >             return 0;
 >         }

This change, in _TIFFMergeFields() handled the case where a field
is defined that was already defined.  Previously an error was issued
and no fields were defined in the call.  This change only merges in
field definitions for which a definition does not already exist.
Duplicates are silently ignored.  Without this it seemed that any
multi-directory file was resulting in terrible redefinition warnings
even just with tiffinfo.

diff -r1.94 tif_dirinfo.c
333,344d332
<       for (i = 0; i < n; i++) {
<               const TIFFField *fip =
<                       TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
<               if (fip) {
<       for (i = 0; i < n; i++) {
<               const TIFFField *fip =
<                       TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
<               if (fip) {
<                       TIFFErrorExt(tif->tif_clientdata, module,
<                       "Field with tag %lu is already registered as \"%s\"",
<                                    (unsigned int) info[i].field_tag,
<                                    fip->field_name);
<                       return 0;
<               }
<       }
<
361a350
 >
363,364c352,361
<       for (i = 0; i < n; i++)
<               *tp++ = (TIFFField *) (info + i);       /* XXX */
---
 >       for (i = 0; i < n; i++) {
 >               const TIFFField *fip =
 >                       TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
 >
 >                 /* only add definitions that aren't already present */
 >               if (!fip) {
 >                         tif->tif_fields[tif->tif_nfields] = (TIFFField *) (inf
o+i);
 >                         tif->tif_nfields++;
 >                 }
 >       }
367c364
<       qsort(tif->tif_fields, tif->tif_nfields += n,
---
 >       qsort(tif->tif_fields, tif->tif_nfields,

This change is the "real beef" I needed for GDAL.  GDAL's overview writer
creates directories for several directories for overviews, then goes back
and generates the imagery and updates the strip/tile pointers and rewrites
the directory.  The TIFFWriteDirectory() function was always writing a
"zero" next pointer instead of writing an existing valid next pointer back.
This change makes it possible to read a directory in the middle of the
chain, change something (hopefully not changing the size of the directory!)
and then write it back without disrupting the chain.

diff -r1.56 tif_dirwrite.c
784c784
<               *(uint32*)n=0;
---
 >               *(uint32*)n = tif->tif_nextdiroff;
814c814
<               *(uint64*)n=0;
---
 >               *(uint64*)n = tif->tif_nextdiroff;

With these changes GDAL overview generation seems to work fine, and in
fact the full GDAL test suite passes.  I am now inclined to migrate
libtiff4 into GDAL as it's primary working version.

Best regards,
-- 
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | President OSGeo, http://osgeo.org




More information about the Gdal-dev mailing list