2016.09.19 16:29 "[Tiff] Accuracy of TIFF Field metadata (COLORMAP)", by

2016.09.20 11:20 "Re: [Tiff] Accuracy of TIFF Field metadata (COLORMAP)", by

On 2016-09-20 11:06, rleigh@codelibre.net wrote:

On 2016-09-19 18:47, mickey.rose@seznam.cz wrote:

I recently discovered a problem on Windows where I was getting a strange runtime error ("Run-Time Check Failure #2 -S") which turns out was due to stack corruption. This was due to calling TIFFGetField with the wrong parameters, and that was because the field metadata in tif_dirinfo.c was wrong. Here's the broken bit:

         { TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER,

TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL },

These values are correct. There's field_passcount=0, which means you shouldn't be asking for the nunber of colors (&n in your code) from TIFFGetField. See:

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dir.c#L327

TIFFGetField gives you the three uint16* pointers to r/g/b arrays, whose length, i.e. the number of colors in the palette, is determined by bitspersample (n = 1<<bitspersample)

I'm not sure I follow completely.

        unsigned char field_passcount;  /* if true, pass dir count on set */

This is a "get" operation I'm performing, so I'm not sure it applies. Does it also apply to get?

That's my understanding, yes. In _TIFFVGetField it's only used in the custom field case, probably because the rest are hardcoded.

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dir.c#L1053

Additionally, where is it specified that the value is "1<<bitspersample"? I know it's in the specification e.g. http://www.awaresystems.be/imaging/tiff/tifftags/colormap.html.

It's hardcoded in various places:

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dir.c#L328

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dirread.c#L3771

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dirwrite.c#L1774

These places are not related to TIFFGetField, but that's because

    TIFFGetField(tif, TIFFTAG_COLORMAP, &p0, &p1, &p2);

returns only pointers to arrays, it doesn't care how long they are.

What I mean is I'm trying to write this code without any specific prior knowledge of the tag types, and I'd like to obtain that information from libtiff itself, without making any assumptions in my code. Is that possible to obtain in any way?

I don't think that's possible. Look at TIFFTAG_COLORMAP and TIFFTAG_TRANSFERFUNCTION, for example. Their TIFFField records, except the name, are identical:

{ TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction",

NULL },

Yet their handling in _TIFFVGetField differs:

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dir.c#L939

    case TIFFTAG_COLORMAP:

        *va_arg(ap, uint16**) = td->td_colormap[0];
        *va_arg(ap, uint16**) = td->td_colormap[1];
        *va_arg(ap, uint16**) = td->td_colormap[2];

https://github.com/vadz/libtiff/blob/c87dc82d7ff8214bd417176bd76f3fe94a237659/libtiff/tif_dir.c#L1005

    case TIFFTAG_TRANSFERFUNCTION:

        *va_arg(ap, uint16**) = td->td_transferfunction[0];
        if (td->td_samplesperpixel - td->td_extrasamples > 1) {

            *va_arg(ap, uint16**) = td->td_transferfunction[1];
            *va_arg(ap, uint16**) = td->td_transferfunction[2];

        }