mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 01:46:18 +03:00
Merge pull request #1988 from wiredfool/iccprofile
Binary Tiff Metadata/ICC profile.
This commit is contained in:
commit
ffcc067038
|
@ -544,8 +544,7 @@ class ImageFileDirectory_v2(collections.MutableMapping):
|
|||
self.tagtype[tag] = 2
|
||||
|
||||
if self.tagtype[tag] == 7 and bytes is not str:
|
||||
values = [value.encode("ascii", 'replace') if isinstance(value, str) else value
|
||||
for value in values]
|
||||
values = [value.encode("ascii", 'replace') if isinstance(value, str) else value]
|
||||
|
||||
values = tuple(info.cvt_enum(value) for value in values)
|
||||
|
||||
|
@ -604,8 +603,7 @@ class ImageFileDirectory_v2(collections.MutableMapping):
|
|||
|
||||
@_register_loader(1, 1) # Basic type, except for the legacy API.
|
||||
def load_byte(self, data, legacy_api=True):
|
||||
return (data if legacy_api else
|
||||
tuple(map(ord, data) if bytes is str else data))
|
||||
return data
|
||||
|
||||
@_register_writer(1) # Basic type, except for the legacy API.
|
||||
def write_byte(self, data):
|
||||
|
|
|
@ -48,11 +48,21 @@ def lookup(tag):
|
|||
#
|
||||
# id: (Name, Type, Length, enum_values)
|
||||
#
|
||||
# The length here differs from the length in the tiff spec. For
|
||||
# numbers, the tiff spec is for the number of fields returned. We
|
||||
# agree here. For string-like types, the tiff spec uses the length of
|
||||
# field in bytes. In Pillow, we are using the number of expected
|
||||
# fields, in general 1 for string-like types.
|
||||
|
||||
|
||||
BYTE = 1
|
||||
ASCII = 2
|
||||
SHORT = 3
|
||||
LONG = 4
|
||||
RATIONAL = 5
|
||||
UNDEFINED = 7
|
||||
SIGNED_RATIONAL = 10
|
||||
DOUBLE = 12
|
||||
|
||||
TAGS_V2 = {
|
||||
|
||||
|
@ -128,8 +138,8 @@ TAGS_V2 = {
|
|||
338: ("ExtraSamples", SHORT, 0),
|
||||
339: ("SampleFormat", SHORT, 0),
|
||||
|
||||
340: ("SMinSampleValue", 12, 0),
|
||||
341: ("SMaxSampleValue", 12, 0),
|
||||
340: ("SMinSampleValue", DOUBLE, 0),
|
||||
341: ("SMaxSampleValue", DOUBLE, 0),
|
||||
342: ("TransferRange", SHORT, 6),
|
||||
|
||||
# obsolete JPEG tags
|
||||
|
@ -152,34 +162,34 @@ TAGS_V2 = {
|
|||
|
||||
# FIXME add more tags here
|
||||
34665: ("ExifIFD", SHORT, 1),
|
||||
34675: ('ICCProfile', 7, 0),
|
||||
34853: ('GPSInfoIFD', 1, 1),
|
||||
34675: ('ICCProfile', UNDEFINED, 1),
|
||||
34853: ('GPSInfoIFD', BYTE, 1),
|
||||
|
||||
# MPInfo
|
||||
45056: ("MPFVersion", 7, 1),
|
||||
45056: ("MPFVersion", UNDEFINED, 1),
|
||||
45057: ("NumberOfImages", LONG, 1),
|
||||
45058: ("MPEntry", 7, 1),
|
||||
45059: ("ImageUIDList", 7, 0),
|
||||
45058: ("MPEntry", UNDEFINED, 1),
|
||||
45059: ("ImageUIDList", UNDEFINED, 0), # UNDONE, check
|
||||
45060: ("TotalFrames", LONG, 1),
|
||||
45313: ("MPIndividualNum", LONG, 1),
|
||||
45569: ("PanOrientation", LONG, 1),
|
||||
45570: ("PanOverlap_H", RATIONAL, 1),
|
||||
45571: ("PanOverlap_V", RATIONAL, 1),
|
||||
45572: ("BaseViewpointNum", LONG, 1),
|
||||
45573: ("ConvergenceAngle", 10, 1),
|
||||
45573: ("ConvergenceAngle", SIGNED_RATIONAL, 1),
|
||||
45574: ("BaselineLength", RATIONAL, 1),
|
||||
45575: ("VerticalDivergence", 10, 1),
|
||||
45576: ("AxisDistance_X", 10, 1),
|
||||
45577: ("AxisDistance_Y", 10, 1),
|
||||
45578: ("AxisDistance_Z", 10, 1),
|
||||
45579: ("YawAngle", 10, 1),
|
||||
45580: ("PitchAngle", 10, 1),
|
||||
45581: ("RollAngle", 10, 1),
|
||||
45575: ("VerticalDivergence", SIGNED_RATIONAL, 1),
|
||||
45576: ("AxisDistance_X", SIGNED_RATIONAL, 1),
|
||||
45577: ("AxisDistance_Y", SIGNED_RATIONAL, 1),
|
||||
45578: ("AxisDistance_Z", SIGNED_RATIONAL, 1),
|
||||
45579: ("YawAngle", SIGNED_RATIONAL, 1),
|
||||
45580: ("PitchAngle", SIGNED_RATIONAL, 1),
|
||||
45581: ("RollAngle", SIGNED_RATIONAL, 1),
|
||||
|
||||
50741: ("MakerNoteSafety", SHORT, 1, {"Unsafe": 0, "Safe": 1}),
|
||||
50780: ("BestQualityScale", RATIONAL, 1),
|
||||
50838: ("ImageJMetaDataByteCounts", LONG, 1),
|
||||
50839: ("ImageJMetaData", 7, 1)
|
||||
50839: ("ImageJMetaData", UNDEFINED, 1)
|
||||
}
|
||||
|
||||
# Legacy Tags structure
|
||||
|
|
|
@ -287,7 +287,7 @@ class TestFileTiff(PillowTestCase):
|
|||
ifd = TiffImagePlugin.ImageFileDirectory_v2()
|
||||
data = b"abc"
|
||||
ret = ifd.load_byte(data, legacy_api)
|
||||
self.assertEqual(ret, b"abc" if legacy_api else (97, 98, 99))
|
||||
self.assertEqual(ret, b"abc")
|
||||
|
||||
def test_load_string(self):
|
||||
ifd = TiffImagePlugin.ImageFileDirectory_v2()
|
||||
|
|
|
@ -175,7 +175,7 @@ class TestFileTiffMetadata(PillowTestCase):
|
|||
|
||||
im.save(out)
|
||||
reloaded = Image.open(out)
|
||||
self.assert_(type(im.info['icc_profile']) is not type(tuple))
|
||||
self.assert_(type(im.info['icc_profile']) is not tuple)
|
||||
self.assertEqual(im.info['icc_profile'], reloaded.info['icc_profile'])
|
||||
|
||||
def test_iccprofile_binary(self):
|
||||
|
@ -186,6 +186,16 @@ class TestFileTiffMetadata(PillowTestCase):
|
|||
self.assertEqual(im.tag_v2.tagtype[34675], 1)
|
||||
self.assertTrue(im.info['icc_profile'])
|
||||
|
||||
def test_iccprofile_save_png(self):
|
||||
im = Image.open('Tests/images/hopper.iccprofile.tif')
|
||||
outfile = self.tempfile('temp.png')
|
||||
im.save(outfile)
|
||||
|
||||
def test_iccprofile_binary_save_png(self):
|
||||
im = Image.open('Tests/images/hopper.iccprofile_binary.tif')
|
||||
outfile = self.tempfile('temp.png')
|
||||
im.save(outfile)
|
||||
|
||||
def test_exif_div_zero(self):
|
||||
im = hopper()
|
||||
info = TiffImagePlugin.ImageFileDirectory_v2()
|
||||
|
|
|
@ -22,3 +22,12 @@ There are two new options to control the ``build_ext`` task in ``setup.py``:
|
|||
that are checked for libraries and headers for build systems or
|
||||
cross compilers that specify that information in via environment
|
||||
variables.
|
||||
|
||||
|
||||
Image Metadata
|
||||
==============
|
||||
|
||||
The return type for binary data in version 2 Exif and Tiff metadata
|
||||
has been changed from a tuple of integers to bytes. This is a change
|
||||
from the behavior since ``3.0.0``.
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user