-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Reading and converting 16-bit pixels #452
Comments
That image isn't coming up as a signed tiff for me. I'm seeing a SampleFormat of 1, not 2. If you look at the tiff spec, http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf page 80, the SampleFormat tag can take one of 4 values:
We do read the sample format tag and act on it -- the values are in PIL/TiffImagePlugin.py around line 140. If this had a sample format of 2, we'd be getting this line: (MM, 1, 2, 1, (16,), ()): ("I;16BS", "I;16BS"), where currently we're getting: (MM, 1, 1, 1, (16,), ()): ("I;16B", "I;16B"),
Imagemagick agrees:
|
Of course its not coming up as a signed tiff. Its not a signed tiff - your ImageMagick dump, my tiffdump, tiffinfo, and ImageJ are all in complete agreement about that. Its only a signed tiff when read by Image.open(), which is the whole problem and basis for this bug report. The mode is reported correctly as unsigned, but the pixel values are negative! As far as conversion goes, I would expect the same numerical values as I convert from unsigned 16-bit to unsigned 32-bit, and back to unsigned 16-bit (I;16B -> I -> I;16). This should be true regardless of the numerical range because the first conversion is an up-cast, and the second conversion is a down-cast to the original numeric type. The output above clearly shows that this is not the case. So PR #416 and #417 are not part of the 2.2.2 release which looked to me happened after their merge into master? From my looking at them (which I did before submitting this report, but maybe not in sufficient detail), they deal with 12-bit tiffs stored as 16-bit, where you wouldn't encounter numerical values high enough to run into signedness bugs. If these were not merged into the 2.2.2 release, and as they are your PRs and you already have the test file in hand, can you quickly check what pixel values get reported for this file using your codebase? Lastly, tiffdump does not report a SampleFormat tag for this file, so a SampleFormat tag value of 1 (unsigned) is only implied by its absence. Or, did you read the SampleFormat tag from the file? I always considered tiffdump the last word on what tags are present in a tiff file, but at this point I'm ready to consider any possibility. |
Finally, in case your branch isn't merged with master at this repo, I installed pillow from your 12-bit-tiff branch like so:
And the output is still exactly the same as above. Are we there yet? |
Sorry, I misread your report as the image not showing up as signed. I'll take a closer look. |
It looks like the pixel access functions are using int16 and int32 instead of uint*s. Check out #455. |
Note no 'S' in mode.
Then,
Two problems: Other than using the extended SampleFormat tag (339, 0x0153), there is no way to store a signed value in a tiff file. The value stored in this image at 0,0 is 32768, and this file has no SampleFormat tag, so only unsigned integers are possible. Instead the value reported is the two's complement of the actual value.
Second problem unrelated to tiff peculiarities, you have an unsigned image mode with a signed pixel value.
Moving on,
This is the correct value.
Even more surprising is when we convert this 32-bit, presumably unsigned image back to unsigned 16 bit:
???. Even better, a pixel at 32,16 has a value of 32769:
Correct in the 32-bit unsigned image (is it really unsigned, BTW? didn't check), but in the 16-bit image converted from it, this pixel is still 32767!
In fact, all of the pixels in the converted image are clipped to 32767. In the image as-read, this value is -32767 (two's complement of 32769):
Does the problem originate from the fact that we went over the signed 16-bit max even though we were supposed to be dealing with unsigned values? Is the convert problem related to the tiff reader problem?
Sample file for the above: pil_pillow_16_bit_bug.tif
The text was updated successfully, but these errors were encountered: