This commit is contained in:
hugovk 2017-05-27 23:55:14 +03:00
parent c3ed7447cc
commit c70eb8a128
3 changed files with 33 additions and 25 deletions

View File

@ -127,7 +127,7 @@ def APP(self, marker):
dpi = x_resolution[0] / x_resolution[1] dpi = x_resolution[0] / x_resolution[1]
except TypeError: except TypeError:
dpi = x_resolution dpi = x_resolution
if resolution_unit == 3: # cm if resolution_unit == 3: # cm
# 1 dpcm = 2.54 dpi # 1 dpcm = 2.54 dpi
dpi *= 2.54 dpi *= 2.54
self.info["dpi"] = dpi, dpi self.info["dpi"] = dpi, dpi
@ -423,7 +423,8 @@ def _fixup_dict(src_dict):
try: try:
if len(value) == 1 and not isinstance(value, dict): if len(value) == 1 and not isinstance(value, dict):
return value[0] return value[0]
except: pass except:
pass
return value return value
return {k: _fixup(v) for k, v in src_dict.items()} return {k: _fixup(v) for k, v in src_dict.items()}
@ -696,8 +697,8 @@ def _save(im, fp, filename):
# "progressive" is the official name, but older documentation # "progressive" is the official name, but older documentation
# says "progression" # says "progression"
# FIXME: issue a warning if the wrong form is used (post-1.1.7) # FIXME: issue a warning if the wrong form is used (post-1.1.7)
progressive = info.get("progressive", False) or\ progressive = (info.get("progressive", False) or
info.get("progression", False) info.get("progression", False))
optimize = info.get("optimize", False) optimize = info.get("optimize", False)

View File

