mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-12 02:06:18 +03:00
Flake8 fixes
This commit is contained in:
parent
17a111cba7
commit
37b293f593
|
@ -131,7 +131,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
||||||
# ----------------- Process BMP with Bitfields compression (not palette)
|
# ----------------- Process BMP with Bitfields compression (not palette)
|
||||||
if file_info['compression'] == self.BITFIELDS:
|
if file_info['compression'] == self.BITFIELDS:
|
||||||
SUPPORTED = {
|
SUPPORTED = {
|
||||||
32: [(0xff0000, 0xff00, 0xff, 0x0), (0xff0000, 0xff00, 0xff, 0xff000000), (0x0, 0x0, 0x0, 0x0), (0xff000000, 0xff0000, 0xff00, 0x0) ],
|
32: [(0xff0000, 0xff00, 0xff, 0x0), (0xff0000, 0xff00, 0xff, 0xff000000), (0x0, 0x0, 0x0, 0x0), (0xff000000, 0xff0000, 0xff00, 0x0)],
|
||||||
24: [(0xff0000, 0xff00, 0xff)],
|
24: [(0xff0000, 0xff00, 0xff)],
|
||||||
16: [(0xf800, 0x7e0, 0x1f), (0x7c00, 0x3e0, 0x1f)]
|
16: [(0xf800, 0x7e0, 0x1f), (0x7c00, 0x3e0, 0x1f)]
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,7 +307,7 @@ def _normalize_mode(im, initial_call=False):
|
||||||
UNDONE: What is the point of mucking with the initial call palette, for
|
UNDONE: What is the point of mucking with the initial call palette, for
|
||||||
an image that shouldn't have a palette, or it would be a mode 'P' and
|
an image that shouldn't have a palette, or it would be a mode 'P' and
|
||||||
get returned in the RAWMODE clause.
|
get returned in the RAWMODE clause.
|
||||||
|
|
||||||
:param im: Image object
|
:param im: Image object
|
||||||
:param initial_call: Default false, set to true for a single frame.
|
:param initial_call: Default false, set to true for a single frame.
|
||||||
:returns: Image object
|
:returns: Image object
|
||||||
|
@ -325,6 +325,7 @@ def _normalize_mode(im, initial_call=False):
|
||||||
return im.convert("P")
|
return im.convert("P")
|
||||||
return im.convert("L")
|
return im.convert("L")
|
||||||
|
|
||||||
|
|
||||||
def _normalize_palette(im, palette, info):
|
def _normalize_palette(im, palette, info):
|
||||||
"""
|
"""
|
||||||
Normalizes the palette for image.
|
Normalizes the palette for image.
|
||||||
|
@ -334,7 +335,7 @@ def _normalize_palette(im, palette, info):
|
||||||
|
|
||||||
:param im: Image object
|
:param im: Image object
|
||||||
:param palette: bytes object containing the source palette, or ....
|
:param palette: bytes object containing the source palette, or ....
|
||||||
:param info: encoderinfo
|
:param info: encoderinfo
|
||||||
:returns: Image object
|
:returns: Image object
|
||||||
"""
|
"""
|
||||||
source_palette = None
|
source_palette = None
|
||||||
|
@ -347,7 +348,7 @@ def _normalize_palette(im, palette, info):
|
||||||
zip(palette.palette[:256],
|
zip(palette.palette[:256],
|
||||||
palette.palette[256:512],
|
palette.palette[256:512],
|
||||||
palette.palette[512:768])))
|
palette.palette[512:768])))
|
||||||
|
|
||||||
if im.mode == "P":
|
if im.mode == "P":
|
||||||
if not source_palette:
|
if not source_palette:
|
||||||
source_palette = im.im.getpalette("RGB")[:768]
|
source_palette = im.im.getpalette("RGB")[:768]
|
||||||
|
@ -364,6 +365,7 @@ def _normalize_palette(im, palette, info):
|
||||||
im.palette.palette = source_palette
|
im.palette.palette = source_palette
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
|
||||||
def _write_single_frame(im, fp, palette):
|
def _write_single_frame(im, fp, palette):
|
||||||
im_out = _normalize_mode(im, True)
|
im_out = _normalize_mode(im, True)
|
||||||
im_out = _normalize_palette(im_out, palette, im.encoderinfo)
|
im_out = _normalize_palette(im_out, palette, im.encoderinfo)
|
||||||
|
@ -383,6 +385,7 @@ def _write_single_frame(im, fp, palette):
|
||||||
|
|
||||||
fp.write(b"\0") # end of image data
|
fp.write(b"\0") # end of image data
|
||||||
|
|
||||||
|
|
||||||
def _write_multiple_frames(im, fp, palette):
|
def _write_multiple_frames(im, fp, palette):
|
||||||
|
|
||||||
duration = im.encoderinfo.get("duration", None)
|
duration = im.encoderinfo.get("duration", None)
|
||||||
|
@ -418,9 +421,9 @@ def _write_multiple_frames(im, fp, palette):
|
||||||
else:
|
else:
|
||||||
bbox = None
|
bbox = None
|
||||||
im_frames.append({
|
im_frames.append({
|
||||||
'im':im_frame,
|
'im': im_frame,
|
||||||
'bbox':bbox,
|
'bbox': bbox,
|
||||||
'encoderinfo':encoderinfo
|
'encoderinfo': encoderinfo
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(im_frames) > 1:
|
if len(im_frames) > 1:
|
||||||
|
@ -441,6 +444,7 @@ def _write_multiple_frames(im, fp, palette):
|
||||||
_write_frame_data(fp, im_frame, offset, frame_data['encoderinfo'])
|
_write_frame_data(fp, im_frame, offset, frame_data['encoderinfo'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _save_all(im, fp, filename):
|
def _save_all(im, fp, filename):
|
||||||
_save(im, fp, filename, save_all=True)
|
_save(im, fp, filename, save_all=True)
|
||||||
|
|
||||||
|
@ -593,6 +597,7 @@ def _save_netpbm(im, fp, filename):
|
||||||
# cases where it took lots of memory and time previously.
|
# cases where it took lots of memory and time previously.
|
||||||
_FORCE_OPTIMIZE = False
|
_FORCE_OPTIMIZE = False
|
||||||
|
|
||||||
|
|
||||||
def _get_optimize(im, info):
|
def _get_optimize(im, info):
|
||||||
"""
|
"""
|
||||||
Palette optimization is a potentially expensive operation.
|
Palette optimization is a potentially expensive operation.
|
||||||
|
@ -624,9 +629,10 @@ def _get_optimize(im, info):
|
||||||
used_palette_colors.append(i)
|
used_palette_colors.append(i)
|
||||||
|
|
||||||
if optimise or (len(used_palette_colors) <= 128 and
|
if optimise or (len(used_palette_colors) <= 128 and
|
||||||
max(used_palette_colors) > len(used_palette_colors)):
|
max(used_palette_colors) > len(used_palette_colors)):
|
||||||
return used_palette_colors
|
return used_palette_colors
|
||||||
|
|
||||||
|
|
||||||
def _get_color_table_size(palette_bytes):
|
def _get_color_table_size(palette_bytes):
|
||||||
# calculate the palette size for the header
|
# calculate the palette size for the header
|
||||||
import math
|
import math
|
||||||
|
@ -635,6 +641,7 @@ def _get_color_table_size(palette_bytes):
|
||||||
color_table_size = 0
|
color_table_size = 0
|
||||||
return color_table_size
|
return color_table_size
|
||||||
|
|
||||||
|
|
||||||
def _get_header_palette(palette_bytes):
|
def _get_header_palette(palette_bytes):
|
||||||
"""
|
"""
|
||||||
Returns the palette, null padded to the next power of 2 (*3) bytes
|
Returns the palette, null padded to the next power of 2 (*3) bytes
|
||||||
|
@ -652,14 +659,16 @@ def _get_header_palette(palette_bytes):
|
||||||
palette_bytes += o8(0) * 3 * actual_target_size_diff
|
palette_bytes += o8(0) * 3 * actual_target_size_diff
|
||||||
return palette_bytes
|
return palette_bytes
|
||||||
|
|
||||||
def _get_palette_bytes(im):
|
|
||||||
"""
|
|
||||||
Gets the palette for inclusion in the gif header
|
|
||||||
|
|
||||||
:param im: Image object
|
def _get_palette_bytes(im):
|
||||||
:returns: Bytes, len<=768 suitable for inclusion in gif header
|
"""
|
||||||
"""
|
Gets the palette for inclusion in the gif header
|
||||||
return im.palette.palette
|
|
||||||
|
:param im: Image object
|
||||||
|
:returns: Bytes, len<=768 suitable for inclusion in gif header
|
||||||
|
"""
|
||||||
|
return im.palette.palette
|
||||||
|
|
||||||
|
|
||||||
def _get_global_header(im, info):
|
def _get_global_header(im, info):
|
||||||
"""Return a list of strings representing a GIF header"""
|
"""Return a list of strings representing a GIF header"""
|
||||||
|
@ -671,7 +680,7 @@ def _get_global_header(im, info):
|
||||||
for extensionKey in ["transparency", "duration", "loop", "comment"]:
|
for extensionKey in ["transparency", "duration", "loop", "comment"]:
|
||||||
if info and extensionKey in info:
|
if info and extensionKey in info:
|
||||||
if ((extensionKey == "duration" and info[extensionKey] == 0) or
|
if ((extensionKey == "duration" and info[extensionKey] == 0) or
|
||||||
(extensionKey == "comment" and not (1 <= len(info[extensionKey]) <= 255))):
|
(extensionKey == "comment" and not (1 <= len(info[extensionKey]) <= 255))):
|
||||||
continue
|
continue
|
||||||
version = b"89a"
|
version = b"89a"
|
||||||
break
|
break
|
||||||
|
@ -693,12 +702,13 @@ def _get_global_header(im, info):
|
||||||
# size of global color table + global color table flag
|
# size of global color table + global color table flag
|
||||||
o8(color_table_size + 128), # packed fields
|
o8(color_table_size + 128), # packed fields
|
||||||
# background + reserved/aspect
|
# background + reserved/aspect
|
||||||
o8(background) + o8(0),
|
o8(background) + o8(0),
|
||||||
|
|
||||||
# Global Color Table
|
# Global Color Table
|
||||||
_get_header_palette(palette_bytes)
|
_get_header_palette(palette_bytes)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def _write_frame_data(fp, im_frame, offset, params):
|
def _write_frame_data(fp, im_frame, offset, params):
|
||||||
try:
|
try:
|
||||||
im_frame.encoderinfo = params
|
im_frame.encoderinfo = params
|
||||||
|
@ -716,6 +726,7 @@ def _write_frame_data(fp, im_frame, offset, params):
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Legacy GIF utilities
|
# Legacy GIF utilities
|
||||||
|
|
||||||
|
|
||||||
def getheader(im, palette=None, info=None):
|
def getheader(im, palette=None, info=None):
|
||||||
"""
|
"""
|
||||||
Legacy Method to get Gif data from image.
|
Legacy Method to get Gif data from image.
|
||||||
|
@ -724,7 +735,7 @@ def getheader(im, palette=None, info=None):
|
||||||
|
|
||||||
:param im: Image object
|
:param im: Image object
|
||||||
:param palette: bytes object containing the source palette, or ....
|
:param palette: bytes object containing the source palette, or ....
|
||||||
:param info: encoderinfo
|
:param info: encoderinfo
|
||||||
:returns: tuple of(list of header items, optimized palette)
|
:returns: tuple of(list of header items, optimized palette)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -733,7 +744,7 @@ def getheader(im, palette=None, info=None):
|
||||||
if info is None:
|
if info is None:
|
||||||
info = {}
|
info = {}
|
||||||
|
|
||||||
if not "background" in info and "background" in im.info:
|
if "background" not in info and "background" in im.info:
|
||||||
info["background"] = im.info["background"]
|
info["background"] = im.info["background"]
|
||||||
|
|
||||||
im_mod = _normalize_palette(im, palette, info)
|
im_mod = _normalize_palette(im, palette, info)
|
||||||
|
@ -743,6 +754,7 @@ def getheader(im, palette=None, info=None):
|
||||||
|
|
||||||
return header, used_palette_colors
|
return header, used_palette_colors
|
||||||
|
|
||||||
|
|
||||||
# To specify duration, add the time in milliseconds to getdata(),
|
# To specify duration, add the time in milliseconds to getdata(),
|
||||||
# e.g. getdata(im_frame, duration=1000)
|
# e.g. getdata(im_frame, duration=1000)
|
||||||
def getdata(im, offset=(0, 0), **params):
|
def getdata(im, offset=(0, 0), **params):
|
||||||
|
|
16
PIL/Image.py
16
PIL/Image.py
|
@ -558,16 +558,16 @@ class Image(object):
|
||||||
|
|
||||||
if getattr(self, 'map', None):
|
if getattr(self, 'map', None):
|
||||||
self.map = None
|
self.map = None
|
||||||
|
|
||||||
# Instead of simply setting to None, we're setting up a
|
# Instead of simply setting to None, we're setting up a
|
||||||
# deferred error that will better explain that the core image
|
# deferred error that will better explain that the core image
|
||||||
# object is gone.
|
# object is gone.
|
||||||
self.im = deferred_error(ValueError("Operation on closed image"))
|
self.im = deferred_error(ValueError("Operation on closed image"))
|
||||||
|
|
||||||
if sys.version_info >= (3,4,0):
|
if sys.version_info >= (3, 4, 0):
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if (hasattr(self, 'fp') and hasattr(self, '_exclusive_fp')
|
if (hasattr(self, 'fp') and hasattr(self, '_exclusive_fp')
|
||||||
and self.fp and self._exclusive_fp):
|
and self.fp and self._exclusive_fp):
|
||||||
self.fp.close()
|
self.fp.close()
|
||||||
self.fp = None
|
self.fp = None
|
||||||
|
|
||||||
|
@ -1554,7 +1554,6 @@ class Image(object):
|
||||||
else: # L-mode
|
else: # L-mode
|
||||||
source_palette = bytearray(i//3 for i in range(768))
|
source_palette = bytearray(i//3 for i in range(768))
|
||||||
|
|
||||||
|
|
||||||
palette_bytes = b""
|
palette_bytes = b""
|
||||||
new_positions = [0]*256
|
new_positions = [0]*256
|
||||||
|
|
||||||
|
@ -1589,8 +1588,8 @@ class Image(object):
|
||||||
m_im.palette = ImagePalette.ImagePalette("RGB",
|
m_im.palette = ImagePalette.ImagePalette("RGB",
|
||||||
palette=mapping_palette*3,
|
palette=mapping_palette*3,
|
||||||
size=768)
|
size=768)
|
||||||
#possibly set palette dirty, then
|
# possibly set palette dirty, then
|
||||||
#m_im.putpalette(mapping_palette, 'L') # converts to 'P'
|
# m_im.putpalette(mapping_palette, 'L') # converts to 'P'
|
||||||
# or just force it.
|
# or just force it.
|
||||||
# UNDONE -- this is part of the general issue with palettes
|
# UNDONE -- this is part of the general issue with palettes
|
||||||
m_im.im.putpalette(*m_im.palette.getdata())
|
m_im.im.putpalette(*m_im.palette.getdata())
|
||||||
|
@ -1607,8 +1606,6 @@ class Image(object):
|
||||||
|
|
||||||
return m_im
|
return m_im
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def resize(self, size, resample=NEAREST):
|
def resize(self, size, resample=NEAREST):
|
||||||
"""
|
"""
|
||||||
Returns a resized copy of this image.
|
Returns a resized copy of this image.
|
||||||
|
@ -2627,6 +2624,7 @@ def registered_extensions():
|
||||||
init()
|
init()
|
||||||
return EXTENSION
|
return EXTENSION
|
||||||
|
|
||||||
|
|
||||||
def register_decoder(name, decoder):
|
def register_decoder(name, decoder):
|
||||||
"""
|
"""
|
||||||
Registers an image decoder. This function should not be
|
Registers an image decoder. This function should not be
|
||||||
|
|
|
@ -166,7 +166,6 @@ class ImageCmsProfile(object):
|
||||||
self._set(profile)
|
self._set(profile)
|
||||||
else:
|
else:
|
||||||
raise TypeError("Invalid type for Profile")
|
raise TypeError("Invalid type for Profile")
|
||||||
|
|
||||||
|
|
||||||
def _set(self, profile, filename=None):
|
def _set(self, profile, filename=None):
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
|
|
|
@ -160,7 +160,7 @@ class ImageFile(Image.Image):
|
||||||
# try memory mapping
|
# try memory mapping
|
||||||
decoder_name, extents, offset, args = self.tile[0]
|
decoder_name, extents, offset, args = self.tile[0]
|
||||||
if decoder_name == "raw" and len(args) >= 3 and args[0] == self.mode \
|
if decoder_name == "raw" and len(args) >= 3 and args[0] == self.mode \
|
||||||
and args[0] in Image._MAPMODES:
|
and args[0] in Image._MAPMODES:
|
||||||
try:
|
try:
|
||||||
if hasattr(Image.core, "map"):
|
if hasattr(Image.core, "map"):
|
||||||
# use built-in mapper WIN32 only
|
# use built-in mapper WIN32 only
|
||||||
|
@ -199,7 +199,7 @@ class ImageFile(Image.Image):
|
||||||
|
|
||||||
for decoder_name, extents, offset, args in self.tile:
|
for decoder_name, extents, offset, args in self.tile:
|
||||||
decoder = Image._getdecoder(self.mode, decoder_name,
|
decoder = Image._getdecoder(self.mode, decoder_name,
|
||||||
args, self.decoderconfig)
|
args, self.decoderconfig)
|
||||||
seek(offset)
|
seek(offset)
|
||||||
decoder.setimage(self.im, extents)
|
decoder.setimage(self.im, extents)
|
||||||
if decoder.pulls_fd:
|
if decoder.pulls_fd:
|
||||||
|
@ -540,6 +540,7 @@ class PyCodecState(object):
|
||||||
return (self.xoff, self.yoff,
|
return (self.xoff, self.yoff,
|
||||||
self.xoff+self.xsize, self.yoff+self.ysize)
|
self.xoff+self.xsize, self.yoff+self.ysize)
|
||||||
|
|
||||||
|
|
||||||
class PyDecoder(object):
|
class PyDecoder(object):
|
||||||
"""
|
"""
|
||||||
Python implementation of a format decoder. Override this class and
|
Python implementation of a format decoder. Override this class and
|
||||||
|
@ -565,7 +566,7 @@ class PyDecoder(object):
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pulls_fd(self):
|
def pulls_fd(self):
|
||||||
return self._pulls_fd
|
return self._pulls_fd
|
||||||
|
@ -597,7 +598,7 @@ class PyDecoder(object):
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
self.fd = fd
|
self.fd = fd
|
||||||
|
|
||||||
def setimage(self, im, extents=None):
|
def setimage(self, im, extents=None):
|
||||||
"""
|
"""
|
||||||
Called from ImageFile to set the core output image for the decoder
|
Called from ImageFile to set the core output image for the decoder
|
||||||
|
@ -607,7 +608,7 @@ class PyDecoder(object):
|
||||||
for this tile
|
for this tile
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# following c code
|
# following c code
|
||||||
self.im = im
|
self.im = im
|
||||||
|
|
||||||
|
@ -616,7 +617,6 @@ class PyDecoder(object):
|
||||||
else:
|
else:
|
||||||
(x0, y0, x1, y1) = (0, 0, 0, 0)
|
(x0, y0, x1, y1) = (0, 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
if x0 == 0 and x1 == 0:
|
if x0 == 0 and x1 == 0:
|
||||||
self.state.xsize, self.state.ysize = self.im.size
|
self.state.xsize, self.state.ysize = self.im.size
|
||||||
else:
|
else:
|
||||||
|
@ -627,11 +627,11 @@ class PyDecoder(object):
|
||||||
|
|
||||||
if self.state.xsize <= 0 or self.state.ysize <= 0:
|
if self.state.xsize <= 0 or self.state.ysize <= 0:
|
||||||
raise ValueError("Size cannot be negative")
|
raise ValueError("Size cannot be negative")
|
||||||
|
|
||||||
if (self.state.xsize + self.state.xoff > self.im.size[0] or
|
if (self.state.xsize + self.state.xoff > self.im.size[0] or
|
||||||
self.state.ysize + self.state.yoff > self.im.size[1]):
|
self.state.ysize + self.state.yoff > self.im.size[1]):
|
||||||
raise ValueError("Tile cannot extend outside image")
|
raise ValueError("Tile cannot extend outside image")
|
||||||
|
|
||||||
def set_as_raw(self, data, rawmode=None):
|
def set_as_raw(self, data, rawmode=None):
|
||||||
"""
|
"""
|
||||||
Convenience method to set the internal image from a stream of raw data
|
Convenience method to set the internal image from a stream of raw data
|
||||||
|
@ -641,13 +641,13 @@ class PyDecoder(object):
|
||||||
it will default to the mode of the image
|
it will default to the mode of the image
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not rawmode:
|
if not rawmode:
|
||||||
rawmode = self.mode
|
rawmode = self.mode
|
||||||
d = Image._getdecoder(self.mode, 'raw', (rawmode))
|
d = Image._getdecoder(self.mode, 'raw', (rawmode))
|
||||||
d.setimage(self.im, self.state.extents())
|
d.setimage(self.im, self.state.extents())
|
||||||
s = d.decode(data)
|
s = d.decode(data)
|
||||||
|
|
||||||
if s[0] >= 0:
|
if s[0] >= 0:
|
||||||
raise ValueError("not enough image data")
|
raise ValueError("not enough image data")
|
||||||
if s[1] != 0:
|
if s[1] != 0:
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
from ._binary import i16le as i16, o16le as o16, i8
|
from ._binary import i16le as i16, o16le as o16, i8
|
||||||
import struct, io
|
import struct
|
||||||
|
import io
|
||||||
|
|
||||||
__version__ = "0.1"
|
__version__ = "0.1"
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@ class MspDecoder(ImageFile.PyDecoder):
|
||||||
# If the RunType value is non-zero
|
# If the RunType value is non-zero
|
||||||
# Use this value as the RunCount
|
# Use this value as the RunCount
|
||||||
# Read and write the next RunCount bytes literally
|
# Read and write the next RunCount bytes literally
|
||||||
#
|
#
|
||||||
# e.g.:
|
# e.g.:
|
||||||
# 0x00 03 ff 05 00 01 02 03 04
|
# 0x00 03 ff 05 00 01 02 03 04
|
||||||
# would yield the bytes:
|
# would yield the bytes:
|
||||||
|
@ -105,11 +106,10 @@ class MspDecoder(ImageFile.PyDecoder):
|
||||||
#
|
#
|
||||||
# which are then interpreted as a bit packed mode '1' image
|
# which are then interpreted as a bit packed mode '1' image
|
||||||
|
|
||||||
|
|
||||||
_pulls_fd = True
|
_pulls_fd = True
|
||||||
|
|
||||||
def decode(self, buffer):
|
def decode(self, buffer):
|
||||||
|
|
||||||
img = io.BytesIO()
|
img = io.BytesIO()
|
||||||
blank_line = bytearray((0xff,)*((self.state.xsize+7)//8))
|
blank_line = bytearray((0xff,)*((self.state.xsize+7)//8))
|
||||||
try:
|
try:
|
||||||
|
@ -140,17 +140,17 @@ class MspDecoder(ImageFile.PyDecoder):
|
||||||
runcount = runtype
|
runcount = runtype
|
||||||
img.write(row[idx:idx+runcount])
|
img.write(row[idx:idx+runcount])
|
||||||
idx += runcount
|
idx += runcount
|
||||||
|
|
||||||
except struct.error:
|
except struct.error:
|
||||||
raise IOError("Corrupted MSP file in row %d" %x)
|
raise IOError("Corrupted MSP file in row %d" % x)
|
||||||
|
|
||||||
self.set_as_raw(img.getvalue(), ("1", 0, 1))
|
self.set_as_raw(img.getvalue(), ("1", 0, 1))
|
||||||
|
|
||||||
return 0,0
|
return 0, 0
|
||||||
|
|
||||||
|
|
||||||
Image.register_decoder('MSP', MspDecoder)
|
Image.register_decoder('MSP', MspDecoder)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# write MSP files (uncompressed only)
|
# write MSP files (uncompressed only)
|
||||||
|
|
|
@ -124,14 +124,14 @@ def _save(im, fp, filename):
|
||||||
fp.write(struct.pack('>l', pinmin))
|
fp.write(struct.pack('>l', pinmin))
|
||||||
fp.write(struct.pack('>l', pinmax))
|
fp.write(struct.pack('>l', pinmax))
|
||||||
|
|
||||||
fp.write(struct.pack('4s', b'')) # dummy
|
fp.write(struct.pack('4s', b'')) # dummy
|
||||||
fp.write(struct.pack('79s', imgName)) # truncates to 79 chars
|
fp.write(struct.pack('79s', imgName)) # truncates to 79 chars
|
||||||
fp.write(struct.pack('s', b'')) # force null byte after imgname
|
fp.write(struct.pack('s', b'')) # force null byte after imgname
|
||||||
fp.write(struct.pack('>l', colormap))
|
fp.write(struct.pack('>l', colormap))
|
||||||
|
|
||||||
fp.write(struct.pack('404s', b'')) # dummy
|
fp.write(struct.pack('404s', b'')) # dummy
|
||||||
|
|
||||||
#assert we've got the right number of bands.
|
# assert we've got the right number of bands.
|
||||||
if len(im.getbands()) != z:
|
if len(im.getbands()) != z:
|
||||||
raise ValueError("incorrect number of bands in SGI write: %s vs %s" %
|
raise ValueError("incorrect number of bands in SGI write: %s vs %s" %
|
||||||
(z, len(im.getbands())))
|
(z, len(im.getbands())))
|
||||||
|
|
|
@ -52,7 +52,6 @@ class SunImageFile(ImageFile.ImageFile):
|
||||||
# DWORD ColorMapLength; /* Size of the color map in bytes */
|
# DWORD ColorMapLength; /* Size of the color map in bytes */
|
||||||
# } SUNRASTER;
|
# } SUNRASTER;
|
||||||
|
|
||||||
|
|
||||||
# HEAD
|
# HEAD
|
||||||
s = self.fp.read(32)
|
s = self.fp.read(32)
|
||||||
if i32(s) != 0x59a66a95:
|
if i32(s) != 0x59a66a95:
|
||||||
|
@ -63,9 +62,9 @@ class SunImageFile(ImageFile.ImageFile):
|
||||||
self.size = i32(s[4:8]), i32(s[8:12])
|
self.size = i32(s[4:8]), i32(s[8:12])
|
||||||
|
|
||||||
depth = i32(s[12:16])
|
depth = i32(s[12:16])
|
||||||
data_length = i32(s[16:20]) # unreliable, ignore.
|
data_length = i32(s[16:20]) # unreliable, ignore.
|
||||||
file_type = i32(s[20:24])
|
file_type = i32(s[20:24])
|
||||||
palette_type = i32(s[24:28]) # 0: None, 1: RGB, 2: Raw/arbitrary
|
palette_type = i32(s[24:28]) # 0: None, 1: RGB, 2: Raw/arbitrary
|
||||||
palette_length = i32(s[28:32])
|
palette_length = i32(s[28:32])
|
||||||
|
|
||||||
if depth == 1:
|
if depth == 1:
|
||||||
|
|
|
@ -616,7 +616,8 @@ class ImageFileDirectory_v2(collections.MutableMapping):
|
||||||
@_register_loader(5, 8)
|
@_register_loader(5, 8)
|
||||||
def load_rational(self, data, legacy_api=True):
|
def load_rational(self, data, legacy_api=True):
|
||||||
vals = self._unpack("{}L".format(len(data) // 4), data)
|
vals = self._unpack("{}L".format(len(data) // 4), data)
|
||||||
combine = lambda a, b: (a, b) if legacy_api else IFDRational(a, b)
|
|
||||||
|
def combine(a, b): return (a, b) if legacy_api else IFDRational(a, b)
|
||||||
return tuple(combine(num, denom)
|
return tuple(combine(num, denom)
|
||||||
for num, denom in zip(vals[::2], vals[1::2]))
|
for num, denom in zip(vals[::2], vals[1::2]))
|
||||||
|
|
||||||
|
@ -636,7 +637,8 @@ class ImageFileDirectory_v2(collections.MutableMapping):
|
||||||
@_register_loader(10, 8)
|
@_register_loader(10, 8)
|
||||||
def load_signed_rational(self, data, legacy_api=True):
|
def load_signed_rational(self, data, legacy_api=True):
|
||||||
vals = self._unpack("{}l".format(len(data) // 4), data)
|
vals = self._unpack("{}l".format(len(data) // 4), data)
|
||||||
combine = lambda a, b: (a, b) if legacy_api else IFDRational(a, b)
|
|
||||||
|
def combine(a, b): return (a, b) if legacy_api else IFDRational(a, b)
|
||||||
return tuple(combine(num, denom)
|
return tuple(combine(num, denom)
|
||||||
for num, denom in zip(vals[::2], vals[1::2]))
|
for num, denom in zip(vals[::2], vals[1::2]))
|
||||||
|
|
||||||
|
@ -1136,7 +1138,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
sampleFormat = self.tag_v2.get(SAMPLEFORMAT, (1,))
|
sampleFormat = self.tag_v2.get(SAMPLEFORMAT, (1,))
|
||||||
if (len(sampleFormat) > 1
|
if (len(sampleFormat) > 1
|
||||||
and max(sampleFormat) == min(sampleFormat) == 1):
|
and max(sampleFormat) == min(sampleFormat) == 1):
|
||||||
# SAMPLEFORMAT is properly per band, so an RGB image will
|
# SAMPLEFORMAT is properly per band, so an RGB image will
|
||||||
# be (1,1,1). But, we don't support per band pixel types,
|
# be (1,1,1). But, we don't support per band pixel types,
|
||||||
# and anything more than one band is a uint8. So, just
|
# and anything more than one band is a uint8. So, just
|
||||||
|
@ -1174,7 +1176,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
self.info["dpi"] = xres, yres
|
self.info["dpi"] = xres, yres
|
||||||
elif resunit == 3: # dots per centimeter. convert to dpi
|
elif resunit == 3: # dots per centimeter. convert to dpi
|
||||||
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
|
||||||
|
@ -1492,6 +1494,7 @@ def _save(im, fp, filename):
|
||||||
# just to access o32 and o16 (using correct byte order)
|
# just to access o32 and o16 (using correct byte order)
|
||||||
im._debug_multipage = ifd
|
im._debug_multipage = ifd
|
||||||
|
|
||||||
|
|
||||||
class AppendingTiffWriter:
|
class AppendingTiffWriter:
|
||||||
fieldSizes = [
|
fieldSizes = [
|
||||||
0, # None
|
0, # None
|
||||||
|
@ -1679,12 +1682,12 @@ 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,
|
# trace("fixing IFD at %X; number of tags: %u (0x%X)", self.f.tell()-2,
|
||||||
# numTags, numTags)
|
# 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, self.f.read(8))
|
||||||
#trace(" at %X: tag %u (0x%X), type %u, count %u", self.f.tell()-8,
|
# trace(" at %X: tag %u (0x%X), type %u, count %u", self.f.tell()-8,
|
||||||
# tag, tag, fieldType, count)
|
# tag, tag, fieldType, count)
|
||||||
|
|
||||||
fieldSize = self.fieldSizes[fieldType]
|
fieldSize = self.fieldSizes[fieldType]
|
||||||
|
@ -1737,6 +1740,7 @@ class AppendingTiffWriter:
|
||||||
else:
|
else:
|
||||||
self.rewriteLastLong(offset)
|
self.rewriteLastLong(offset)
|
||||||
|
|
||||||
|
|
||||||
def _save_all(im, fp, filename):
|
def _save_all(im, fp, filename):
|
||||||
if not hasattr(im, "n_frames"):
|
if not hasattr(im, "n_frames"):
|
||||||
return _save(im, fp, filename)
|
return _save(im, fp, filename)
|
||||||
|
|
|
@ -25,7 +25,6 @@ from . import Image, ImageFile
|
||||||
from ._binary import i16le as word, si16le as short, i32le as dword, si32le as _long
|
from ._binary import i16le as word, si16le as short, i32le as dword, si32le as _long
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
__version__ = "0.2"
|
__version__ = "0.2"
|
||||||
|
|
||||||
_handler = None
|
_handler = None
|
||||||
|
@ -66,6 +65,7 @@ if hasattr(Image.core, "drawwmf"):
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Read WMF file
|
# Read WMF file
|
||||||
|
|
||||||
|
|
||||||
def _accept(prefix):
|
def _accept(prefix):
|
||||||
return (
|
return (
|
||||||
prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or
|
prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or
|
||||||
|
|
|
@ -37,6 +37,7 @@ def i16le(c, o=0):
|
||||||
"""
|
"""
|
||||||
return unpack("<H", c[o:o+2])[0]
|
return unpack("<H", c[o:o+2])[0]
|
||||||
|
|
||||||
|
|
||||||
def si16le(c, o=0):
|
def si16le(c, o=0):
|
||||||
"""
|
"""
|
||||||
Converts a 2-bytes (16 bits) string to a signed integer.
|
Converts a 2-bytes (16 bits) string to a signed integer.
|
||||||
|
@ -56,6 +57,7 @@ def i32le(c, o=0):
|
||||||
"""
|
"""
|
||||||
return unpack("<I", c[o:o+4])[0]
|
return unpack("<I", c[o:o+4])[0]
|
||||||
|
|
||||||
|
|
||||||
def si32le(c, o=0):
|
def si32le(c, o=0):
|
||||||
"""
|
"""
|
||||||
Converts a 4-bytes (32 bits) string to a signed integer.
|
Converts a 4-bytes (32 bits) string to a signed integer.
|
||||||
|
|
|
@ -250,6 +250,7 @@ if sys.platform == 'win32':
|
||||||
else:
|
else:
|
||||||
IMCONVERT = 'convert'
|
IMCONVERT = 'convert'
|
||||||
|
|
||||||
|
|
||||||
def distro():
|
def distro():
|
||||||
if os.path.exists('/etc/os-release'):
|
if os.path.exists('/etc/os-release'):
|
||||||
with open('/etc/os-release', 'r') as f:
|
with open('/etc/os-release', 'r') as f:
|
||||||
|
@ -257,6 +258,7 @@ def distro():
|
||||||
if 'ID=' in line:
|
if 'ID=' in line:
|
||||||
return line.strip().split('=')[1]
|
return line.strip().split('=')[1]
|
||||||
|
|
||||||
|
|
||||||
class cached_property(object):
|
class cached_property(object):
|
||||||
def __init__(self, func):
|
def __init__(self, func):
|
||||||
self.func = func
|
self.func = func
|
||||||
|
|
|
@ -58,21 +58,20 @@ class TestFileGif(PillowTestCase):
|
||||||
# Check for correctness after conversion back to RGB
|
# Check for correctness after conversion back to RGB
|
||||||
def check(colors, size, expected_palette_length):
|
def check(colors, size, expected_palette_length):
|
||||||
# make an image with empty colors in the start of the palette range
|
# make an image with empty colors in the start of the palette range
|
||||||
im = Image.frombytes('P', (colors,colors),
|
im = Image.frombytes('P', (colors, colors),
|
||||||
bytes(bytearray(range(256-colors,256))*colors))
|
bytes(bytearray(range(256-colors, 256))*colors))
|
||||||
im = im.resize((size,size))
|
im = im.resize((size, size))
|
||||||
outfile = BytesIO()
|
outfile = BytesIO()
|
||||||
im.save(outfile, 'GIF')
|
im.save(outfile, 'GIF')
|
||||||
outfile.seek(0)
|
outfile.seek(0)
|
||||||
reloaded = Image.open(outfile)
|
reloaded = Image.open(outfile)
|
||||||
|
|
||||||
# check palette length
|
# check palette length
|
||||||
palette_length = max(i+1 for i,v in enumerate(reloaded.histogram()) if v)
|
palette_length = max(i+1 for i, v in enumerate(reloaded.histogram()) if v)
|
||||||
self.assertEqual(expected_palette_length, palette_length)
|
self.assertEqual(expected_palette_length, palette_length)
|
||||||
|
|
||||||
self.assert_image_equal(im.convert('RGB'), reloaded.convert('RGB'))
|
self.assert_image_equal(im.convert('RGB'), reloaded.convert('RGB'))
|
||||||
|
|
||||||
|
|
||||||
# These do optimize the palette
|
# These do optimize the palette
|
||||||
check(128, 511, 128)
|
check(128, 511, 128)
|
||||||
check(64, 511, 64)
|
check(64, 511, 64)
|
||||||
|
@ -284,7 +283,7 @@ class TestFileGif(PillowTestCase):
|
||||||
Image.new('L', (100, 100), '#222')
|
Image.new('L', (100, 100), '#222')
|
||||||
]
|
]
|
||||||
|
|
||||||
#duration as list
|
# duration as list
|
||||||
im_list[0].save(
|
im_list[0].save(
|
||||||
out,
|
out,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
|
@ -327,7 +326,7 @@ class TestFileGif(PillowTestCase):
|
||||||
Image.new('L', (100, 100), '#111')
|
Image.new('L', (100, 100), '#111')
|
||||||
]
|
]
|
||||||
|
|
||||||
#duration as list
|
# duration as list
|
||||||
im_list[0].save(
|
im_list[0].save(
|
||||||
out,
|
out,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
|
@ -428,10 +427,10 @@ class TestFileGif(PillowTestCase):
|
||||||
|
|
||||||
from PIL import ImagePalette
|
from PIL import ImagePalette
|
||||||
|
|
||||||
data = bytes(bytearray(range(1,254)))
|
data = bytes(bytearray(range(1, 254)))
|
||||||
palette = ImagePalette.ImagePalette("RGB", list(range(256))*3)
|
palette = ImagePalette.ImagePalette("RGB", list(range(256))*3)
|
||||||
|
|
||||||
im = Image.new('L', (253,1))
|
im = Image.new('L', (253, 1))
|
||||||
im.frombytes(data)
|
im.frombytes(data)
|
||||||
im.putpalette(palette)
|
im.putpalette(palette)
|
||||||
|
|
||||||
|
@ -444,8 +443,8 @@ class TestFileGif(PillowTestCase):
|
||||||
def test_bbox(self):
|
def test_bbox(self):
|
||||||
out = self.tempfile('temp.gif')
|
out = self.tempfile('temp.gif')
|
||||||
|
|
||||||
im = Image.new('RGB', (100,100), '#fff')
|
im = Image.new('RGB', (100, 100), '#fff')
|
||||||
ims = [Image.new("RGB", (100,100), '#000')]
|
ims = [Image.new("RGB", (100, 100), '#000')]
|
||||||
im.save(out, save_all=True, append_images=ims)
|
im.save(out, save_all=True, append_images=ims)
|
||||||
|
|
||||||
reread = Image.open(out)
|
reread = Image.open(out)
|
||||||
|
@ -453,7 +452,7 @@ class TestFileGif(PillowTestCase):
|
||||||
|
|
||||||
def test_palette_save_L(self):
|
def test_palette_save_L(self):
|
||||||
# generate an L mode image with a separate palette
|
# generate an L mode image with a separate palette
|
||||||
|
|
||||||
im = hopper('P')
|
im = hopper('P')
|
||||||
im_l = Image.frombytes('L', im.size, im.tobytes())
|
im_l = Image.frombytes('L', im.size, im.tobytes())
|
||||||
palette = bytes(bytearray(im.getpalette()))
|
palette = bytes(bytearray(im.getpalette()))
|
||||||
|
@ -464,7 +463,7 @@ class TestFileGif(PillowTestCase):
|
||||||
reloaded = Image.open(out)
|
reloaded = Image.open(out)
|
||||||
|
|
||||||
self.assert_image_equal(reloaded.convert('RGB'), im.convert('RGB'))
|
self.assert_image_equal(reloaded.convert('RGB'), im.convert('RGB'))
|
||||||
|
|
||||||
def test_palette_save_P(self):
|
def test_palette_save_P(self):
|
||||||
# pass in a different palette, then construct what the image
|
# pass in a different palette, then construct what the image
|
||||||
# would look like.
|
# would look like.
|
||||||
|
@ -511,7 +510,7 @@ class TestFileGif(PillowTestCase):
|
||||||
im = Image._wedge().resize((16, 16))
|
im = Image._wedge().resize((16, 16))
|
||||||
im.putpalette(ImagePalette.ImagePalette('RGB'))
|
im.putpalette(ImagePalette.ImagePalette('RGB'))
|
||||||
im.info = {'background': 0}
|
im.info = {'background': 0}
|
||||||
|
|
||||||
passed_palette = bytes(bytearray([255-i//3 for i in range(768)]))
|
passed_palette = bytes(bytearray([255-i//3 for i in range(768)]))
|
||||||
|
|
||||||
GifImagePlugin._FORCE_OPTIMIZE = True
|
GifImagePlugin._FORCE_OPTIMIZE = True
|
||||||
|
@ -521,19 +520,16 @@ class TestFileGif(PillowTestCase):
|
||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
# Enable to get target values on pre-refactor version
|
# Enable to get target values on pre-refactor version
|
||||||
#with open('Tests/images/gif_header_data.pkl', 'wb') as f:
|
# with open('Tests/images/gif_header_data.pkl', 'wb') as f:
|
||||||
# pickle.dump((h, d), f, 1)
|
# pickle.dump((h, d), f, 1)
|
||||||
with open('Tests/images/gif_header_data.pkl', 'rb') as f:
|
with open('Tests/images/gif_header_data.pkl', 'rb') as f:
|
||||||
(h_target, d_target) = pickle.load(f)
|
(h_target, d_target) = pickle.load(f)
|
||||||
|
|
||||||
self.assertEqual(h, h_target)
|
self.assertEqual(h, h_target)
|
||||||
self.assertEqual(d, d_target)
|
self.assertEqual(d, d_target)
|
||||||
finally:
|
finally:
|
||||||
GifImagePlugin._FORCE_OPTIMIZE = False
|
GifImagePlugin._FORCE_OPTIMIZE = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -42,6 +42,7 @@ class LibTiffTestCase(PillowTestCase):
|
||||||
out_bytes = io.BytesIO()
|
out_bytes = io.BytesIO()
|
||||||
im.save(out_bytes, format='tiff', compression='group4')
|
im.save(out_bytes, format='tiff', compression='group4')
|
||||||
|
|
||||||
|
|
||||||
class TestFileLibTiff(LibTiffTestCase):
|
class TestFileLibTiff(LibTiffTestCase):
|
||||||
|
|
||||||
def test_g4_tiff(self):
|
def test_g4_tiff(self):
|
||||||
|
@ -532,7 +533,7 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
count = im.n_frames
|
count = im.n_frames
|
||||||
im.close()
|
im.close()
|
||||||
try:
|
try:
|
||||||
os.remove(tmpfile) # Windows PermissionError here!
|
os.remove(tmpfile) # Windows PermissionError here!
|
||||||
except:
|
except:
|
||||||
self.fail("Should not get permission error here")
|
self.fail("Should not get permission error here")
|
||||||
|
|
||||||
|
|
|
@ -59,17 +59,17 @@ class TestFileMsp(PillowTestCase):
|
||||||
if os.path.splitext(f)[1] == '.msp')
|
if os.path.splitext(f)[1] == '.msp')
|
||||||
for path in files:
|
for path in files:
|
||||||
self._assert_file_image_equal(path,
|
self._assert_file_image_equal(path,
|
||||||
path.replace('.msp','.png'))
|
path.replace('.msp', '.png'))
|
||||||
|
|
||||||
@unittest.skipIf(not os.path.exists(YA_EXTRA_DIR),
|
@unittest.skipIf(not os.path.exists(YA_EXTRA_DIR),
|
||||||
"Even More Extra image files not installed")
|
"Even More Extra image files not installed")
|
||||||
def test_msp_v2(self):
|
def test_msp_v2(self):
|
||||||
for f in os.listdir(YA_EXTRA_DIR):
|
for f in os.listdir(YA_EXTRA_DIR):
|
||||||
if not '.MSP' in f: continue
|
if '.MSP' not in f:
|
||||||
|
continue
|
||||||
path = os.path.join(YA_EXTRA_DIR, f)
|
path = os.path.join(YA_EXTRA_DIR, f)
|
||||||
self._assert_file_image_equal(path,
|
self._assert_file_image_equal(path,
|
||||||
path.replace('.MSP','.png'))
|
path.replace('.MSP', '.png'))
|
||||||
|
|
||||||
|
|
||||||
def test_cannot_save_wrong_mode(self):
|
def test_cannot_save_wrong_mode(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
|
|
@ -41,7 +41,6 @@ class TestFilePpm(PillowTestCase):
|
||||||
|
|
||||||
self.assertRaises(ValueError, lambda: Image.open(path))
|
self.assertRaises(ValueError, lambda: Image.open(path))
|
||||||
|
|
||||||
|
|
||||||
def test_neg_ppm(self):
|
def test_neg_ppm(self):
|
||||||
# Storage.c accepted negative values for xsize, ysize. the
|
# Storage.c accepted negative values for xsize, ysize. the
|
||||||
# internal open_ppm function didn't check for sanity but it
|
# internal open_ppm function didn't check for sanity but it
|
||||||
|
|
|
@ -25,7 +25,7 @@ class TestFileSgi(PillowTestCase):
|
||||||
# Created with ImageMagick:
|
# Created with ImageMagick:
|
||||||
# convert transparent.png -compress None transparent.sgi
|
# convert transparent.png -compress None transparent.sgi
|
||||||
test_file = "Tests/images/transparent.sgi"
|
test_file = "Tests/images/transparent.sgi"
|
||||||
|
|
||||||
im = Image.open(test_file)
|
im = Image.open(test_file)
|
||||||
target = Image.open('Tests/images/transparent.png')
|
target = Image.open('Tests/images/transparent.png')
|
||||||
self.assert_image_equal(im, target)
|
self.assert_image_equal(im, target)
|
||||||
|
@ -56,6 +56,5 @@ class TestFileSgi(PillowTestCase):
|
||||||
roundtrip(hopper(mode))
|
roundtrip(hopper(mode))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import os
|
||||||
|
|
||||||
EXTRA_DIR = 'Tests/images/sunraster'
|
EXTRA_DIR = 'Tests/images/sunraster'
|
||||||
|
|
||||||
|
|
||||||
class TestFileSun(PillowTestCase):
|
class TestFileSun(PillowTestCase):
|
||||||
|
|
||||||
def test_sanity(self):
|
def test_sanity(self):
|
||||||
|
@ -19,8 +20,8 @@ class TestFileSun(PillowTestCase):
|
||||||
# Assert
|
# Assert
|
||||||
self.assertEqual(im.size, (128, 128))
|
self.assertEqual(im.size, (128, 128))
|
||||||
|
|
||||||
self.assert_image_similar(im, hopper(), 5) # visually verified
|
self.assert_image_similar(im, hopper(), 5) # visually verified
|
||||||
|
|
||||||
invalid_file = "Tests/images/flower.jpg"
|
invalid_file = "Tests/images/flower.jpg"
|
||||||
self.assertRaises(SyntaxError,
|
self.assertRaises(SyntaxError,
|
||||||
lambda: SunImagePlugin.SunImageFile(invalid_file))
|
lambda: SunImagePlugin.SunImageFile(invalid_file))
|
||||||
|
@ -30,21 +31,20 @@ class TestFileSun(PillowTestCase):
|
||||||
target = Image.open('Tests/images/sunraster.im1.png')
|
target = Image.open('Tests/images/sunraster.im1.png')
|
||||||
self.assert_image_equal(im, target)
|
self.assert_image_equal(im, target)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(not os.path.exists(EXTRA_DIR),
|
@unittest.skipIf(not os.path.exists(EXTRA_DIR),
|
||||||
"Extra image files not installed")
|
"Extra image files not installed")
|
||||||
def test_others(self):
|
def test_others(self):
|
||||||
files = (os.path.join(EXTRA_DIR, f) for f in
|
files = (os.path.join(EXTRA_DIR, f) for f in
|
||||||
os.listdir(EXTRA_DIR) if os.path.splitext(f)[1]
|
os.listdir(EXTRA_DIR) if os.path.splitext(f)[1]
|
||||||
in ('.sun', '.SUN', '.ras'))
|
in ('.sun', '.SUN', '.ras'))
|
||||||
for path in files:
|
for path in files:
|
||||||
with Image.open(path) as im:
|
with Image.open(path) as im:
|
||||||
im.load()
|
im.load()
|
||||||
self.assertIsInstance(im, SunImagePlugin.SunImageFile)
|
self.assertIsInstance(im, SunImagePlugin.SunImageFile)
|
||||||
target_path = "%s.png" % os.path.splitext(path)[0]
|
target_path = "%s.png" % os.path.splitext(path)[0]
|
||||||
#im.save(target_file)
|
# im.save(target_file)
|
||||||
with Image.open(target_path) as target:
|
with Image.open(target_path) as target:
|
||||||
self.assert_image_equal(im, target)
|
self.assert_image_equal(im, target)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from helper import unittest, PillowTestCase, hopper
|
from helper import unittest, PillowTestCase, hopper
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
class TestFileWmf(PillowTestCase):
|
class TestFileWmf(PillowTestCase):
|
||||||
|
|
||||||
def test_load_raw(self):
|
def test_load_raw(self):
|
||||||
|
|
|
@ -375,13 +375,16 @@ class TestImage(PillowTestCase):
|
||||||
self.assert_image_equal(im, target)
|
self.assert_image_equal(im, target)
|
||||||
|
|
||||||
|
|
||||||
class MockEncoder(object):pass
|
class MockEncoder(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def mock_encode(*args):
|
def mock_encode(*args):
|
||||||
encoder = MockEncoder()
|
encoder = MockEncoder()
|
||||||
encoder.args = args
|
encoder.args = args
|
||||||
return encoder
|
return encoder
|
||||||
|
|
||||||
|
|
||||||
class TestRegistry(PillowTestCase):
|
class TestRegistry(PillowTestCase):
|
||||||
|
|
||||||
def test_encode_registry(self):
|
def test_encode_registry(self):
|
||||||
|
|
|
@ -97,7 +97,6 @@ class TestImageGetPixel(AccessTest):
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
im.getpixel((0, 0))
|
im.getpixel((0, 0))
|
||||||
|
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
for mode in ("1", "L", "LA", "I", "I;16", "I;16B", "F",
|
for mode in ("1", "L", "LA", "I", "I;16", "I;16B", "F",
|
||||||
"P", "PA", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr"):
|
"P", "PA", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr"):
|
||||||
|
|
|
@ -187,7 +187,6 @@ class TestImageConvert(PillowTestCase):
|
||||||
else:
|
else:
|
||||||
self.assert_image_similar(converted_im, target.split()[0], 1)
|
self.assert_image_similar(converted_im, target.split()[0], 1)
|
||||||
|
|
||||||
|
|
||||||
matrix_convert('RGB')
|
matrix_convert('RGB')
|
||||||
matrix_convert('L')
|
matrix_convert('L')
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class TestImageCopy(PillowTestCase):
|
||||||
self.assertEqual(out.size, croppedSize)
|
self.assertEqual(out.size, croppedSize)
|
||||||
|
|
||||||
def test_copy_zero(self):
|
def test_copy_zero(self):
|
||||||
im = Image.new('RGB', (0,0))
|
im = Image.new('RGB', (0, 0))
|
||||||
out = im.copy()
|
out = im.copy()
|
||||||
self.assertEqual(out.mode, im.mode)
|
self.assertEqual(out.mode, im.mode)
|
||||||
self.assertEqual(out.size, im.size)
|
self.assertEqual(out.size, im.size)
|
||||||
|
|
|
@ -70,13 +70,13 @@ class TestImageCrop(PillowTestCase):
|
||||||
self.assertEqual(cropped.size, (3, 5))
|
self.assertEqual(cropped.size, (3, 5))
|
||||||
|
|
||||||
def test_crop_crash(self):
|
def test_crop_crash(self):
|
||||||
#Image.crop crashes prepatch with an access violation
|
# Image.crop crashes prepatch with an access violation
|
||||||
#apparently a use after free on windows, see
|
# apparently a use after free on windows, see
|
||||||
#https://github.com/python-pillow/Pillow/issues/1077
|
# https://github.com/python-pillow/Pillow/issues/1077
|
||||||
|
|
||||||
test_img = 'Tests/images/bmp/g/pal8-0.bmp'
|
test_img = 'Tests/images/bmp/g/pal8-0.bmp'
|
||||||
extents = (1,1,10,10)
|
extents = (1, 1, 10, 10)
|
||||||
#works prepatch
|
# works prepatch
|
||||||
img = Image.open(test_img)
|
img = Image.open(test_img)
|
||||||
img2 = img.crop(extents)
|
img2 = img.crop(extents)
|
||||||
img2.load()
|
img2.load()
|
||||||
|
@ -104,6 +104,5 @@ class TestImageCrop(PillowTestCase):
|
||||||
self.assertEqual(cropped.getdata()[2], (0, 0, 0))
|
self.assertEqual(cropped.getdata()[2], (0, 0, 0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
from helper import unittest, PillowTestCase, hopper, distro
|
from helper import unittest, PillowTestCase, hopper
|
||||||
from test_imageqt import PillowQtTestCase, PillowQPixmapTestCase
|
from test_imageqt import PillowQtTestCase, PillowQPixmapTestCase
|
||||||
|
|
||||||
from PIL import ImageQt
|
from PIL import ImageQt
|
||||||
|
|
||||||
|
|
||||||
class TestFromQPixmap(PillowQPixmapTestCase, PillowTestCase):
|
class TestFromQPixmap(PillowQPixmapTestCase, PillowTestCase):
|
||||||
|
|
||||||
def roundtrip(self, expected):
|
def roundtrip(self, expected):
|
||||||
|
|
|
@ -9,9 +9,9 @@ class TestImagingPaste(PillowTestCase):
|
||||||
|
|
||||||
def assert_9points_image(self, im, expected):
|
def assert_9points_image(self, im, expected):
|
||||||
expected = [
|
expected = [
|
||||||
point[0]
|
point[0]
|
||||||
if im.mode == 'L' else
|
if im.mode == 'L' else
|
||||||
point[:len(im.mode)]
|
point[:len(im.mode)]
|
||||||
for point in expected
|
for point in expected
|
||||||
]
|
]
|
||||||
px = im.load()
|
px = im.load()
|
||||||
|
@ -249,7 +249,7 @@ class TestImagingPaste(PillowTestCase):
|
||||||
im2 = Image.new('RGB', (50, 50))
|
im2 = Image.new('RGB', (50, 50))
|
||||||
|
|
||||||
im.copy().paste(im2)
|
im.copy().paste(im2)
|
||||||
im.copy().paste(im2, (0,0))
|
im.copy().paste(im2, (0, 0))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from helper import unittest, PillowTestCase, hopper
|
from helper import unittest, PillowTestCase, hopper
|
||||||
from PIL import Image, ImageDraw, ImageMode
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
|
||||||
class TestImagingResampleVulnerability(PillowTestCase):
|
class TestImagingResampleVulnerability(PillowTestCase):
|
||||||
|
@ -244,8 +244,8 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
|
||||||
for y in range(i.size[1]):
|
for y in range(i.size[1]):
|
||||||
used_colors = {px[x, y][0] for x in range(i.size[0])}
|
used_colors = {px[x, y][0] for x in range(i.size[0])}
|
||||||
self.assertEqual(256, len(used_colors),
|
self.assertEqual(256, len(used_colors),
|
||||||
'All colors should present in resized image. '
|
'All colors should present in resized image. '
|
||||||
'Only {} on {} line.'.format(len(used_colors), y))
|
'Only {} on {} line.'.format(len(used_colors), y))
|
||||||
|
|
||||||
@unittest.skip("current implementation isn't precise enough")
|
@unittest.skip("current implementation isn't precise enough")
|
||||||
def test_levels_rgba(self):
|
def test_levels_rgba(self):
|
||||||
|
@ -343,10 +343,10 @@ class CoreResampleCoefficientsTest(PillowTestCase):
|
||||||
im = Image.new('RGBA', (1280, 1280), (0x20, 0x40, 0x60, 0xff))
|
im = Image.new('RGBA', (1280, 1280), (0x20, 0x40, 0x60, 0xff))
|
||||||
histogram = im.resize((256, 256), Image.BICUBIC).histogram()
|
histogram = im.resize((256, 256), Image.BICUBIC).histogram()
|
||||||
|
|
||||||
self.assertEqual(histogram[0x100 * 0 + 0x20], 0x10000) # first channel
|
self.assertEqual(histogram[0x100 * 0 + 0x20], 0x10000) # first channel
|
||||||
self.assertEqual(histogram[0x100 * 1 + 0x40], 0x10000) # second channel
|
self.assertEqual(histogram[0x100 * 1 + 0x40], 0x10000) # second channel
|
||||||
self.assertEqual(histogram[0x100 * 2 + 0x60], 0x10000) # third channel
|
self.assertEqual(histogram[0x100 * 2 + 0x60], 0x10000) # third channel
|
||||||
self.assertEqual(histogram[0x100 * 3 + 0xff], 0x10000) # fourth channel
|
self.assertEqual(histogram[0x100 * 3 + 0xff], 0x10000) # fourth channel
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -92,10 +92,10 @@ class TestImagingCoreResize(PillowTestCase):
|
||||||
def test_enlarge_zero(self):
|
def test_enlarge_zero(self):
|
||||||
for f in [Image.NEAREST, Image.BOX, Image.BILINEAR, Image.HAMMING,
|
for f in [Image.NEAREST, Image.BOX, Image.BILINEAR, Image.HAMMING,
|
||||||
Image.BICUBIC, Image.LANCZOS]:
|
Image.BICUBIC, Image.LANCZOS]:
|
||||||
r = self.resize(Image.new('RGB', (0,0), "white"), (212, 195), f)
|
r = self.resize(Image.new('RGB', (0, 0), "white"), (212, 195), f)
|
||||||
self.assertEqual(r.mode, "RGB")
|
self.assertEqual(r.mode, "RGB")
|
||||||
self.assertEqual(r.size, (212, 195))
|
self.assertEqual(r.size, (212, 195))
|
||||||
self.assertEqual(r.getdata()[0], (0,0,0))
|
self.assertEqual(r.getdata()[0], (0, 0, 0))
|
||||||
|
|
||||||
def test_unknown_filter(self):
|
def test_unknown_filter(self):
|
||||||
self.assertRaises(ValueError, self.resize, hopper(), (10, 10), 9)
|
self.assertRaises(ValueError, self.resize, hopper(), (10, 10), 9)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class TestImageRotate(PillowTestCase):
|
||||||
else:
|
else:
|
||||||
self.assertNotEqual(out.size, im.size)
|
self.assertNotEqual(out.size, im.size)
|
||||||
|
|
||||||
def test_mode(self):
|
def test_mode(self):
|
||||||
for mode in ("1", "P", "L", "RGB", "I", "F"):
|
for mode in ("1", "P", "L", "RGB", "I", "F"):
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
self.rotate(im, mode, 45)
|
self.rotate(im, mode, 45)
|
||||||
|
@ -29,13 +29,13 @@ class TestImageRotate(PillowTestCase):
|
||||||
|
|
||||||
def test_zero(self):
|
def test_zero(self):
|
||||||
for angle in (0, 45, 90, 180, 270):
|
for angle in (0, 45, 90, 180, 270):
|
||||||
im = Image.new('RGB',(0,0))
|
im = Image.new('RGB', (0, 0))
|
||||||
self.rotate(im, im.mode, angle)
|
self.rotate(im, im.mode, angle)
|
||||||
|
|
||||||
def test_resample(self):
|
def test_resample(self):
|
||||||
# Target image creation, inspected by eye.
|
# Target image creation, inspected by eye.
|
||||||
# >>> im = Image.open('Tests/images/hopper.ppm')
|
# >>> im = Image.open('Tests/images/hopper.ppm')
|
||||||
# >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True)
|
# >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True)
|
||||||
# >>> im.save('Tests/images/hopper_45.png')
|
# >>> im.save('Tests/images/hopper_45.png')
|
||||||
|
|
||||||
target = Image.open('Tests/images/hopper_45.png')
|
target = Image.open('Tests/images/hopper_45.png')
|
||||||
|
@ -52,7 +52,7 @@ class TestImageRotate(PillowTestCase):
|
||||||
target_origin = target.size[1]/2
|
target_origin = target.size[1]/2
|
||||||
target = target.crop((0, target_origin, 128, target_origin + 128))
|
target = target.crop((0, target_origin, 128, target_origin + 128))
|
||||||
|
|
||||||
im = im.rotate(45, center=(0,0), resample=Image.BICUBIC)
|
im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC)
|
||||||
|
|
||||||
self.assert_image_similar(im, target, 15)
|
self.assert_image_similar(im, target, 15)
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class TestImageRotate(PillowTestCase):
|
||||||
target_origin = target.size[1] / 2 - 14
|
target_origin = target.size[1] / 2 - 14
|
||||||
target = target.crop((6, target_origin, 128 + 6, target_origin + 128))
|
target = target.crop((6, target_origin, 128 + 6, target_origin + 128))
|
||||||
|
|
||||||
im = im.rotate(45, center=(14,14), resample=Image.BICUBIC)
|
im = im.rotate(45, center=(14, 14), resample=Image.BICUBIC)
|
||||||
|
|
||||||
self.assert_image_similar(im, target, 10)
|
self.assert_image_similar(im, target, 10)
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class TestImageRotate(PillowTestCase):
|
||||||
target = target.crop((target_origin, target_origin,
|
target = target.crop((target_origin, target_origin,
|
||||||
target_origin + 128, target_origin + 128))
|
target_origin + 128, target_origin + 128))
|
||||||
|
|
||||||
im = im.rotate(45, translate=(5,5), resample=Image.BICUBIC)
|
im = im.rotate(45, translate=(5, 5), resample=Image.BICUBIC)
|
||||||
|
|
||||||
self.assert_image_similar(im, target, 1)
|
self.assert_image_similar(im, target, 1)
|
||||||
|
|
||||||
|
@ -81,14 +81,14 @@ class TestImageRotate(PillowTestCase):
|
||||||
# if the center is -1,-1 and we rotate by 90<=x<=270 the
|
# if the center is -1,-1 and we rotate by 90<=x<=270 the
|
||||||
# resulting image should be black
|
# resulting image should be black
|
||||||
for angle in (90, 180, 270):
|
for angle in (90, 180, 270):
|
||||||
im = hopper().rotate(angle, center=(-1,-1))
|
im = hopper().rotate(angle, center=(-1, -1))
|
||||||
self.assert_image_equal(im, Image.new('RGB', im.size, 'black'))
|
self.assert_image_equal(im, Image.new('RGB', im.size, 'black'))
|
||||||
|
|
||||||
def test_fastpath_translate(self):
|
def test_fastpath_translate(self):
|
||||||
# if we post-translate by -128
|
# if we post-translate by -128
|
||||||
# resulting image should be black
|
# resulting image should be black
|
||||||
for angle in (0, 90, 180, 270):
|
for angle in (0, 90, 180, 270):
|
||||||
im = hopper().rotate(angle, translate=(-128,-128))
|
im = hopper().rotate(angle, translate=(-128, -128))
|
||||||
self.assert_image_equal(im, Image.new('RGB', im.size, 'black'))
|
self.assert_image_equal(im, Image.new('RGB', im.size, 'black'))
|
||||||
|
|
||||||
def test_center(self):
|
def test_center(self):
|
||||||
|
@ -97,8 +97,6 @@ class TestImageRotate(PillowTestCase):
|
||||||
self.rotate(im, im.mode, 45, translate=(im.size[0]/2, 0))
|
self.rotate(im, im.mode, 45, translate=(im.size[0]/2, 0))
|
||||||
self.rotate(im, im.mode, 45, center=(0, 0), translate=(im.size[0]/2, 0))
|
self.rotate(im, im.mode, 45, center=(0, 0), translate=(im.size[0]/2, 0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -20,7 +20,8 @@ if ImageQt.qt_is_installed:
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
from PySide.QtGui import QWidget, QHBoxLayout, QLabel, QApplication
|
from PySide.QtGui import QWidget, QHBoxLayout, QLabel, QApplication
|
||||||
QT_VERSION = 4
|
QT_VERSION = 4
|
||||||
|
|
||||||
|
|
||||||
class TestToQImage(PillowQtTestCase, PillowTestCase):
|
class TestToQImage(PillowQtTestCase, PillowTestCase):
|
||||||
|
|
||||||
def test_sanity(self):
|
def test_sanity(self):
|
||||||
|
@ -45,12 +46,12 @@ class TestToQImage(PillowQtTestCase, PillowTestCase):
|
||||||
# libpng warning: Invalid color type/bit depth combination in IHDR
|
# libpng warning: Invalid color type/bit depth combination in IHDR
|
||||||
# libpng error: Invalid IHDR data
|
# libpng error: Invalid IHDR data
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Test saving the file
|
# Test saving the file
|
||||||
tempfile = self.tempfile('temp_{}.png'.format(mode))
|
tempfile = self.tempfile('temp_{}.png'.format(mode))
|
||||||
data.save(tempfile)
|
data.save(tempfile)
|
||||||
|
|
||||||
# Check that it actually worked.
|
# Check that it actually worked.
|
||||||
reloaded = Image.open(tempfile)
|
reloaded = Image.open(tempfile)
|
||||||
# Gray images appear to come back in palette mode.
|
# Gray images appear to come back in palette mode.
|
||||||
# They're roughly equivalent
|
# They're roughly equivalent
|
||||||
|
@ -58,7 +59,6 @@ class TestToQImage(PillowQtTestCase, PillowTestCase):
|
||||||
src = src.convert('P')
|
src = src.convert('P')
|
||||||
self.assert_image_equal(reloaded, src)
|
self.assert_image_equal(reloaded, src)
|
||||||
|
|
||||||
|
|
||||||
def test_segfault(self):
|
def test_segfault(self):
|
||||||
PillowQtTestCase.setUp(self)
|
PillowQtTestCase.setUp(self)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from helper import unittest, PillowTestCase, hopper, distro
|
from helper import unittest, PillowTestCase, hopper
|
||||||
from test_imageqt import PillowQtTestCase, PillowQPixmapTestCase
|
from test_imageqt import PillowQtTestCase, PillowQPixmapTestCase
|
||||||
|
|
||||||
from PIL import ImageQt
|
from PIL import ImageQt
|
||||||
|
|
|
@ -344,7 +344,7 @@ class TestImageCms(PillowTestCase):
|
||||||
chans = []
|
chans = []
|
||||||
bands = ImageMode.getmode(mode).bands
|
bands = ImageMode.getmode(mode).bands
|
||||||
for band_ndx in range(len(bands)):
|
for band_ndx in range(len(bands)):
|
||||||
channel_type = 'L' # 8-bit unorm
|
channel_type = 'L' # 8-bit unorm
|
||||||
channel_pattern = hopper(channel_type)
|
channel_pattern = hopper(channel_type)
|
||||||
|
|
||||||
# paste pattern with varying offsets to avoid correlation
|
# paste pattern with varying offsets to avoid correlation
|
||||||
|
|
|
@ -310,7 +310,6 @@ class TestImageDraw(PillowTestCase):
|
||||||
self.assert_image_equal(im, im_floodfill)
|
self.assert_image_equal(im, im_floodfill)
|
||||||
del draw
|
del draw
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(hasattr(sys, 'pypy_version_info'),
|
@unittest.skipIf(hasattr(sys, 'pypy_version_info'),
|
||||||
"Causes fatal RPython error on PyPy")
|
"Causes fatal RPython error on PyPy")
|
||||||
def test_floodfill_border(self):
|
def test_floodfill_border(self):
|
||||||
|
|
|
@ -138,10 +138,12 @@ class TestImageFile(PillowTestCase):
|
||||||
|
|
||||||
class MockPyDecoder(ImageFile.PyDecoder):
|
class MockPyDecoder(ImageFile.PyDecoder):
|
||||||
def decode(self, buffer):
|
def decode(self, buffer):
|
||||||
#eof
|
# eof
|
||||||
return (-1, 0)
|
return (-1, 0)
|
||||||
|
|
||||||
xoff, yoff, xsize, ysize = 10, 20, 100, 100
|
xoff, yoff, xsize, ysize = 10, 20, 100, 100
|
||||||
|
|
||||||
|
|
||||||
class MockImageFile(ImageFile.ImageFile):
|
class MockImageFile(ImageFile.ImageFile):
|
||||||
def _open(self):
|
def _open(self):
|
||||||
self.rawmode = 'RGBA'
|
self.rawmode = 'RGBA'
|
||||||
|
@ -149,6 +151,7 @@ class MockImageFile(ImageFile.ImageFile):
|
||||||
self.size = (200, 200)
|
self.size = (200, 200)
|
||||||
self.tile = [("MOCK", (xoff, yoff, xoff+xsize, yoff+ysize), 32, None)]
|
self.tile = [("MOCK", (xoff, yoff, xoff+xsize, yoff+ysize), 32, None)]
|
||||||
|
|
||||||
|
|
||||||
class TestPyDecoder(PillowTestCase):
|
class TestPyDecoder(PillowTestCase):
|
||||||
|
|
||||||
def get_decoder(self):
|
def get_decoder(self):
|
||||||
|
|
|
@ -128,16 +128,16 @@ class TestImagePalette(PillowTestCase):
|
||||||
def test_2bit_palette(self):
|
def test_2bit_palette(self):
|
||||||
# issue #2258, 2 bit palettes are corrupted.
|
# issue #2258, 2 bit palettes are corrupted.
|
||||||
outfile = self.tempfile('temp.png')
|
outfile = self.tempfile('temp.png')
|
||||||
|
|
||||||
rgb = b'\x00' * 2 + b'\x01' * 2 + b'\x02' * 2
|
rgb = b'\x00' * 2 + b'\x01' * 2 + b'\x02' * 2
|
||||||
img = Image.frombytes('P', (6, 1), rgb)
|
img = Image.frombytes('P', (6, 1), rgb)
|
||||||
img.putpalette(b'\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF') # RGB
|
img.putpalette(b'\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF') # RGB
|
||||||
img.save(outfile, format='PNG')
|
img.save(outfile, format='PNG')
|
||||||
|
|
||||||
reloaded = Image.open(outfile)
|
reloaded = Image.open(outfile)
|
||||||
|
|
||||||
self.assert_image_equal(img, reloaded)
|
self.assert_image_equal(img, reloaded)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -62,7 +62,6 @@ class TestImageSequence(PillowTestCase):
|
||||||
self.assert_image_equal(frame, firstFrame)
|
self.assert_image_equal(frame, firstFrame)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def test_palette_mmap(self):
|
def test_palette_mmap(self):
|
||||||
# Using mmap in ImageFile can require to reload the palette.
|
# Using mmap in ImageFile can require to reload the palette.
|
||||||
im = Image.open('Tests/images/multipage-mmap.tiff')
|
im = Image.open('Tests/images/multipage-mmap.tiff')
|
||||||
|
|
|
@ -10,9 +10,10 @@ try:
|
||||||
except (OSError, ImportError) as v:
|
except (OSError, ImportError) as v:
|
||||||
# Skipped via setUp()
|
# Skipped via setUp()
|
||||||
HAS_TK = False
|
HAS_TK = False
|
||||||
|
|
||||||
TK_MODES = ('1', 'L', 'P', 'RGB', 'RGBA')
|
TK_MODES = ('1', 'L', 'P', 'RGB', 'RGBA')
|
||||||
|
|
||||||
|
|
||||||
class TestImageTk(PillowTestCase):
|
class TestImageTk(PillowTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -21,7 +22,7 @@ class TestImageTk(PillowTestCase):
|
||||||
try:
|
try:
|
||||||
# setup tk
|
# setup tk
|
||||||
app = tk.Frame()
|
app = tk.Frame()
|
||||||
#root = tk.Tk()
|
# root = tk.Tk()
|
||||||
except (tk.TclError) as v:
|
except (tk.TclError) as v:
|
||||||
self.skipTest("TCL Error: %s" % v)
|
self.skipTest("TCL Error: %s" % v)
|
||||||
|
|
||||||
|
@ -46,12 +47,11 @@ class TestImageTk(PillowTestCase):
|
||||||
im = ImageTk._get_image_from_kw(kw)
|
im = ImageTk._get_image_from_kw(kw)
|
||||||
self.assertEqual(im, None)
|
self.assertEqual(im, None)
|
||||||
|
|
||||||
|
|
||||||
def test_photoimage(self):
|
def test_photoimage(self):
|
||||||
for mode in TK_MODES:
|
for mode in TK_MODES:
|
||||||
# test as image:
|
# test as image:
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
|
|
||||||
# this should not crash
|
# this should not crash
|
||||||
im_tk = ImageTk.PhotoImage(im)
|
im_tk = ImageTk.PhotoImage(im)
|
||||||
|
|
||||||
|
@ -59,35 +59,32 @@ class TestImageTk(PillowTestCase):
|
||||||
self.assertEqual(im_tk.height(), im.height)
|
self.assertEqual(im_tk.height(), im.height)
|
||||||
|
|
||||||
# _tkinter.TclError: this function is not yet supported
|
# _tkinter.TclError: this function is not yet supported
|
||||||
#reloaded = ImageTk.getimage(im_tk)
|
# reloaded = ImageTk.getimage(im_tk)
|
||||||
#self.assert_image_equal(reloaded, im)
|
# self.assert_image_equal(reloaded, im)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_photoimage_blank(self):
|
def test_photoimage_blank(self):
|
||||||
# test a image using mode/size:
|
# test a image using mode/size:
|
||||||
for mode in TK_MODES:
|
for mode in TK_MODES:
|
||||||
im_tk = ImageTk.PhotoImage(mode, (100,100))
|
im_tk = ImageTk.PhotoImage(mode, (100, 100))
|
||||||
|
|
||||||
self.assertEqual(im_tk.width(), 100)
|
self.assertEqual(im_tk.width(), 100)
|
||||||
self.assertEqual(im_tk.height(), 100)
|
self.assertEqual(im_tk.height(), 100)
|
||||||
|
|
||||||
#reloaded = ImageTk.getimage(im_tk)
|
# reloaded = ImageTk.getimage(im_tk)
|
||||||
#self.assert_image_equal(reloaded, im)
|
# self.assert_image_equal(reloaded, im)
|
||||||
|
|
||||||
def test_bitmapimage(self):
|
def test_bitmapimage(self):
|
||||||
im = hopper('1')
|
im = hopper('1')
|
||||||
|
|
||||||
# this should not crash
|
# this should not crash
|
||||||
im_tk = ImageTk.BitmapImage(im)
|
im_tk = ImageTk.BitmapImage(im)
|
||||||
|
|
||||||
self.assertEqual(im_tk.width(), im.width)
|
self.assertEqual(im_tk.width(), im.width)
|
||||||
self.assertEqual(im_tk.height(), im.height)
|
self.assertEqual(im_tk.height(), im.height)
|
||||||
|
|
||||||
#reloaded = ImageTk.getimage(im_tk)
|
|
||||||
#self.assert_image_equal(reloaded, im)
|
|
||||||
|
|
||||||
|
|
||||||
|
# reloaded = ImageTk.getimage(im_tk)
|
||||||
|
# self.assert_image_equal(reloaded, im)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -233,7 +233,6 @@ class DdsImageFile(ImageFile.ImageFile):
|
||||||
bitcount, rmask, gmask, bmask, amask = struct.unpack("<5I",
|
bitcount, rmask, gmask, bmask, amask = struct.unpack("<5I",
|
||||||
header.read(20))
|
header.read(20))
|
||||||
|
|
||||||
|
|
||||||
if fourcc == b"DXT1":
|
if fourcc == b"DXT1":
|
||||||
self.decoder = "DXT1"
|
self.decoder = "DXT1"
|
||||||
codec = _dxt1
|
codec = _dxt1
|
||||||
|
@ -247,7 +246,6 @@ class DdsImageFile(ImageFile.ImageFile):
|
||||||
(self.decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))
|
(self.decoder, (0, 0) + self.size, 0, (self.mode, 0, 1))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def load_seek(self, pos):
|
def load_seek(self, pos):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -260,8 +258,8 @@ class DXT1Decoder(ImageFile.PyDecoder):
|
||||||
self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize))
|
self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize))
|
||||||
except struct.error:
|
except struct.error:
|
||||||
raise IOError("Truncated DDS file")
|
raise IOError("Truncated DDS file")
|
||||||
|
return 0, 0
|
||||||
return 0,0
|
|
||||||
|
|
||||||
class DXT5Decoder(ImageFile.PyDecoder):
|
class DXT5Decoder(ImageFile.PyDecoder):
|
||||||
_pulls_fd = True
|
_pulls_fd = True
|
||||||
|
@ -271,7 +269,7 @@ class DXT5Decoder(ImageFile.PyDecoder):
|
||||||
self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize))
|
self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize))
|
||||||
except struct.error:
|
except struct.error:
|
||||||
raise IOError("Truncated DDS file")
|
raise IOError("Truncated DDS file")
|
||||||
return 0,0
|
return 0, 0
|
||||||
|
|
||||||
Image.register_decoder('DXT1', DXT1Decoder)
|
Image.register_decoder('DXT1', DXT1Decoder)
|
||||||
Image.register_decoder('DXT5', DXT5Decoder)
|
Image.register_decoder('DXT5', DXT5Decoder)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user