mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-27 00:13:27 +03:00
Merge pull request #827 from hugovk/test_file_tiff
More tests for TiffImagePlugin
This commit is contained in:
commit
ab1bbb07c3
|
@ -49,7 +49,8 @@ from PIL import _binary
|
||||||
from PIL._util import isStringType
|
from PIL._util import isStringType
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
import array, sys
|
import array
|
||||||
|
import sys
|
||||||
import collections
|
import collections
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
|
@ -58,8 +59,8 @@ import os
|
||||||
READ_LIBTIFF = False
|
READ_LIBTIFF = False
|
||||||
WRITE_LIBTIFF = False
|
WRITE_LIBTIFF = False
|
||||||
|
|
||||||
II = b"II" # little-endian (intel-style)
|
II = b"II" # little-endian (Intel style)
|
||||||
MM = b"MM" # big-endian (motorola-style)
|
MM = b"MM" # big-endian (Motorola style)
|
||||||
|
|
||||||
i8 = _binary.i8
|
i8 = _binary.i8
|
||||||
o8 = _binary.o8
|
o8 = _binary.o8
|
||||||
|
@ -164,7 +165,7 @@ OPEN_INFO = {
|
||||||
(II, 2, 1, 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"),
|
(II, 2, 1, 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"),
|
||||||
(II, 2, 1, 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"),
|
(II, 2, 1, 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"),
|
||||||
(II, 2, 1, 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
|
(II, 2, 1, 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
|
||||||
(II, 2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10
|
(II, 2, 1, 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10
|
||||||
(II, 3, 1, 1, (1,), ()): ("P", "P;1"),
|
(II, 3, 1, 1, (1,), ()): ("P", "P;1"),
|
||||||
(II, 3, 1, 2, (1,), ()): ("P", "P;1R"),
|
(II, 3, 1, 2, (1,), ()): ("P", "P;1R"),
|
||||||
(II, 3, 1, 1, (2,), ()): ("P", "P;2"),
|
(II, 3, 1, 1, (2,), ()): ("P", "P;2"),
|
||||||
|
@ -196,7 +197,7 @@ OPEN_INFO = {
|
||||||
(MM, 2, 1, 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"),
|
(MM, 2, 1, 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"),
|
||||||
(MM, 2, 1, 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"),
|
(MM, 2, 1, 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"),
|
||||||
(MM, 2, 1, 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
|
(MM, 2, 1, 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
|
||||||
(MM, 2, 1, 1, (8,8,8,8), (999,)): ("RGBA", "RGBA"), # corel draw 10
|
(MM, 2, 1, 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10
|
||||||
(MM, 3, 1, 1, (1,), ()): ("P", "P;1"),
|
(MM, 3, 1, 1, (1,), ()): ("P", "P;1"),
|
||||||
(MM, 3, 1, 2, (1,), ()): ("P", "P;1R"),
|
(MM, 3, 1, 2, (1,), ()): ("P", "P;1R"),
|
||||||
(MM, 3, 1, 1, (2,), ()): ("P", "P;2"),
|
(MM, 3, 1, 1, (2,), ()): ("P", "P;2"),
|
||||||
|
@ -214,9 +215,11 @@ OPEN_INFO = {
|
||||||
|
|
||||||
PREFIXES = [b"MM\000\052", b"II\052\000", b"II\xBC\000"]
|
PREFIXES = [b"MM\000\052", b"II\052\000", b"II\xBC\000"]
|
||||||
|
|
||||||
|
|
||||||
def _accept(prefix):
|
def _accept(prefix):
|
||||||
return prefix[:4] in PREFIXES
|
return prefix[:4] in PREFIXES
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Wrapper for TIFF IFDs.
|
# Wrapper for TIFF IFDs.
|
||||||
|
|
||||||
|
@ -287,7 +290,9 @@ class ImageFileDirectory(collections.MutableMapping):
|
||||||
return dict(self.items())
|
return dict(self.items())
|
||||||
|
|
||||||
def named(self):
|
def named(self):
|
||||||
"""Returns the complete tag dictionary, with named tags where posible."""
|
"""
|
||||||
|
Returns the complete tag dictionary, with named tags where posible.
|
||||||
|
"""
|
||||||
from PIL import TiffTags
|
from PIL import TiffTags
|
||||||
result = {}
|
result = {}
|
||||||
for tag_code, value in self.items():
|
for tag_code, value in self.items():
|
||||||
|
@ -295,7 +300,6 @@ class ImageFileDirectory(collections.MutableMapping):
|
||||||
result[tag_name] = value
|
result[tag_name] = value
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
# dictionary API
|
# dictionary API
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
|
@ -449,14 +453,17 @@ class ImageFileDirectory(collections.MutableMapping):
|
||||||
data = ifd[8:8+size]
|
data = ifd[8:8+size]
|
||||||
|
|
||||||
if len(data) != size:
|
if len(data) != size:
|
||||||
warnings.warn("Possibly corrupt EXIF data. Expecting to read %d bytes but only got %d. Skipping tag %s" % (size, len(data), tag))
|
warnings.warn("Possibly corrupt EXIF data. "
|
||||||
|
"Expecting to read %d bytes but only got %d. "
|
||||||
|
"Skipping tag %s" % (size, len(data), tag))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.tagdata[tag] = data
|
self.tagdata[tag] = data
|
||||||
self.tagtype[tag] = typ
|
self.tagtype[tag] = typ
|
||||||
|
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP):
|
if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK,
|
||||||
|
ICCPROFILE, XMP):
|
||||||
print("- value: <table: %d bytes>" % size)
|
print("- value: <table: %d bytes>" % size)
|
||||||
else:
|
else:
|
||||||
print("- value:", self[tag])
|
print("- value:", self[tag])
|
||||||
|
@ -541,7 +548,8 @@ class ImageFileDirectory(collections.MutableMapping):
|
||||||
typname = TiffTags.TYPES.get(typ, "unknown")
|
typname = TiffTags.TYPES.get(typ, "unknown")
|
||||||
print("save: %s (%d)" % (tagname, tag), end=' ')
|
print("save: %s (%d)" % (tagname, tag), end=' ')
|
||||||
print("- type: %s (%d)" % (typname, typ), end=' ')
|
print("- type: %s (%d)" % (typname, typ), end=' ')
|
||||||
if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP):
|
if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK,
|
||||||
|
ICCPROFILE, XMP):
|
||||||
size = len(data)
|
size = len(data)
|
||||||
print("- value: <table: %d bytes>" % size)
|
print("- value: <table: %d bytes>" % size)
|
||||||
else:
|
else:
|
||||||
|
@ -586,6 +594,7 @@ class ImageFileDirectory(collections.MutableMapping):
|
||||||
|
|
||||||
return offset
|
return offset
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Image plugin for TIFF files.
|
# Image plugin for TIFF files.
|
||||||
|
|
||||||
|
@ -694,9 +703,11 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if not len(self.tile) == 1:
|
if not len(self.tile) == 1:
|
||||||
raise IOError("Not exactly one tile")
|
raise IOError("Not exactly one tile")
|
||||||
|
|
||||||
# (self._compression, (extents tuple), 0, (rawmode, self._compression, fp))
|
# (self._compression, (extents tuple),
|
||||||
|
# 0, (rawmode, self._compression, fp))
|
||||||
ignored, extents, ignored_2, args = self.tile[0]
|
ignored, extents, ignored_2, args = self.tile[0]
|
||||||
decoder = Image._getdecoder(self.mode, 'libtiff', args, self.decoderconfig)
|
decoder = Image._getdecoder(self.mode, 'libtiff', args,
|
||||||
|
self.decoderconfig)
|
||||||
try:
|
try:
|
||||||
decoder.setimage(self.im, extents)
|
decoder.setimage(self.im, extents)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -706,12 +717,12 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
# We've got a stringio like thing passed in. Yay for all in memory.
|
# We've got a stringio like thing passed in. Yay for all in memory.
|
||||||
# The decoder needs the entire file in one shot, so there's not
|
# The decoder needs the entire file in one shot, so there's not
|
||||||
# a lot we can do here other than give it the entire file.
|
# a lot we can do here other than give it the entire file.
|
||||||
# unless we could do something like get the address of the underlying
|
# unless we could do something like get the address of the
|
||||||
# string for stringio.
|
# underlying string for stringio.
|
||||||
#
|
#
|
||||||
# Rearranging for supporting byteio items, since they have a fileno
|
# Rearranging for supporting byteio items, since they have a fileno
|
||||||
# that returns an IOError if there's no underlying fp. Easier to deal
|
# that returns an IOError if there's no underlying fp. Easier to
|
||||||
# with here by reordering.
|
# dea. with here by reordering.
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
print ("have getvalue. just sending in a string from getvalue")
|
print ("have getvalue. just sending in a string from getvalue")
|
||||||
n, err = decoder.decode(self.fp.getvalue())
|
n, err = decoder.decode(self.fp.getvalue())
|
||||||
|
@ -720,7 +731,8 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
print ("have fileno, calling fileno version of the decoder.")
|
print ("have fileno, calling fileno version of the decoder.")
|
||||||
self.fp.seek(0)
|
self.fp.seek(0)
|
||||||
n,err = decoder.decode(b"fpfp") # 4 bytes, otherwise the trace might error out
|
# 4 bytes, otherwise the trace might error out
|
||||||
|
n, err = decoder.decode(b"fpfp")
|
||||||
else:
|
else:
|
||||||
# we have something else.
|
# we have something else.
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
|
@ -728,7 +740,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
# UNDONE -- so much for that buffer size thing.
|
# UNDONE -- so much for that buffer size thing.
|
||||||
n, err = decoder.decode(self.fp.read())
|
n, err = decoder.decode(self.fp.read())
|
||||||
|
|
||||||
|
|
||||||
self.tile = []
|
self.tile = []
|
||||||
self.readonly = 0
|
self.readonly = 0
|
||||||
# libtiff closed the fp in a, we need to close self.fp, if possible
|
# libtiff closed the fp in a, we need to close self.fp, if possible
|
||||||
|
@ -825,13 +836,16 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
offsets = self.tag[STRIPOFFSETS]
|
offsets = self.tag[STRIPOFFSETS]
|
||||||
h = getscalar(ROWSPERSTRIP, ysize)
|
h = getscalar(ROWSPERSTRIP, ysize)
|
||||||
w = self.size[0]
|
w = self.size[0]
|
||||||
if READ_LIBTIFF or self._compression in ["tiff_ccitt", "group3", "group4",
|
if READ_LIBTIFF or self._compression in ["tiff_ccitt", "group3",
|
||||||
"tiff_jpeg", "tiff_adobe_deflate",
|
"group4", "tiff_jpeg",
|
||||||
"tiff_thunderscan", "tiff_deflate",
|
"tiff_adobe_deflate",
|
||||||
"tiff_sgilog", "tiff_sgilog24",
|
"tiff_thunderscan",
|
||||||
|
"tiff_deflate",
|
||||||
|
"tiff_sgilog",
|
||||||
|
"tiff_sgilog24",
|
||||||
"tiff_raw_16"]:
|
"tiff_raw_16"]:
|
||||||
## if Image.DEBUG:
|
# if Image.DEBUG:
|
||||||
## print "Activating g4 compression for whole file"
|
# print "Activating g4 compression for whole file"
|
||||||
|
|
||||||
# Decoder expects entire file as one tile.
|
# Decoder expects entire file as one tile.
|
||||||
# There's a buffer size limit in load (64k)
|
# There's a buffer size limit in load (64k)
|
||||||
|
@ -850,7 +864,8 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
# libtiff closes the file descriptor, so pass in a dup.
|
# libtiff closes the file descriptor, so pass in a dup.
|
||||||
try:
|
try:
|
||||||
fp = hasattr(self.fp, "fileno") and os.dup(self.fp.fileno())
|
fp = hasattr(self.fp, "fileno") and \
|
||||||
|
os.dup(self.fp.fileno())
|
||||||
except IOError:
|
except IOError:
|
||||||
# io.BytesIO have a fileno, but returns an IOError if
|
# io.BytesIO have a fileno, but returns an IOError if
|
||||||
# it doesn't use a file descriptor.
|
# it doesn't use a file descriptor.
|
||||||
|
@ -937,10 +952,12 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Write TIFF files
|
# Write TIFF files
|
||||||
|
|
||||||
# little endian is default except for image modes with explict big endian byte-order
|
# little endian is default except for image modes with
|
||||||
|
# explict big endian byte-order
|
||||||
|
|
||||||
SAVE_INFO = {
|
SAVE_INFO = {
|
||||||
# mode => rawmode, byteorder, photometrics, sampleformat, bitspersample, extra
|
# mode => rawmode, byteorder, photometrics,
|
||||||
|
# sampleformat, bitspersample, extra
|
||||||
"1": ("1", II, 1, 1, (1,), None),
|
"1": ("1", II, 1, 1, (1,), None),
|
||||||
"L": ("L", II, 1, 1, (8,), None),
|
"L": ("L", II, 1, 1, (8,), None),
|
||||||
"LA": ("LA", II, 1, 1, (8, 8), 2),
|
"LA": ("LA", II, 1, 1, (8, 8), 2),
|
||||||
|
@ -963,6 +980,7 @@ SAVE_INFO = {
|
||||||
"F;32BF": ("F;32BF", MM, 1, 3, (32,), None),
|
"F;32BF": ("F;32BF", MM, 1, 3, (32,), None),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _cvt_res(value):
|
def _cvt_res(value):
|
||||||
# convert value to TIFF rational number -- (numerator, denominator)
|
# convert value to TIFF rational number -- (numerator, denominator)
|
||||||
if isinstance(value, collections.Sequence):
|
if isinstance(value, collections.Sequence):
|
||||||
|
@ -973,6 +991,7 @@ def _cvt_res(value):
|
||||||
value = float(value)
|
value = float(value)
|
||||||
return (int(value * 65536), 65536)
|
return (int(value * 65536), 65536)
|
||||||
|
|
||||||
|
|
||||||
def _save(im, fp, filename):
|
def _save(im, fp, filename):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -982,7 +1001,8 @@ def _save(im, fp, filename):
|
||||||
|
|
||||||
ifd = ImageFileDirectory(prefix)
|
ifd = ImageFileDirectory(prefix)
|
||||||
|
|
||||||
compression = im.encoderinfo.get('compression',im.info.get('compression','raw'))
|
compression = im.encoderinfo.get('compression', im.info.get('compression',
|
||||||
|
'raw'))
|
||||||
|
|
||||||
libtiff = WRITE_LIBTIFF or compression != 'raw'
|
libtiff = WRITE_LIBTIFF or compression != 'raw'
|
||||||
|
|
||||||
|
@ -1010,7 +1030,6 @@ def _save(im, fp, filename):
|
||||||
except:
|
except:
|
||||||
pass # might not be an IFD, Might not have populated type
|
pass # might not be an IFD, Might not have populated type
|
||||||
|
|
||||||
|
|
||||||
# additions written by Greg Couch, gregc@cgl.ucsf.edu
|
# additions written by Greg Couch, gregc@cgl.ucsf.edu
|
||||||
# inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com
|
# inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com
|
||||||
if hasattr(im, 'tag'):
|
if hasattr(im, 'tag'):
|
||||||
|
@ -1078,7 +1097,8 @@ def _save(im, fp, filename):
|
||||||
ifd[ROWSPERSTRIP] = im.size[1]
|
ifd[ROWSPERSTRIP] = im.size[1]
|
||||||
ifd[STRIPBYTECOUNTS] = stride * im.size[1]
|
ifd[STRIPBYTECOUNTS] = stride * im.size[1]
|
||||||
ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer
|
ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer
|
||||||
ifd[COMPRESSION] = COMPRESSION_INFO_REV.get(compression,1) # no compression by default
|
# no compression by default:
|
||||||
|
ifd[COMPRESSION] = COMPRESSION_INFO_REV.get(compression, 1)
|
||||||
|
|
||||||
if libtiff:
|
if libtiff:
|
||||||
if Image.DEBUG:
|
if Image.DEBUG:
|
||||||
|
@ -1089,23 +1109,27 @@ def _save(im, fp, filename):
|
||||||
fp.seek(0)
|
fp.seek(0)
|
||||||
_fp = os.dup(fp.fileno())
|
_fp = os.dup(fp.fileno())
|
||||||
|
|
||||||
blocklist = [STRIPOFFSETS, STRIPBYTECOUNTS, ROWSPERSTRIP, ICCPROFILE] # ICC Profile crashes.
|
# ICC Profile crashes.
|
||||||
|
blocklist = [STRIPOFFSETS, STRIPBYTECOUNTS, ROWSPERSTRIP, ICCPROFILE]
|
||||||
atts = {}
|
atts = {}
|
||||||
# bits per sample is a single short in the tiff directory, not a list.
|
# bits per sample is a single short in the tiff directory, not a list.
|
||||||
atts[BITSPERSAMPLE] = bits[0]
|
atts[BITSPERSAMPLE] = bits[0]
|
||||||
# Merge the ones that we have with (optional) more bits from
|
# Merge the ones that we have with (optional) more bits from
|
||||||
# the original file, e.g x,y resolution so that we can
|
# the original file, e.g x,y resolution so that we can
|
||||||
# save(load('')) == original file.
|
# save(load('')) == original file.
|
||||||
for k,v in itertools.chain(ifd.items(), getattr(im, 'ifd', {}).items()):
|
for k, v in itertools.chain(ifd.items(),
|
||||||
|
getattr(im, 'ifd', {}).items()):
|
||||||
if k not in atts and k not in blocklist:
|
if k not in atts and k not in blocklist:
|
||||||
if type(v[0]) == tuple and len(v) > 1:
|
if type(v[0]) == tuple and len(v) > 1:
|
||||||
# A tuple of more than one rational tuples
|
# A tuple of more than one rational tuples
|
||||||
# flatten to floats, following tiffcp.c->cpTag->TIFF_RATIONAL
|
# flatten to floats,
|
||||||
|
# following tiffcp.c->cpTag->TIFF_RATIONAL
|
||||||
atts[k] = [float(elt[0])/float(elt[1]) for elt in v]
|
atts[k] = [float(elt[0])/float(elt[1]) for elt in v]
|
||||||
continue
|
continue
|
||||||
if type(v[0]) == tuple and len(v) == 1:
|
if type(v[0]) == tuple and len(v) == 1:
|
||||||
# A tuple of one rational tuples
|
# A tuple of one rational tuples
|
||||||
# flatten to floats, following tiffcp.c->cpTag->TIFF_RATIONAL
|
# flatten to floats,
|
||||||
|
# following tiffcp.c->cpTag->TIFF_RATIONAL
|
||||||
atts[k] = float(v[0][0])/float(v[0][1])
|
atts[k] = float(v[0][0])/float(v[0][1])
|
||||||
continue
|
continue
|
||||||
if type(v) == tuple and len(v) > 2:
|
if type(v) == tuple and len(v) > 2:
|
||||||
|
@ -1115,7 +1139,8 @@ def _save(im, fp, filename):
|
||||||
continue
|
continue
|
||||||
if type(v) == tuple and len(v) == 2:
|
if type(v) == tuple and len(v) == 2:
|
||||||
# one rational tuple
|
# one rational tuple
|
||||||
# flatten to float, following tiffcp.c->cpTag->TIFF_RATIONAL
|
# flatten to float,
|
||||||
|
# following tiffcp.c->cpTag->TIFF_RATIONAL
|
||||||
atts[k] = float(v[0])/float(v[1])
|
atts[k] = float(v[0])/float(v[1])
|
||||||
continue
|
continue
|
||||||
if type(v) == tuple and len(v) == 1:
|
if type(v) == tuple and len(v) == 1:
|
||||||
|
@ -1143,7 +1168,8 @@ def _save(im, fp, filename):
|
||||||
e = Image._getencoder(im.mode, 'libtiff', a, im.encoderconfig)
|
e = Image._getencoder(im.mode, 'libtiff', a, im.encoderconfig)
|
||||||
e.setimage(im.im, (0, 0)+im.size)
|
e.setimage(im.im, (0, 0)+im.size)
|
||||||
while True:
|
while True:
|
||||||
l, s, d = e.encode(16*1024) # undone, change to self.decodermaxblock
|
# undone, change to self.decodermaxblock:
|
||||||
|
l, s, d = e.encode(16*1024)
|
||||||
if not _fp:
|
if not _fp:
|
||||||
fp.write(d)
|
fp.write(d)
|
||||||
if s:
|
if s:
|
||||||
|
@ -1158,7 +1184,6 @@ def _save(im, fp, filename):
|
||||||
("raw", (0, 0)+im.size, offset, (rawmode, stride, 1))
|
("raw", (0, 0)+im.size, offset, (rawmode, stride, 1))
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
# -- helper for multi-page save --
|
# -- helper for multi-page save --
|
||||||
if "_debug_multipage" in im.encoderinfo:
|
if "_debug_multipage" in im.encoderinfo:
|
||||||
# just to access o32 and o16 (using correct byte order)
|
# just to access o32 and o16 (using correct byte order)
|
||||||
|
|
|
@ -141,6 +141,137 @@ class TestFileTiff(PillowTestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
im.getextrema(), (-3.140936851501465, 3.140684127807617))
|
im.getextrema(), (-3.140936851501465, 3.140684127807617))
|
||||||
|
|
||||||
|
def test___str__(self):
|
||||||
|
# Arrange
|
||||||
|
file = "Tests/images/pil136.tiff"
|
||||||
|
im = Image.open(file)
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = str(im.ifd)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertIsInstance(ret, str)
|
||||||
|
self.assertEqual(
|
||||||
|
ret,
|
||||||
|
'{256: (55,), 257: (43,), 258: (8, 8, 8, 8), 259: (1,), '
|
||||||
|
'262: (2,), 296: (2,), 273: (8,), 338: (1,), 277: (4,), '
|
||||||
|
'279: (9460,), 282: ((720000, 10000),), '
|
||||||
|
'283: ((720000, 10000),), 284: (1,)}')
|
||||||
|
|
||||||
|
def test__delitem__(self):
|
||||||
|
# Arrange
|
||||||
|
file = "Tests/images/pil136.tiff"
|
||||||
|
im = Image.open(file)
|
||||||
|
len_before = len(im.ifd.as_dict())
|
||||||
|
|
||||||
|
# Act
|
||||||
|
del im.ifd[256]
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
len_after = len(im.ifd.as_dict())
|
||||||
|
self.assertEqual(len_before, len_after + 1)
|
||||||
|
|
||||||
|
def test_load_byte(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL import TiffImagePlugin
|
||||||
|
ifd = TiffImagePlugin.ImageFileDirectory()
|
||||||
|
data = b"abc"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = ifd.load_byte(data)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, b"abc")
|
||||||
|
|
||||||
|
def test_load_string(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL import TiffImagePlugin
|
||||||
|
ifd = TiffImagePlugin.ImageFileDirectory()
|
||||||
|
data = b"abc\0"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = ifd.load_string(data)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, "abc")
|
||||||
|
|
||||||
|
def test_load_float(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL import TiffImagePlugin
|
||||||
|
ifd = TiffImagePlugin.ImageFileDirectory()
|
||||||
|
data = b"abcdabcd"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = ifd.load_float(data)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, (1.6777999408082104e+22, 1.6777999408082104e+22))
|
||||||
|
|
||||||
|
def test_load_double(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL import TiffImagePlugin
|
||||||
|
ifd = TiffImagePlugin.ImageFileDirectory()
|
||||||
|
data = b"abcdefghabcdefgh"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = ifd.load_double(data)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, (8.540883223036124e+194, 8.540883223036124e+194))
|
||||||
|
|
||||||
|
def test_seek(self):
|
||||||
|
# Arrange
|
||||||
|
file = "Tests/images/pil136.tiff"
|
||||||
|
im = Image.open(file)
|
||||||
|
|
||||||
|
# Act
|
||||||
|
im.seek(-1)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(im.tell(), 0)
|
||||||
|
|
||||||
|
def test_seek_eof(self):
|
||||||
|
# Arrange
|
||||||
|
file = "Tests/images/pil136.tiff"
|
||||||
|
im = Image.open(file)
|
||||||
|
self.assertEqual(im.tell(), 0)
|
||||||
|
|
||||||
|
# Act / Assert
|
||||||
|
self.assertRaises(EOFError, lambda: im.seek(1))
|
||||||
|
|
||||||
|
def test__cvt_res_int(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL.TiffImagePlugin import _cvt_res
|
||||||
|
value = 34
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = _cvt_res(value)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, (34, 1))
|
||||||
|
|
||||||
|
def test__cvt_res_float(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL.TiffImagePlugin import _cvt_res
|
||||||
|
value = 22.3
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = _cvt_res(value)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, (1461452, 65536))
|
||||||
|
|
||||||
|
def test__cvt_res_sequence(self):
|
||||||
|
# Arrange
|
||||||
|
from PIL.TiffImagePlugin import _cvt_res
|
||||||
|
value = [0, 1]
|
||||||
|
|
||||||
|
# Act
|
||||||
|
ret = _cvt_res(value)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(ret, [0, 1])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user