-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Color inversion for signed gray images #129
Comments
I tried figuring out how libtiff does this, but this is the only relevant code I found: /*
* Construct a mapping table to convert from the range
* of the data samples to [0,255] --for display. This
* process also handles inverting B&W images when needed.
*/
static int
setupMap(TIFFRGBAImage* img)
{
int32_t x, range;
range = (int32_t)((1L << img->bitspersample) - 1);
/* treat 16 bit the same as eight bit */
if (img->bitspersample == 16)
range = (int32_t)255;
img->Map = (TIFFRGBValue*)_TIFFmalloc((range + 1) * sizeof(TIFFRGBValue));
if (img->Map == NULL) {
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
"No space for photometric conversion table");
return (0);
}
if (img->photometric == PHOTOMETRIC_MINISWHITE) {
for (x = 0; x <= range; x++)
img->Map[x] = (TIFFRGBValue)(((range - x) * 255) / range);
} else {
for (x = 0; x <= range; x++)
img->Map[x] = (TIFFRGBValue)((x * 255) / range);
}
if (img->bitspersample <= 16 && (img->photometric == PHOTOMETRIC_MINISBLACK || img->photometric == PHOTOMETRIC_MINISWHITE)) {
/*
* Use photometric mapping table to construct
* unpacking tables for samples <= 8 bits.
*/
if (!makebwmap(img))
return (0);
/* no longer need Map, free it */
_TIFFfree(img->Map);
img->Map = NULL;
}
return (1);
} What also puzzles me, is that we try to invert floating point values, Lines 572 to 577 in a874b9c
but again, I haven't found any code in libtiff which would manipulate floating-point data in such a way. I also tried creating a copy of a 32-bit floating-point encoded file where I changed the PhotometricInterpretation tag from BlackIsZero to WhiteIsZero . Both of the files are displayed the same in GIMP, Krita fails to display the WhiteIsZero version, which seems to suggest that this inversion might be wrong.
But take this with a grain of salt. The libtiff codebase is a bit hard to read, so it's possible that I have missed something. |
OK, the way libtiff handles these conversions is weird. libtiff has a few different interfaces(man pages):
The I also created two test images. I tried loading them with the Therefore it's questionable if we should do implicit conversions at all. |
We only ever do color inversion if the file specifies "white is zero". A lot of the weirdness comes from seeing that tag on files where that doesn't really make sense. |
Looked through the liftiff source as well and came to a similar conclusion as @TomasKralCZ. I don't see anything that indicates our current strategy is clearly wrong. I'd say we leave things as they are. We can revisit later if anyone comes across a more definitive answer or some software that creates images with different assumptions. |
From @TomasKralCZ in #125 (comment)
#128 wasn't intended to change this behavior, but looking more closely it seems that the library wasn't being consistent prior to the change. In particular, i32 and i64 grayscale images never did inversion, while i8 and i16 would if WhiteIsZero was specified.
We should figure out which is correct behavior and then do it consistently. This comment suggests that inversion might be correct:
image-tiff/src/decoder/mod.rs
Lines 1037 to 1038 in 9b94e9d
The text was updated successfully, but these errors were encountered: