AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
November 2003

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2003.11.17 00:45 "TIFF, v3.6.0. Fetching "custom" tags", by Chris Losinger
2003.11.17 14:23 "TIFF, v3.6.0. Fetching "custom" tags", by Frank Warmerdam
2003.11.17 15:16 "TIFF, v3.6.0. Fetching "custom" tags", by Andrey Kiselev
2003.11.17 16:07 "TIFF, v3.6.0. Fetching "custom" tags", by Frank Warmerdam
2003.11.17 16:26 "TIFF, v3.6.0. Fetching "custom" tags", by Andrey Kiselev
2003.11.18 02:13 "TIFF, v3.6.0. Fetching "custom" tags", by Ross Finlayson
2003.11.18 06:59 "TIFF, v3.6.0. Fetching "custom" tags", by Ross Finlayson
2003.11.18 15:05 "TIFF, v3.6.0. Fetching "custom" tags", by Ross Finlayson

2003.11.18 15:05 "TIFF, v3.6.0. Fetching "custom" tags", by Ross Finlayson

Going back to the _TIFFextender variables, _TIFFextender is the 
identifier of a static variable declared in tif_dir.c.  It is defined as 
a TIFFExtendProc.  The TIFFDefaultDirectory function calls the non-null 
function pointer installed at the _TIFFextender static variable.  The 
TIFFExtendProc function pointer is installed in the _TIFFextender static 
(global) variable using the TIFFSetTagExtender function.

Then, the user implementation of the TIFFExtendProc function that is 
patched into the _TIFFextender static variable, when it is called by the 
TIFFDefaultDirectory function, may call TIFFMergeFieldInfo on whatever 
private or "custom" tags that it wants to to be handled by TIFFGetField 
and TIFFSetField.  It can also call other functions on the TIFF pointer.

A problem with this is that the _TIFFextender function is called each 
time the TIFFDefaultDirectory function is called, where if the 
_TIFFextender function is to be used for adding the custom tag 
definitions that it would be called multiple times as directories were 
added from TIFFCreateDirectory calling TIFFDefaultDirectory.  The 
TIFFFieldInfo and the nfields members are of the TIFF struct, not the 
TIFFDirectory struct.

Perhaps a better place for _TIFFextender to be called would be in 
TIFFClientOpen.
The Nota Bene in _TIFFFindFieldInfo suggest that as the table of 
TIFFFieldInfo pointers grows that it would be more efficient to use 
binary search instead of plain search.  The list of TIFFFieldInfo 
pointers is already sorted by _TIFFMergeFieldInfo.  I turn to a C book 
around here and read about bsearch, I think it can use the same compare 
function as qsort, and is also defined in stdlib.h.  Yet, 
_TIFFFiindFieldInfo should return the TIFFFieldInfo struct with the 
greatest precision width, and specification is by the tag.  The bsearch 
can be implemented when the data type is not TIFF_ANY.  It could be 
implemented for all but I don't know if bsearch is stable.

if(dt != TIFF_ANY){
	const TIFFFieldInfo key={tag, 0, 0, dt, 0, 0, 0, 0};
	return( (const TIFFFieldInfo *) bsearch(
			&key,
			tif->tif_fieldinfo,
			tif->tif_nfields,
			sizeof(TIFFFieldInfo),
			tagCompare);
}

Now the problem with that is that tagCompare doesn't return zero if the 
tag and data type of the TIFFFieldInfo are equal.

I'd modify line 311 of tagCompare from "return(tb->field_type < 
ta->field_type ? -1 : 1)" to "return(tb->field_type - ta->field_type)", 
yet TIFFDataType is an enum.  As enum is unsigned, maybe, 
"return((int)tb->field_type - (int)ta->field_type)".  Hopefully, that 
won't slow the compare function to a crawl or be worthless for 99% of 
the cases.

So anyways if the _TIFFextender function is to be used to add private or 
custom tags definitions to the TIFF, which it does, then it should be 
called from somewhere besides in TIFFDefaultDirectory.  Imagine 
generating a thousand page output file, with thousands of calls to 
_TIFFextender, instead it should only be one.

Here I'll edit tif_dirinfo.c locally here and the output of diff follows.

Is it worthwhile to use bsearch on the array of TIFFFieldInfo structs or 
is the array not worth it?  It's probably worth it because the array of 
info structs is all known fields.

What do you think about the _TIFFextender?  I don't understand its 
justification for being called from TIFFDefaultDirectory.  Instead, I 
think it should be called in TIFFClientOpen, around line 313 of 
tif_open.c, right before TIFFClientOpen calls TIFFDefaultDirectory, 
instead of line 1189 of tif_dir.c.  Then, if there is to be a separate 
function to extend the TIFFDefaultDirectory, then have that, too.  Then, 
besides _TIFFextender there could be _TIFFDirectoryExtender.

Then, I'm still trying to figure out a good way to copy each of the tags 
from a read mode directory to a write mode directory.

Let me know if I'm unclear.  Having a fresh pair of eyes makes a big 
difference.  The doxygen output really helps to browse the source code.

Ross F.





--- tif_dirinfo.c.orig  Tue Nov 18 06:12:48 2003
+++ tif_dirinfo.c       Tue Nov 18 06:23:53 2003
@@ -308,7 +308,7 @@
         if (ta->field_tag != tb->field_tag)
                 return (ta->field_tag < tb->field_tag ? -1 : 1);
         else
-               return (tb->field_type < ta->field_type ? -1 : 1);
+               return ((int)tb->field_type - (int)ta->field_type);
  }

  void
@@ -419,7 +419,17 @@
             (dt == TIFF_ANY || dt == last->field_type))
                 return (last);
         /* NB: if table gets big, use sorted search (e.g. binary 
search) */
-       for (i = 0, n = tif->tif_nfields; i < n; i++) {
+       if(dt != TIFF_ANY){
+            TIFFFieldInfo key={0, 0, 0, 0, 0, 0, 0, 0};
+            key.field_tag=tag;
+            key.field_type=dt;
+            return( (const TIFFFieldInfo *) bsearch(
+                       &key,
+                       tif->tif_fieldinfo,
+                       tif->tif_nfields,
+                       sizeof(TIFFFieldInfo),
+                       tagCompare));
+        } else for (i = 0, n = tif->tif_nfields; i < n; i++) {
                 const TIFFFieldInfo* fip = tif->tif_fieldinfo[i];
                 if (fip->field_tag == tag &&
                     (dt == TIFF_ANY || fip->field_type == dt))