Do not write custom tags with libtiff < 4

This commit is contained in:
Andrew Murray 2018-10-25 19:36:49 +11:00
parent a3d45e9cef
commit ddf8593e7b
5 changed files with 43 additions and 5 deletions

View File

@ -8,6 +8,7 @@ import io
import logging import logging
import itertools import itertools
import os import os
import distutils.version
from PIL import Image, TiffImagePlugin, TiffTags from PIL import Image, TiffImagePlugin, TiffTags
@ -236,7 +237,15 @@ class TestFileLibTiff(LibTiffTestCase):
37000: 4, 37000: 4,
37001: 4.2 37001: 4.2
} }
for libtiff in [False, True]:
libtiff_version = TiffImagePlugin._libtiff_version()
libtiffs = [False]
if distutils.version.StrictVersion(libtiff_version) >= \
distutils.version.StrictVersion("4.0"):
libtiffs.append(True)
for libtiff in libtiffs:
TiffImagePlugin.WRITE_LIBTIFF = libtiff TiffImagePlugin.WRITE_LIBTIFF = libtiff
im = hopper() im = hopper()

View File

@ -10,6 +10,7 @@ def version(module, version):
version(Image, "jpeglib") version(Image, "jpeglib")
version(Image, "zlib") version(Image, "zlib")
version(Image, "libtiff")
try: try:
from PIL import ImageFont from PIL import ImageFont

View File

@ -54,6 +54,7 @@ import os
import struct import struct
import sys import sys
import warnings import warnings
import distutils.version
from .TiffTags import TYPES from .TiffTags import TYPES
@ -284,6 +285,10 @@ def _limit_rational(val, max_val):
return n_d[::-1] if inv else n_d return n_d[::-1] if inv else n_d
def _libtiff_version():
return Image.core.libtiff_version.split("\n")[0].split("Version ")[1]
## ##
# Wrapper for TIFF IFDs. # Wrapper for TIFF IFDs.
@ -1501,9 +1506,11 @@ def _save(im, fp, filename):
# Libtiff can only process certain core items without adding # Libtiff can only process certain core items without adding
# them to the custom dictionary. Support has only been been added # them to the custom dictionary. Support has only been been added
# for int and float values # for int and float values
if tag not in TiffTags.LIBTIFF_CORE and not \ if tag not in TiffTags.LIBTIFF_CORE:
(isinstance(value, int) or isinstance(value, float)): if (distutils.version.StrictVersion(_libtiff_version()) <
continue distutils.version.StrictVersion("4.0")) \
or not (isinstance(value, int) or isinstance(value, float)):
continue
if tag not in atts and tag not in blocklist: if tag not in atts and tag not in blocklist:
if isinstance(value, str if py3 else unicode): if isinstance(value, str if py3 else unicode):
atts[tag] = value.encode('ascii', 'replace') + b"\0" atts[tag] = value.encode('ascii', 'replace') + b"\0"

View File

@ -3849,6 +3849,13 @@ setup_module(PyObject* m) {
} }
#endif #endif
#ifdef HAVE_LIBTIFF
{
extern const char * ImagingTiffVersion(void);
PyDict_SetItemString(d, "libtiff_version", PyUnicode_FromString(ImagingTiffVersion()));
}
#endif
PyDict_SetItemString(d, "PILLOW_VERSION", PyUnicode_FromString(version)); PyDict_SetItemString(d, "PILLOW_VERSION", PyUnicode_FromString(version));
return 0; return 0;

View File

@ -406,13 +406,20 @@ int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_typ
TIFFSTATE *clientstate = (TIFFSTATE *)state->context; TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
char field_name[10]; char field_name[10];
uint32 n; uint32 n;
int status = 0;
const TIFFFieldInfo info[] = { const TIFFFieldInfo info[] = {
{ key, 0, 1, field_type, FIELD_CUSTOM, 1, 0, field_name } { key, 0, 1, field_type, FIELD_CUSTOM, 1, 0, field_name }
}; };
n = sizeof(info) / sizeof(info[0]); n = sizeof(info) / sizeof(info[0]);
return TIFFMergeFieldInfo(clientstate->tiff, info, n); // Test for libtiff 4.0 or later, excluding libtiff 3.9.6 and 3.9.7
#if TIFFLIB_VERSION >= 20111221 && TIFFLIB_VERSION != 20120218 && TIFFLIB_VERSION != 20120922
status = TIFFMergeFieldInfo(clientstate->tiff, info, n);
#else
TIFFMergeFieldInfo(clientstate->tiff, info, n);
#endif
return status;
} }
int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...){ int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...){
@ -514,4 +521,11 @@ int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int
state->errcode = IMAGING_CODEC_END; state->errcode = IMAGING_CODEC_END;
return 0; return 0;
} }
const char*
ImagingTiffVersion(void)
{
return TIFFGetVersion();
}
#endif #endif