Skip to content

Commit

Permalink
Fixing the mapping from [0, 255] (Java) to [0, 65535] (TIFF) color specs
Browse files Browse the repository at this point in the history
  • Loading branch information
WeatherGod committed Feb 14, 2024
1 parent ea02fee commit 882a5fa
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 9 deletions.
12 changes: 7 additions & 5 deletions cdm/misc/src/main/java/ucar/nc2/geotiff/GeotiffWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public int[] getColorTable() {

/**
* Have the geotiff include a colormap in the form of a mapping of the pixel value to the rgb triplet.
* Assumes an RGB of {255, 255, 255} for any values not specified.
* Assumes an RGB of {0, 0, 0} for any values not specified.
*
* Pass null to unset the colorTable.
*
Expand All @@ -411,7 +411,7 @@ public int[] getColorTable() {
* and the output data type must be byte or integer.
*/
public void setColorTable(Map<Integer, Color> colorMap) {
setColorTable(colorMap, new Color(255, 255, 255));
setColorTable(colorMap, new Color(0, 0, 0));
}

/**
Expand All @@ -438,9 +438,11 @@ public void setColorTable(Map<Integer, Color> colorMap, Color defaultRGB) {
colorTable = new int[3 * 256];
for (int i = 0; i < 256; i++) {
// Scale it up to [0, 65535], which is needed by the ColorMap tag.
colorTable[i] = colorMap.getOrDefault(i, defaultRGB).getRed() * 256;
colorTable[256 + i] = colorMap.getOrDefault(i, defaultRGB).getGreen() * 256;
colorTable[512 + i] = colorMap.getOrDefault(i, defaultRGB).getBlue() * 256;
// It seems like 0 should map to 255, 1 to 511, and so forth, as that
// seems to be the only way to get gdalinfo to report back the correct values.
colorTable[i] = (colorMap.getOrDefault(i, defaultRGB).getRed() + 1) * 256 - 1;
colorTable[256 + i] = (colorMap.getOrDefault(i, defaultRGB).getGreen() + 1) * 256 - 1;
colorTable[512 + i] = (colorMap.getOrDefault(i, defaultRGB).getBlue() + 1) * 256 - 1;
}
}

Expand Down
Binary file modified cdm/misc/src/test/data/ucar/nc2/geotiff/baseline_palette.tif
Binary file not shown.
33 changes: 29 additions & 4 deletions cdm/misc/src/test/java/ucar/nc2/geotiff/TestGeoTiffPalette.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,37 @@ public void testSetColorTable() {
writer.setColorTable(colorMap, Color.black);
int[] resultTable = writer.getColorTable();

// Explicitly spelling out the RGB channel values [0, 255]
// because there were some off-by-one errors in initial development.
int[] expectedRGBs = new int[] {0, 170, 255, // #00AAff
21, 20, 18, // #151412
222, 1, 171, // #DE01aB
16, 10, 187}; // #100ABB

int[] expectedTable = new int[3 * 256];
// The colortable uses black for the default color as per above,
// which translate to RGB values of (255, 255, 255) in the TIFF color notation (see note below).
// Java arrays are initialized to zero, so we need to fill it with 255 before putting in our table.
for (int i = 0; i < expectedTable.length; i++) {
expectedTable[i] = 255;
}

// Now put in our color table.
for (int i = 1; i <= 4; i++) {
// Channel values are between 0 and 256*256 as per tiff conventions.
expectedTable[0 * 256 + i] = colorMap.get(i).getRed() * 256;
expectedTable[1 * 256 + i] = colorMap.get(i).getGreen() * 256;
expectedTable[2 * 256 + i] = colorMap.get(i).getBlue() * 256;
// TIFF ColorTable Channel values are between 0 and (256*256 - 1), inclusively, as per tiff conventions.
// Java Color Channel values are between 0 and 255, inclusively.
// Java Channel Value 0 should map to TIFF Channel Value 255
// 1 should map to 511
// 2 should map to 767
// 255 should map to 65535
Assert.assertEquals(expectedRGBs[0 + 3 * (i - 1)], colorMap.get(i).getRed());
expectedTable[0 * 256 + i] = (colorMap.get(i).getRed() + 1) * 256 - 1;

Assert.assertEquals(expectedRGBs[1 + 3 * (i - 1)], colorMap.get(i).getGreen());
expectedTable[1 * 256 + i] = (colorMap.get(i).getGreen() + 1) * 256 - 1;

Assert.assertEquals(expectedRGBs[2 + 3 * (i - 1)], colorMap.get(i).getBlue());
expectedTable[2 * 256 + i] = (colorMap.get(i).getBlue() + 1) * 256 - 1;
}
Assert.assertArrayEquals(expectedTable, resultTable);

Expand Down

0 comments on commit 882a5fa

Please sign in to comment.