- 2007.09.12 15:01 "Re: [Tiff] SIZEOF_UNSIGNED_LONG", by Frank Warmerdam
- 2007.09.19 13:23 "[Tiff] New Beta Cut?", by Frank Warmerdam
- 2007.09.20 21:03 "[Tiff] libtiff4, and the size of STRIPOFFSETs and TILEOFFSETs", by Frank Warmerdam
- 2007.10.18 14:47 "Re: [Tiff] linking in MS Visual Studio 2005", by Jason Tillett
2007.08.24 21:08 "[Tiff] A few libtiff4 changes", by Frank Warmerdam
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@pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush | President OSGeo, http://osgeo.org