Merge pull request #5848 from radarhere/sampleformat

Pass SAMPLEFORMAT to libtiff
This commit is contained in:
Hugo van Kemenade 2021-12-28 10:03:16 +02:00 committed by GitHub
commit 1806cf5607
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 7 deletions

View File

@ -9,7 +9,7 @@ from ctypes import c_float
import pytest
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags, features
from PIL.TiffImagePlugin import STRIPOFFSETS, SUBIFD
from PIL.TiffImagePlugin import SAMPLEFORMAT, STRIPOFFSETS, SUBIFD
from .helper import (
assert_image_equal,
@ -825,6 +825,17 @@ class TestFileLibTiff(LibTiffTestCase):
assert_image_equal_tofile(im, "Tests/images/copyleft.png", mode="RGB")
def test_sampleformat_write(self, tmp_path):
im = Image.new("F", (1, 1))
out = str(tmp_path / "temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True
im.save(out)
TiffImagePlugin.WRITE_LIBTIFF = False
with Image.open(out) as reloaded:
assert reloaded.mode == "F"
assert reloaded.getexif()[SAMPLEFORMAT] == 3
def test_lzw(self):
with Image.open("Tests/images/hopper_lzw.tif") as im:
assert im.mode == "RGB"

View File

@ -1676,8 +1676,6 @@ def _save(im, fp, filename):
# optional types for non core tags
types = {}
# SAMPLEFORMAT is determined by the image format and should not be copied
# from legacy_ifd.
# STRIPOFFSETS and STRIPBYTECOUNTS are added by the library
# based on the data in the strip.
# The other tags expect arrays with a certain length (fixed or depending on
@ -1686,7 +1684,6 @@ def _save(im, fp, filename):
# SUBIFD may also cause a segfault.
blocklist += [
REFERENCEBLACKWHITE,
SAMPLEFORMAT,
STRIPBYTECOUNTS,
STRIPOFFSETS,
TRANSFERFUNCTION,
@ -1702,9 +1699,14 @@ def _save(im, fp, filename):
legacy_ifd = {}
if hasattr(im, "tag"):
legacy_ifd = im.tag.to_v2()
for tag, value in itertools.chain(
ifd.items(), getattr(im, "tag_v2", {}).items(), legacy_ifd.items()
):
# SAMPLEFORMAT is determined by the image format and should not be copied
# from legacy_ifd.
supplied_tags = {**getattr(im, "tag_v2", {}), **legacy_ifd}
if SAMPLEFORMAT in supplied_tags:
del supplied_tags[SAMPLEFORMAT]
for tag, value in itertools.chain(ifd.items(), supplied_tags.items()):
# Libtiff can only process certain core items without adding
# them to the custom dictionary.
# Custom items are supported for int, float, unicode, string and byte
@ -1729,6 +1731,9 @@ def _save(im, fp, filename):
else:
atts[tag] = value
if SAMPLEFORMAT in atts and len(atts[SAMPLEFORMAT]) == 1:
atts[SAMPLEFORMAT] = atts[SAMPLEFORMAT][0]
logger.debug("Converted items: %s" % sorted(atts.items()))
# libtiff always expects the bytes in native order.