2003.08.11 05:09 "[Tiff] Custom tags", by Ashley Dreier
Hi Andrey.
Further to my previous posting, I now have the following situation. Writes for non-ascii custom tags of size '1' work fine. If however the size is set to 2 (or higher presumably - i.e. not TIFF_VARIABLE) then I get a corrupted TIFF directory when writing the directory structure. Data from 'purify' indicates that the problem again is in TIFFWriteNormalTag(). The relevant code snippet is:
case TIFF_LONG:
case TIFF_SLONG:
if (wc > 1) {
uint32* lp;
if (wc == (u_short) TIFF_VARIABLE)
TIFFGetField(tif, fip->field_tag, &wc, &lp);
else
TIFFGetField(tif, fip->field_tag, &lp);
if (!WRITEF(TIFFWriteLongArray, lp))
return (0);
} else {
if (fip->field_passcount) {
uint32* lp;
TIFFGetField(tif, fip->field_tag, &wc, &lp);
if (!WRITEF(TIFFWriteLongArray, lp))
return 0;
} else {
/* XXX handle LONG->SHORT conversion */
TIFFGetField(tif, fip->field_tag,
&dir->tdir_offset);
}
}
break;
In my case, 'wc' is set to 2, and fip->field_passcount is also set. I get an 'uninitialised read error' when the WRITEF macro is called, presumably because it's trying to write 2 LONG values out when the reference pointer is addressing the wrong thing. I think the correct code should also look at the 'field_passcount' field as is done in the case where 'wc <= 1'.
Here's my 'diff' output (i.e. cvs diff tif_dirwrite.c) for the LONG custom tag type.
diff -u -w -r1.16 tif_dirwrite.c
--- tif_dirwrite.c 7 Aug 2003 16:39:06 -0000 1.16
+++ tif_dirwrite.c 11 Aug 2003 05:07:35 -0000
@@ -477,6 +477,8 @@
uint32* lp;
if (wc == (u_short) TIFF_VARIABLE)
TIFFGetField(tif, fip->field_tag, &wc, &lp);
+ else if (fip->field_passcount)
+ TIFFGetField(tif, fip->field_tag, &wc, &lp);
else
TIFFGetField(tif, fip->field_tag, &lp);
if (!WRITEF(TIFFWriteLongArray, lp))
The case is probably the same for all other custom tag types also.
Regards,
Ashley.
Ashley J. Dreier. Email: Ashley.Dreier@csiro.au
CSIRO Manufacturing and Infrastructure Tech, Phone: +61 3 9662 7799
Locked Bag No. 9, Fax: +61 3 9662 7851
Preston, Vic, 3072, Australia.
URL: http://www.msa.cmst.csiro.au/cmst/automation/staff/ajd