@ -242,6 +242,7 @@ def _limit_rational(val, max_val):
n_d = IFDRational(1 / val if inv else val).limit_rational(max_val) n_d = IFDRational(1 / val if inv else val).limit_rational(max_val)
return n_d[::-1] if inv else n_d return n_d[::-1] if inv else n_d
## ##
# Wrapper for TIFF IFDs. # Wrapper for TIFF IFDs.
@ -526,7 +527,8 @@ class ImageFileDirectory_v2(collections.MutableMapping):
self.tagtype[tag] = 2 self.tagtype[tag] = 2
if self.tagtype[tag] == 7 and bytes is not str: if self.tagtype[tag] == 7 and bytes is not str:
values = [value.encode("ascii", 'replace') if isinstance(value, str) else value] values = [value.encode("ascii", 'replace') if isinstance(
value, str) else value]
values = tuple(info.cvt_enum(value) for value in values) values = tuple(info.cvt_enum(value) for value in values)
@ -579,9 +581,13 @@ class ImageFileDirectory_v2(collections.MutableMapping):
b"".join(self._pack(fmt, value) for value in values)) b"".join(self._pack(fmt, value) for value in values))
list(map(_register_basic, list(map(_register_basic,
[(3, "H", "short"), (4, "L", "long"), [(3, "H", "short"),
(6, "b", "signed byte"), (8, "h", "signed short"), (4, "L", "long"),
(9, "l", "signed long"), (11, "f", "float"), (12, "d", "double")])) (6, "b", "signed byte"),
(8, "h", "signed short"),
(9, "l", "signed long"),
(11, "f", "float"),
(12, "d", "double")]))
@_register_loader(1, 1) # Basic type, except for the legacy API. @_register_loader(1, 1) # Basic type, except for the legacy API.
def load_byte(self, data, legacy_api=True): def load_byte(self, data, legacy_api=True):
@ -653,7 +659,8 @@ class ImageFileDirectory_v2(collections.MutableMapping):
try: try:
for i in range(self._unpack("H", self._ensure_read(fp, 2))[0]): for i in range(self._unpack("H", self._ensure_read(fp, 2))[0]):
tag, typ, count, data = self._unpack("HHL4s", self._ensure_read(fp, 12)) tag, typ, count, data = self._unpack("HHL4s",
self._ensure_read(fp, 12))
if DEBUG: if DEBUG:
tagname = TiffTags.lookup(tag).name tagname = TiffTags.lookup(tag).name
typname = TYPES.get(typ, "unknown") typname = TYPES.get(typ, "unknown")
@ -681,8 +688,8 @@ class ImageFileDirectory_v2(collections.MutableMapping):
if len(data) != size: if len(data) != size:
warnings.warn("Possibly corrupt EXIF data. " warnings.warn("Possibly corrupt EXIF data. "
"Expecting to read %d bytes but only got %d. " "Expecting to read %d bytes but only got %d."
"Skipping tag %s" % (size, len(data), tag)) " Skipping tag %s" % (size, len(data), tag))
continue continue
if not data: if not data:
@ -741,7 +748,8 @@ class ImageFileDirectory_v2(collections.MutableMapping):
if len(data) <= 4: if len(data) <= 4:
entries.append((tag, typ, count, data.ljust(4, b"\0"), b"")) entries.append((tag, typ, count, data.ljust(4, b"\0"), b""))
else: else:
entries.append((tag, typ, count, self._pack("L", offset), data)) entries.append((tag, typ, count, self._pack("L", offset),
data))
offset += (len(data) + 1) // 2 * 2 # pad to word offset += (len(data) + 1) // 2 * 2 # pad to word
# update strip offset data to point beyond auxiliary data # update strip offset data to point beyond auxiliary data
@ -770,6 +778,7 @@ class ImageFileDirectory_v2(collections.MutableMapping):
return offset return offset
ImageFileDirectory_v2._load_dispatch = _load_dispatch ImageFileDirectory_v2._load_dispatch = _load_dispatch
ImageFileDirectory_v2._write_dispatch = _write_dispatch ImageFileDirectory_v2._write_dispatch = _write_dispatch
for idx, name in TYPES.items(): for idx, name in TYPES.items():
@ -1169,7 +1178,8 @@ class TiffImageFile(ImageFile.ImageFile):
self.info["dpi"] = xres * 2.54, yres * 2.54 self.info["dpi"] = xres * 2.54, yres * 2.54
elif resunit is None: # used to default to 1, but now 2) elif resunit is None: # used to default to 1, but now 2)
self.info["dpi"] = xres, yres self.info["dpi"] = xres, yres
# For backward compatibility, we also preserve the old behavior. # For backward compatibility,
# we also preserve the old behavior
self.info["resolution"] = xres, yres self.info["resolution"] = xres, yres
else: # No absolute unit of measurement else: # No absolute unit of measurement
self.info["resolution"] = xres, yres self.info["resolution"] = xres, yres
@ -1285,6 +1295,8 @@ class TiffImageFile(ImageFile.ImageFile):
if self.mode == "P": if self.mode == "P":
palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]] palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]]
self.palette = ImagePalette.raw("RGB;L", b"".join(palette)) self.palette = ImagePalette.raw("RGB;L", b"".join(palette))
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Write TIFF files # Write TIFF files
@ -1673,13 +1685,10 @@ class AppendingTiffWriter:
def fixIFD(self): def fixIFD(self):
numTags = self.readShort() numTags = self.readShort()
# trace("fixing IFD at %X; number of tags: %u (0x%X)", self.f.tell()-2,
# numTags, numTags)
for i in range(numTags): for i in range(numTags):
tag, fieldType, count = struct.unpack(self.tagFormat, self.f.read(8)) tag, fieldType, count = struct.unpack(self.tagFormat,
# trace(" at %X: tag %u (0x%X), type %u, count %u", self.f.tell()-8, self.f.read(8))
# tag, tag, fieldType, count)
fieldSize = self.fieldSizes[fieldType] fieldSize = self.fieldSizes[fieldType]
totalSize = fieldSize * count totalSize = fieldSize * count
@ -1747,6 +1756,7 @@ def _save_all(im, fp, filename):
finally: finally:
im.seek(cur_idx) im.seek(cur_idx)
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Register # Register

View File

@ -6,6 +6,7 @@ import sys
from helper import unittest, PillowTestCase, hopper, py3 from helper import unittest, PillowTestCase, hopper, py3
from PIL import Image, TiffImagePlugin from PIL import Image, TiffImagePlugin
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION, RESOLUTION_UNIT
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -77,7 +78,6 @@ class TestFileTiff(PillowTestCase):
self.assertEqual(im.mode, 'RGB') self.assertEqual(im.mode, 'RGB')
def test_xyres_tiff(self): def test_xyres_tiff(self):
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION
filename = "Tests/images/pil168.tif" filename = "Tests/images/pil168.tif"
im = Image.open(filename) im = Image.open(filename)
@ -94,7 +94,6 @@ class TestFileTiff(PillowTestCase):
self.assertEqual(im.info['dpi'], (72., 72.)) self.assertEqual(im.info['dpi'], (72., 72.))
def test_xyres_fallback_tiff(self): def test_xyres_fallback_tiff(self):
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION, RESOLUTION_UNIT
filename = "Tests/images/compression.tif" filename = "Tests/images/compression.tif"
im = Image.open(filename) im = Image.open(filename)
@ -112,7 +111,6 @@ class TestFileTiff(PillowTestCase):
self.assertEqual(im.info['dpi'], (100., 100.)) self.assertEqual(im.info['dpi'], (100., 100.))
def test_int_resolution(self): def test_int_resolution(self):
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION
filename = "Tests/images/pil168.tif" filename = "Tests/images/pil168.tif"
im = Image.open(filename) im = Image.open(filename)
@ -123,7 +121,6 @@ class TestFileTiff(PillowTestCase):
self.assertEqual(im.info['dpi'], (71., 71.)) self.assertEqual(im.info['dpi'], (71., 71.))
def test_save_setting_missing_resolution(self): def test_save_setting_missing_resolution(self):
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION
b = BytesIO() b = BytesIO()
Image.open("Tests/images/10ct_32bit_128.tiff").save( Image.open("Tests/images/10ct_32bit_128.tiff").save(
b, format="tiff", resolution=123.45) b, format="tiff", resolution=123.45)
@ -447,8 +444,8 @@ class TestFileTiff(PillowTestCase):
def test_saving_icc_profile(self): def test_saving_icc_profile(self):
# Tests saving TIFF with icc_profile set. # Tests saving TIFF with icc_profile set.
# At the time of writing this will only work for non-compressed tiffs # At the time of writing this will only work for non-compressed tiffs
# as libtiff does not support embedded ICC profiles, ImageFile._save(..) # as libtiff does not support embedded ICC profiles,
# however does. # ImageFile._save(..) however does.
im = Image.new('RGB', (1, 1)) im = Image.new('RGB', (1, 1))
im.info['icc_profile'] = 'Dummy value' im.info['icc_profile'] = 'Dummy value'
@ -486,7 +483,6 @@ class TestFileTiff(PillowTestCase):
self.assertFalse(fp.closed) self.assertFalse(fp.closed)
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only") @unittest.skipUnless(sys.platform.startswith('win32'), "Windows only")
class TestFileTiffW32(PillowTestCase): class TestFileTiffW32(PillowTestCase):
def test_fd_leak(self): def test_fd_leak(self):
@ -511,5 +507,6 @@ class TestFileTiffW32(PillowTestCase):
# and close should have closed the mmap # and close should have closed the mmap
os.remove(tmpfile) os.remove(tmpfile)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()