diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py index 2ddb2263a..6834b7256 100644 --- a/Tests/test_file_libtiff.py +++ b/Tests/test_file_libtiff.py @@ -235,7 +235,10 @@ class TestFileLibTiff(LibTiffTestCase): def test_custom_metadata(self): custom = { 37000: 4, - 37001: 4.2 + 37001: 4.2, + 37002: 'custom tag value', + 37003: u'custom tag value', + 37004: b'custom tag value' } libtiff_version = TiffImagePlugin._libtiff_version() @@ -256,6 +259,8 @@ class TestFileLibTiff(LibTiffTestCase): reloaded = Image.open(out) for tag, value in custom.items(): + if libtiff and isinstance(value, bytes): + value = value.decode() self.assertEqual(reloaded.tag_v2[tag], value) def test_int_dpi(self): diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index a3db8e15c..be24624d6 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1519,12 +1519,16 @@ def _save(im, fp, filename): getattr(im, 'tag_v2', {}).items(), legacy_ifd.items()): # Libtiff can only process certain core items without adding - # them to the custom dictionary. Support has only been been added - # for int and float values + # them to the custom dictionary. + # Support for custom items has only been been added + # for int, float, unicode, string and byte values if tag not in TiffTags.LIBTIFF_CORE: + if TiffTags.lookup(tag).type == TiffTags.UNDEFINED: + continue if (distutils.version.StrictVersion(_libtiff_version()) < distutils.version.StrictVersion("4.0")) \ - or not (isinstance(value, int) or isinstance(value, float)): + or not (isinstance(value, (int, float, str, bytes)) or + (not py3 and isinstance(value, unicode))): # noqa: F821 continue if tag not in atts and tag not in blocklist: if isinstance(value, str if py3 else unicode): # noqa: F821 diff --git a/src/encode.c b/src/encode.c index 3c2f90f18..13da1b999 100644 --- a/src/encode.c +++ b/src/encode.c @@ -885,9 +885,11 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args) } } else if (PyBytes_Check(value)) { TRACE(("Setting from Bytes: %d, %s \n", key_int, PyBytes_AsString(value))); - status = ImagingLibTiffSetField(&encoder->state, - (ttag_t) PyInt_AsLong(key), - PyBytes_AsString(value)); + if (is_core_tag || !ImagingLibTiffMergeFieldInfo(&encoder->state, TIFF_ASCII, key_int)) { + status = ImagingLibTiffSetField(&encoder->state, + (ttag_t) PyInt_AsLong(key), + PyBytes_AsString(value)); + } } else if (PyTuple_Check(value)) { Py_ssize_t len,i; float *floatav;