-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
>>> import PIL
>>> PIL.PILLOW_VERSION
'2.2.2'
>>> from PIL import Image
>>> im = Image.open('pil_pillow_16_bit_bug.tif')
>>> im
<PIL.TiffImagePlugin.TiffImageFile image mode=I;16B size=512x512 at 0x103125E60>
Note no 'S' in mode.
Then,
>>> im.getpixel((0,0))
-32768
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,
>>> im2 = im.convert('I')
>>> im2.getpixel((0,0))
32768
This is the correct value.
Even more surprising is when we convert this 32-bit, presumably unsigned image back to unsigned 16 bit:
>>> im3 = im2.convert('I;16')
>>> im3.getpixel((0,0))
32767
???. Even better, a pixel at 32,16 has a value of 32769:
>>> im2.getpixel((32,16))
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!
>>> im3.getpixel((32,16))
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):
>>>> >>> im.getpixel((32,16))
-32767
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