2003.08.07 01:12 "[Tiff] Custom tags", by Ashley Dreier

2003.08.07 16:40 "[Tiff] Custom tags", by Andrey Kiselev

I've been trying to port some of our old software to use the new CUSTOM tag facility (v3.6.0 beta 2 TIFF source). I am able to read out the custom tags stored in my TIFF images using TIFFGetField() after making a call to TIFFSetTagExtender() to 'configure' my custom tags. The problem I'm having at the moment is that I don't seem able to store modifed versions of the custom tag data to the file. I open the files using the 'r+' mode (i.e. read/write) and grab the directory/tag information. The TIFFGetField() function confirms that I'm reading the custom data correctly. I then use TIFFSetField() to modify the custom tag data and again call TIFFGetField() to confirm that the data has changed (at least in the TIFF data structure). The next thing I do is a TIFFClose(). This appears to close the file handle, but the file has not been updated with the new tag data. I tried doing a 'TIFFRewriteDirectory()' before calling TIFFClose() to try to force the directory update, but this generates a 'segfault', so I assume that I'm not using the CUSTOM tags correctly. I've also tried 'TIFFCheckpointDirectory()' with a similar problem. In both cases, the resultant TIFF file is corrupted and no longer readable by the TIFF library.

Ashley,

Thank you for report, custom tags support was broken (with except of ASCII tags). Problem fixed now, you can take lates revison from CVS repository.

There is a test case:

#include <tiffio.h>
#include <stdio.h>

#define TIFFTAG_ASCIITAG 666
#define TIFFTAG_LONGTAG 667
#define TIFFTAG_SHORTTAG 668
#define TIFFTAG_RATIONALTAG 669
#define TIFFTAG_FLOATTAG 670
#define TIFFTAG_DOUBLETAG 671
#define TIFFTAG_BYTE 672

static void TagExtender(TIFF *tiff)
{
    static const TIFFFieldInfo xtiffFieldInfo[] = {
        { TIFFTAG_ASCIITAG,    -1,-1, TIFF_ASCII,        FIELD_CUSTOM,
          1,       0,      "MyTag" },
        { TIFFTAG_SHORTTAG, 1, 1, TIFF_SHORT,  FIELD_CUSTOM, 0, 1,
            "ShortTag" },
        { TIFFTAG_LONGTAG, 1, 1, TIFF_LONG,  FIELD_CUSTOM, 0, 1,
            "LongTag" },
        { TIFFTAG_RATIONALTAG, 1, 1, TIFF_RATIONAL,  FIELD_CUSTOM, 0, 1,
            "RationalTag" },
        { TIFFTAG_FLOATTAG, 1, 1, TIFF_FLOAT,  FIELD_CUSTOM, 0, 1,
            "FloatTag" },
        { TIFFTAG_DOUBLETAG, 1, 1, TIFF_DOUBLE,  FIELD_CUSTOM, 0, 1,
            "DoubleTag" },
        { TIFFTAG_BYTE, 1, 1, TIFF_BYTE,  FIELD_CUSTOM, 0, 1,
            "DoubleTag" },
    };

    TIFFMergeFieldInfo( tiff, xtiffFieldInfo,
                    sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]) );
}

int main()
{
    TIFF    *tiff;
    char    *pszString;
    long    iLong, *paiLong;
    short   iShort, *paiShort;
    float   fFloat, *pafFloat;
    double  dfDouble, *padfDouble;
    char    iByte, *paiByte;

    unsigned short iCount;

    TIFFSetTagExtender(TagExtender);

    tiff = TIFFOpen("test.tif", "r+");
    TIFFSetField(tiff, TIFFTAG_ASCIITAG, "Tag contents");
    iShort = 263;
    TIFFSetField(tiff, TIFFTAG_SHORTTAG, 1, &iShort);
    iLong = 117;
    TIFFSetField(tiff, TIFFTAG_LONGTAG, 1, &iLong);
    fFloat = 0.333333;
    TIFFSetField(tiff, TIFFTAG_RATIONALTAG, 1, &fFloat);
    fFloat = 0.666666;
    TIFFSetField(tiff, TIFFTAG_FLOATTAG, 1, &fFloat);
    dfDouble = 0.1234567;
    TIFFSetField(tiff, TIFFTAG_DOUBLETAG, 1, &dfDouble);
    iByte = 89;
    TIFFSetField(tiff, TIFFTAG_BYTE, 1, &iByte);
    TIFFRewriteDirectory(tiff);
    TIFFClose(tiff);

    tiff = TIFFOpen("test.tif", "r");
    TIFFGetField(tiff, TIFFTAG_ASCIITAG, &pszString);
    printf("ASCII tag: %s\n", pszString);
    TIFFGetField(tiff, TIFFTAG_SHORTTAG, &iCount, &paiShort);
    if (iCount == 1)
            printf("Short tag: %d\n", paiShort[0]);
    TIFFGetField(tiff, TIFFTAG_LONGTAG, &iCount, &paiLong);
    if (iCount == 1)
            printf("Long tag: %ld\n", paiLong[0]);
    TIFFGetField(tiff, TIFFTAG_RATIONALTAG, &iCount, &pafFloat);
    if (iCount == 1)
            printf("Rational tag: %f\n", pafFloat[0]);
    TIFFGetField(tiff, TIFFTAG_FLOATTAG, &iCount, &pafFloat);
    if (iCount == 1)
            printf("Float tag: %f\n", pafFloat[0]);
    TIFFGetField(tiff, TIFFTAG_DOUBLETAG, &iCount, &padfDouble);
    if (iCount == 1)
            printf("Double tag: %lf\n", padfDouble[0]);
    TIFFGetField(tiff, TIFFTAG_BYTE, &iCount, &paiByte);
    if (iCount == 1)
            printf("Byte tag: %d\n", paiByte[0]);
    TIFFClose(tiff);

    return 0;
}

Regards,
Andrey

Andrey V. Kiselev
Home phone: +7 812 5274898 ICQ# 26871517