#106 Re-post of indexed TIFF palette bug

open
Hervé Drolon
None
5
2012-10-31
2008-03-16
Leszek Pawlowicz
No

The initial posting, and your response are at the bottom.

  1. I don't think you understood my comment. Nowhere do I say that I'm getting 16-bit color palettes from my TIFF with FreeImage. I said that it's a 13-color palette in the indexed TIFF. And then I listed the 8-bit RGB hexcodes I was retrieving with FreeImage, so clearly I wasn't getting 16-bit color.

  2. If I open one of the problematic TIFF files in Photoshop (or Paint Shop Pro), I get the correct standard palette, with the correct standard RGB colors. If I retrieve the palette for the exact same image using FreeImage, I get incorrect values for the palette colors. And I've confirmed this with another independent program that uses FreeImage (the PictureIt application from AIL). If other programs can retrieve the correct palette, but FreeImage doesn't, then there's a bug in FreeImage.

  3. Perhaps you could wait until receiving a response to your comment before closing a bug report.

Initial Comment:
An unusual quirk in the palette for some Tiff files, and specifically for USGS 8-bit GeoTiff topo maps (like those available at the Libremap site, http://libremap.org/). These all have a standard 13-color palette; hex codes:

000000
FFFFFF
0097A4
CB0017
834225
C9EA90

and so on. If you open one of these in Photoshop, and check the palette colors, they're correct. But if you retrieve the palette with FreeImage, here's the palette you get:

000000
FEFEFE
0096A3
CA0016
824124
C89D8F
etc.

The individual RGB values are one less than their correct values, except for 000000 which is unchanged. I've also seen this behavior in 23-color indexed TIff files from the US Forest Service. If I open the Tiff file in Photoshop, then save it under a different name but with the same palette, then the palette colors show up correctly.


Comment By: Hervé Drolon (drolon)
Date: 2008-03-16 14:13

Message:
Logged In: YES
user_id=613758
Originator: NO

Hi,

I don't think it's a bug but a behavior related to the 16- to 8-bit color
conversion.
TIFF palettes are stored as 16-bit.
On loading, the 16-bit palette is converted to a 8-bit displayable palette
using the macro

define CVT(x) (((x) * 255L) / ((1L<<16)-1))

// ---
case PHOTOMETRIC_PALETTE: // color map indexed
uint16 red;
uint16
green;
uint16 *blue;

                   TIFFGetField(tiff, TIFFTAG_COLORMAP, &red, &green, &blue);

                   // load the palette in the DIB

                   if (CheckColormap(1<<bitspersample, red, green, blue) == 16) {
                           for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
                                   pal[i].rgbRed =(BYTE) CVT(red[i]);
                                   pal[i].rgbGreen = (BYTE) CVT(green[i]);
                                   pal[i].rgbBlue = (BYTE) CVT(blue[i]);
                           }
                   } else {
                           for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
                                   pal[i].rgbRed = (BYTE) red[i];
                                   pal[i].rgbGreen = (BYTE) green[i];
                                   pal[i].rgbBlue = (BYTE) blue[i];
                           }
                   }

                   break;

// ---
On saving, the 8-bit palette is converted to a 16-bit palette using the
macro

define SCALE(x) (((x)*((1L<<16)-1))/255)

// ---
if (photometric == PHOTOMETRIC_PALETTE) {
uint16 r, g, b;
uint16 nColors = (uint16)FreeImage_GetColorsUsed(dib);
RGBQUAD
pal = FreeImage_GetPalette(dib);

                   r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * nColors);
                   if(r == NULL) throw FI_GLOBAL_ERROR_MEMORY;
                   g = r + nColors;
                   b = g + nColors;

                   for (int i = nColors - 1; i >= 0; i--) {
                           r[i] = SCALE((uint16)pal[i].rgbRed);
                           g[i] = SCALE((uint16)pal[i].rgbGreen);
                           b[i] = SCALE((uint16)pal[i].rgbBlue);
                   }

                   TIFFSetField(out, TIFFTAG_COLORMAP, r, g, b);

                   _TIFFfree(r);
           }

// ---

There's no 16-bit palettes under FreeImage, so I don't see how you can
have 16-bit values with FreeImage_GetPalette function ...

Hervé Drolon

Discussion

  • Hervé Drolon
    Hervé Drolon
    2008-03-16

    Logged In: YES
    user_id=613758
    Originator: NO

    Hi,

    Sorry, I didn't understood your comments :(

    1. The numbers you describe come from the RGBQUAD pointer returned by FreeImage_GetPalette and should be read as (for example) :
      C9EA90 = [Red][Green][Blue]
      Right ?

    2. I also have Photoshop but I don't see how you can display the 13-colors palette as an array of numbers ...
      Can you explain how you did this ?

    3. The bug was set as 'pending', meaning that it is waiting for comments and that without comments for 14 days, it will be closed automatically.

    Lastly, can you give me a link to a specific sample image at Libre Map so that I can reproduce your results ?

    Hervé Drolon

     
  • Logged In: YES
    user_id=2035698
    Originator: YES

    Sorry - this is the first time I've submitted a bug at SourceForge, so I'm not familiar with the process.

    1. Yes, that's correct.

    2. You can't display the palette as numbers in Photoshop, but you can open up the palette (Image => Mode => Color Table). Once there, double-click on a color to bring up the Color Picker, which will display the RGB byte values for each color, as well as the RGB color hex code (e.g. FFFFFF is white, FF0000 is pure red).

    3. Any TIFF file from the site will likely exhibit the problem, but here's a direct link to one that I just checked to confirm that it will have that issue:

    http://www.archive.org/download/usgs_drg_az_35111_a6/o35111a6.tif

    Thanks for your help.

     
  • Hervé Drolon
    Hervé Drolon
    2008-03-16

    Logged In: YES
    user_id=613758
    Originator: NO

    I'm still thinking it's not a bug :
    the CVT macro comes from the LibTIFF distribution and shows how to convert a 16-bit color value to a 8-bit color value using :

    define CVT(x) (((x) * 255L) / ((1L<<16)-1))

    Photoshop seems to add 'one' to this conversion, that's why you see a difference of 'one' for each color.
    However, Photoshop is wrong here and the LibTIFF macro is correct to my mind.

    Hervé Drolon

     
  • Logged In: YES
    user_id=2035698
    Originator: YES

    It may well be a bug in LibTIFF, but it's definitely not a bug in Photoshop. The USGS topo maps use a standard palette, which you can find listed here:

    http://www.isgs.uiuc.edu/nsdihome/webdocs/drgs/drg_24k/rcc/rcc_met.html

    Note that white is 255, 255,255, which translates to FFFFFF. Photoshop sees this as FFFFFF; Paint Shop Pro sees this as FFFFFF; another program I use which automatically translates topo colors sees this as FFFFFF. But FreeImage sees this as FEFEFE; the other palette colors are listed in a similar fashion with FreeImage, each RGB value decremented by one.

    Assigning the blame to Photoshop also defies common sense: would a program that's been around for 20 years, and which graphic artists rely on for color accuracy, arbitrarily modify a palette the way you suggest? No.

    For that matter, if you save the image in Photoshop under a different name, not modifying the palette in any way, then check the palette of this newly-saved image with FreeImage, the palette colors are now identified correctly; white is now correctly identified as FFFFFF. There's something in the original TIF file format that LibTIFF (and/or FreeImage) is not reading correctly.