Merge pull request #5156 from radarhere/better-binary-use

Better _binary module use
This commit is contained in:
Andrew Murray 2020-12-31 00:07:46 +11:00 committed by GitHub
commit e1e77ff735
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 161 additions and 178 deletions

View File

@ -25,7 +25,6 @@
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import i32le as i32 from ._binary import i32le as i32
from ._binary import o8 from ._binary import o8
@ -52,7 +51,7 @@ def _accept(prefix):
def _dib_accept(prefix): def _dib_accept(prefix):
return i32(prefix[:4]) in [12, 40, 64, 108, 124] return i32(prefix) in [12, 40, 64, 108, 124]
# ============================================================================= # =============================================================================
@ -87,34 +86,34 @@ class BmpImageFile(ImageFile.ImageFile):
# -------------------------------------------------- IBM OS/2 Bitmap v1 # -------------------------------------------------- IBM OS/2 Bitmap v1
# ----- This format has different offsets because of width/height types # ----- This format has different offsets because of width/height types
if file_info["header_size"] == 12: if file_info["header_size"] == 12:
file_info["width"] = i16(header_data[0:2]) file_info["width"] = i16(header_data, 0)
file_info["height"] = i16(header_data[2:4]) file_info["height"] = i16(header_data, 2)
file_info["planes"] = i16(header_data[4:6]) file_info["planes"] = i16(header_data, 4)
file_info["bits"] = i16(header_data[6:8]) file_info["bits"] = i16(header_data, 6)
file_info["compression"] = self.RAW file_info["compression"] = self.RAW
file_info["palette_padding"] = 3 file_info["palette_padding"] = 3
# --------------------------------------------- Windows Bitmap v2 to v5 # --------------------------------------------- Windows Bitmap v2 to v5
# v3, OS/2 v2, v4, v5 # v3, OS/2 v2, v4, v5
elif file_info["header_size"] in (40, 64, 108, 124): elif file_info["header_size"] in (40, 64, 108, 124):
file_info["y_flip"] = i8(header_data[7]) == 0xFF file_info["y_flip"] = header_data[7] == 0xFF
file_info["direction"] = 1 if file_info["y_flip"] else -1 file_info["direction"] = 1 if file_info["y_flip"] else -1
file_info["width"] = i32(header_data[0:4]) file_info["width"] = i32(header_data, 0)
file_info["height"] = ( file_info["height"] = (
i32(header_data[4:8]) i32(header_data, 4)
if not file_info["y_flip"] if not file_info["y_flip"]
else 2 ** 32 - i32(header_data[4:8]) else 2 ** 32 - i32(header_data, 4)
) )
file_info["planes"] = i16(header_data[8:10]) file_info["planes"] = i16(header_data, 8)
file_info["bits"] = i16(header_data[10:12]) file_info["bits"] = i16(header_data, 10)
file_info["compression"] = i32(header_data[12:16]) file_info["compression"] = i32(header_data, 12)
# byte size of pixel data # byte size of pixel data
file_info["data_size"] = i32(header_data[16:20]) file_info["data_size"] = i32(header_data, 16)
file_info["pixels_per_meter"] = ( file_info["pixels_per_meter"] = (
i32(header_data[20:24]), i32(header_data, 20),
i32(header_data[24:28]), i32(header_data, 24),
) )
file_info["colors"] = i32(header_data[28:32]) file_info["colors"] = i32(header_data, 28)
file_info["palette_padding"] = 4 file_info["palette_padding"] = 4
self.info["dpi"] = tuple( self.info["dpi"] = tuple(
int(x / 39.3701 + 0.5) for x in file_info["pixels_per_meter"] int(x / 39.3701 + 0.5) for x in file_info["pixels_per_meter"]
@ -124,7 +123,7 @@ class BmpImageFile(ImageFile.ImageFile):
for idx, mask in enumerate( for idx, mask in enumerate(
["r_mask", "g_mask", "b_mask", "a_mask"] ["r_mask", "g_mask", "b_mask", "a_mask"]
): ):
file_info[mask] = i32(header_data[36 + idx * 4 : 40 + idx * 4]) file_info[mask] = i32(header_data, 36 + idx * 4)
else: else:
# 40 byte headers only have the three components in the # 40 byte headers only have the three components in the
# bitfields masks, ref: # bitfields masks, ref:
@ -267,7 +266,7 @@ class BmpImageFile(ImageFile.ImageFile):
if not _accept(head_data): if not _accept(head_data):
raise SyntaxError("Not a BMP file") raise SyntaxError("Not a BMP file")
# read the start position of the BMP image data (u32) # read the start position of the BMP image data (u32)
offset = i32(head_data[10:14]) offset = i32(head_data, 10)
# load bitmap information (offset=raster info) # load bitmap information (offset=raster info)
self._bitmap(offset=offset) self._bitmap(offset=offset)

View File

@ -16,7 +16,6 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
from . import BmpImagePlugin, Image from . import BmpImagePlugin, Image
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import i32le as i32 from ._binary import i32le as i32
@ -48,17 +47,17 @@ class CurImageFile(BmpImagePlugin.BmpImageFile):
# pick the largest cursor in the file # pick the largest cursor in the file
m = b"" m = b""
for i in range(i16(s[4:])): for i in range(i16(s, 4)):
s = self.fp.read(16) s = self.fp.read(16)
if not m: if not m:
m = s m = s
elif i8(s[0]) > i8(m[0]) and i8(s[1]) > i8(m[1]): elif s[0] > m[0] and s[1] > m[1]:
m = s m = s
if not m: if not m:
raise TypeError("No cursors were found") raise TypeError("No cursors were found")
# load as bitmap # load as bitmap
self._bitmap(i32(m[12:]) + offset) self._bitmap(i32(m, 12) + offset)
# patch up the bitmap height # patch up the bitmap height
self._size = self.size[0], self.size[1] // 2 self._size = self.size[0], self.size[1] // 2

View File

@ -312,14 +312,14 @@ class EpsImageFile(ImageFile.ImageFile):
fp.seek(0, io.SEEK_END) fp.seek(0, io.SEEK_END)
length = fp.tell() length = fp.tell()
offset = 0 offset = 0
elif i32(s[0:4]) == 0xC6D3D0C5: elif i32(s, 0) == 0xC6D3D0C5:
# FIX for: Some EPS file not handled correctly / issue #302 # FIX for: Some EPS file not handled correctly / issue #302
# EPS can contain binary data # EPS can contain binary data
# or start directly with latin coding # or start directly with latin coding
# more info see: # more info see:
# https://web.archive.org/web/20160528181353/http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf # https://web.archive.org/web/20160528181353/http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf
offset = i32(s[4:8]) offset = i32(s, 4)
length = i32(s[8:12]) length = i32(s, 8)
else: else:
raise SyntaxError("not an EPS file") raise SyntaxError("not an EPS file")

View File

@ -17,7 +17,6 @@
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import i32le as i32 from ._binary import i32le as i32
from ._binary import o8 from ._binary import o8
@ -27,7 +26,7 @@ from ._binary import o8
def _accept(prefix): def _accept(prefix):
return len(prefix) >= 6 and i16(prefix[4:6]) in [0xAF11, 0xAF12] return len(prefix) >= 6 and i16(prefix, 4) in [0xAF11, 0xAF12]
## ##
@ -47,22 +46,22 @@ class FliImageFile(ImageFile.ImageFile):
s = self.fp.read(128) s = self.fp.read(128)
if not ( if not (
_accept(s) _accept(s)
and i16(s[14:16]) in [0, 3] # flags and i16(s, 14) in [0, 3] # flags
and s[20:22] == b"\x00\x00" # reserved and s[20:22] == b"\x00\x00" # reserved
): ):
raise SyntaxError("not an FLI/FLC file") raise SyntaxError("not an FLI/FLC file")
# frames # frames
self.n_frames = i16(s[6:8]) self.n_frames = i16(s, 6)
self.is_animated = self.n_frames > 1 self.is_animated = self.n_frames > 1
# image characteristics # image characteristics
self.mode = "P" self.mode = "P"
self._size = i16(s[8:10]), i16(s[10:12]) self._size = i16(s, 8), i16(s, 10)
# animation speed # animation speed
duration = i32(s[16:20]) duration = i32(s, 16)
magic = i16(s[4:6]) magic = i16(s, 4)
if magic == 0xAF11: if magic == 0xAF11:
duration = (duration * 1000) // 70 duration = (duration * 1000) // 70
self.info["duration"] = duration self.info["duration"] = duration
@ -74,17 +73,17 @@ class FliImageFile(ImageFile.ImageFile):
self.__offset = 128 self.__offset = 128
if i16(s[4:6]) == 0xF100: if i16(s, 4) == 0xF100:
# prefix chunk; ignore it # prefix chunk; ignore it
self.__offset = self.__offset + i32(s) self.__offset = self.__offset + i32(s)
s = self.fp.read(16) s = self.fp.read(16)
if i16(s[4:6]) == 0xF1FA: if i16(s, 4) == 0xF1FA:
# look for palette chunk # look for palette chunk
s = self.fp.read(6) s = self.fp.read(6)
if i16(s[4:6]) == 11: if i16(s, 4) == 11:
self._palette(palette, 2) self._palette(palette, 2)
elif i16(s[4:6]) == 4: elif i16(s, 4) == 4:
self._palette(palette, 0) self._palette(palette, 0)
palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette] palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette]
@ -102,15 +101,15 @@ class FliImageFile(ImageFile.ImageFile):
i = 0 i = 0
for e in range(i16(self.fp.read(2))): for e in range(i16(self.fp.read(2))):
s = self.fp.read(2) s = self.fp.read(2)
i = i + i8(s[0]) i = i + s[0]
n = i8(s[1]) n = s[1]
if n == 0: if n == 0:
n = 256 n = 256
s = self.fp.read(n * 3) s = self.fp.read(n * 3)
for n in range(0, len(s), 3): for n in range(0, len(s), 3):
r = i8(s[n]) << shift r = s[n] << shift
g = i8(s[n + 1]) << shift g = s[n + 1] << shift
b = i8(s[n + 2]) << shift b = s[n + 2] << shift
palette[i] = (r, g, b) palette[i] = (r, g, b)
i += 1 i += 1

View File

@ -17,7 +17,6 @@
import olefile import olefile
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i8
from ._binary import i32le as i32 from ._binary import i32le as i32
# we map from colour field tuples to (mode, rawmode) descriptors # we map from colour field tuples to (mode, rawmode) descriptors
@ -181,8 +180,8 @@ class FpxImageFile(ImageFile.ImageFile):
elif compression == 2: elif compression == 2:
internal_color_conversion = i8(s[14]) internal_color_conversion = s[14]
jpeg_tables = i8(s[15]) jpeg_tables = s[15]
rawmode = self.rawmode rawmode = self.rawmode
if internal_color_conversion: if internal_color_conversion:

View File

@ -29,7 +29,7 @@ from ._binary import i32be as i32
def _accept(prefix): def _accept(prefix):
return len(prefix) >= 8 and i32(prefix[:4]) >= 20 and i32(prefix[4:8]) in (1, 2) return len(prefix) >= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2)
## ##

View File

@ -28,7 +28,6 @@
from . import ImageFile, ImagePalette, UnidentifiedImageError from . import ImageFile, ImagePalette, UnidentifiedImageError
from ._binary import i8
from ._binary import i16be as i16 from ._binary import i16be as i16
from ._binary import i32be as i32 from ._binary import i32be as i32
@ -49,17 +48,17 @@ class GdImageFile(ImageFile.ImageFile):
# Header # Header
s = self.fp.read(1037) s = self.fp.read(1037)
if not i16(s[:2]) in [65534, 65535]: if not i16(s) in [65534, 65535]:
raise SyntaxError("Not a valid GD 2.x .gd file") raise SyntaxError("Not a valid GD 2.x .gd file")
self.mode = "L" # FIXME: "P" self.mode = "L" # FIXME: "P"
self._size = i16(s[2:4]), i16(s[4:6]) self._size = i16(s, 2), i16(s, 4)
trueColor = i8(s[6]) trueColor = s[6]
trueColorOffset = 2 if trueColor else 0 trueColorOffset = 2 if trueColor else 0
# transparency index # transparency index
tindex = i32(s[7 + trueColorOffset : 7 + trueColorOffset + 4]) tindex = i32(s, 7 + trueColorOffset)
if tindex < 256: if tindex < 256:
self.info["transparency"] = tindex self.info["transparency"] = tindex

View File

@ -30,7 +30,6 @@ import os
import subprocess import subprocess
from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import o8 from ._binary import o8
from ._binary import o16le as o16 from ._binary import o16le as o16
@ -58,8 +57,8 @@ class GifImageFile(ImageFile.ImageFile):
def data(self): def data(self):
s = self.fp.read(1) s = self.fp.read(1)
if s and i8(s): if s and s[0]:
return self.fp.read(i8(s)) return self.fp.read(s[0])
return None return None
def _open(self): def _open(self):
@ -70,18 +69,18 @@ class GifImageFile(ImageFile.ImageFile):
raise SyntaxError("not a GIF file") raise SyntaxError("not a GIF file")
self.info["version"] = s[:6] self.info["version"] = s[:6]
self._size = i16(s[6:]), i16(s[8:]) self._size = i16(s, 6), i16(s, 8)
self.tile = [] self.tile = []
flags = i8(s[10]) flags = s[10]
bits = (flags & 7) + 1 bits = (flags & 7) + 1
if flags & 128: if flags & 128:
# get global palette # get global palette
self.info["background"] = i8(s[11]) self.info["background"] = s[11]
# check if palette contains colour indices # check if palette contains colour indices
p = self.fp.read(3 << bits) p = self.fp.read(3 << bits)
for i in range(0, len(p), 3): for i in range(0, len(p), 3):
if not (i // 3 == i8(p[i]) == i8(p[i + 1]) == i8(p[i + 2])): if not (i // 3 == p[i] == p[i + 1] == p[i + 2]):
p = ImagePalette.raw("RGB", p) p = ImagePalette.raw("RGB", p)
self.global_palette = self.palette = p self.global_palette = self.palette = p
break break
@ -187,14 +186,14 @@ class GifImageFile(ImageFile.ImageFile):
# #
s = self.fp.read(1) s = self.fp.read(1)
block = self.data() block = self.data()
if i8(s) == 249: if s[0] == 249:
# #
# graphic control extension # graphic control extension
# #
flags = i8(block[0]) flags = block[0]
if flags & 1: if flags & 1:
info["transparency"] = i8(block[3]) info["transparency"] = block[3]
info["duration"] = i16(block[1:3]) * 10 info["duration"] = i16(block, 1) * 10
# disposal method - find the value of bits 4 - 6 # disposal method - find the value of bits 4 - 6
dispose_bits = 0b00011100 & flags dispose_bits = 0b00011100 & flags
@ -205,7 +204,7 @@ class GifImageFile(ImageFile.ImageFile):
# correct, but it seems to prevent the last # correct, but it seems to prevent the last
# frame from looking odd for some animations # frame from looking odd for some animations
self.disposal_method = dispose_bits self.disposal_method = dispose_bits
elif i8(s) == 254: elif s[0] == 254:
# #
# comment extension # comment extension
# #
@ -216,15 +215,15 @@ class GifImageFile(ImageFile.ImageFile):
info["comment"] = block info["comment"] = block
block = self.data() block = self.data()
continue continue
elif i8(s) == 255: elif s[0] == 255:
# #
# application extension # application extension
# #
info["extension"] = block, self.fp.tell() info["extension"] = block, self.fp.tell()
if block[:11] == b"NETSCAPE2.0": if block[:11] == b"NETSCAPE2.0":
block = self.data() block = self.data()
if len(block) >= 3 and i8(block[0]) == 1: if len(block) >= 3 and block[0] == 1:
info["loop"] = i16(block[1:3]) info["loop"] = i16(block, 1)
while self.data(): while self.data():
pass pass
@ -235,12 +234,12 @@ class GifImageFile(ImageFile.ImageFile):
s = self.fp.read(9) s = self.fp.read(9)
# extent # extent
x0, y0 = i16(s[0:]), i16(s[2:]) x0, y0 = i16(s, 0), i16(s, 2)
x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:]) x1, y1 = x0 + i16(s, 4), y0 + i16(s, 6)
if x1 > self.size[0] or y1 > self.size[1]: if x1 > self.size[0] or y1 > self.size[1]:
self._size = max(x1, self.size[0]), max(y1, self.size[1]) self._size = max(x1, self.size[0]), max(y1, self.size[1])
self.dispose_extent = x0, y0, x1, y1 self.dispose_extent = x0, y0, x1, y1
flags = i8(s[8]) flags = s[8]
interlace = (flags & 64) != 0 interlace = (flags & 64) != 0
@ -249,7 +248,7 @@ class GifImageFile(ImageFile.ImageFile):
self.palette = ImagePalette.raw("RGB", self.fp.read(3 << bits)) self.palette = ImagePalette.raw("RGB", self.fp.read(3 << bits))
# image data # image data
bits = i8(self.fp.read(1)) bits = self.fp.read(1)[0]
self.__offset = self.fp.tell() self.__offset = self.fp.tell()
self.tile = [ self.tile = [
("gif", (x0, y0, x1, y1), self.__offset, (bits, interlace)) ("gif", (x0, y0, x1, y1), self.__offset, (bits, interlace))
@ -258,7 +257,7 @@ class GifImageFile(ImageFile.ImageFile):
else: else:
pass pass
# raise OSError, "illegal GIF tag `%x`" % i8(s) # raise OSError, "illegal GIF tag `%x`" % s[0]
try: try:
if self.disposal_method < 2: if self.disposal_method < 2:

View File

@ -10,7 +10,6 @@
# #
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i8
_handler = None _handler = None
@ -30,7 +29,7 @@ def register_handler(handler):
def _accept(prefix): def _accept(prefix):
return prefix[0:4] == b"GRIB" and i8(prefix[7]) == 1 return prefix[0:4] == b"GRIB" and prefix[7] == 1
class GribStubImageFile(ImageFile.StubImageFile): class GribStubImageFile(ImageFile.StubImageFile):

View File

@ -24,7 +24,6 @@ import sys
import tempfile import tempfile
from PIL import Image, ImageFile, PngImagePlugin, features from PIL import Image, ImageFile, PngImagePlugin, features
from PIL._binary import i8
enable_jpeg2k = features.check_codec("jpg_2000") enable_jpeg2k = features.check_codec("jpg_2000")
if enable_jpeg2k: if enable_jpeg2k:
@ -70,7 +69,7 @@ def read_32(fobj, start_length, size):
byte = fobj.read(1) byte = fobj.read(1)
if not byte: if not byte:
break break
byte = i8(byte) byte = byte[0]
if byte & 0x80: if byte & 0x80:
blocksize = byte - 125 blocksize = byte - 125
byte = fobj.read(1) byte = fobj.read(1)

View File

@ -28,7 +28,6 @@ from io import BytesIO
from math import ceil, log from math import ceil, log
from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import i32le as i32 from ._binary import i32le as i32
@ -103,21 +102,21 @@ class IcoFile:
self.entry = [] self.entry = []
# Number of items in file # Number of items in file
self.nb_items = i16(s[4:]) self.nb_items = i16(s, 4)
# Get headers for each item # Get headers for each item
for i in range(self.nb_items): for i in range(self.nb_items):
s = buf.read(16) s = buf.read(16)
icon_header = { icon_header = {
"width": i8(s[0]), "width": s[0],
"height": i8(s[1]), "height": s[1],
"nb_color": i8(s[2]), # No. of colors in image (0 if >=8bpp) "nb_color": s[2], # No. of colors in image (0 if >=8bpp)
"reserved": i8(s[3]), "reserved": s[3],
"planes": i16(s[4:]), "planes": i16(s, 4),
"bpp": i16(s[6:]), "bpp": i16(s, 6),
"size": i32(s[8:]), "size": i32(s, 8),
"offset": i32(s[12:]), "offset": i32(s, 12),
} }
# See Wikipedia # See Wikipedia

View File

@ -30,7 +30,6 @@ import os
import re import re
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Standard tags # Standard tags
@ -223,14 +222,14 @@ class ImImageFile(ImageFile.ImageFile):
linear = 1 # linear greyscale palette linear = 1 # linear greyscale palette
for i in range(256): for i in range(256):
if palette[i] == palette[i + 256] == palette[i + 512]: if palette[i] == palette[i + 256] == palette[i + 512]:
if i8(palette[i]) != i: if palette[i] != i:
linear = 0 linear = 0
else: else:
greyscale = 0 greyscale = 0
if self.mode in ["L", "LA", "P", "PA"]: if self.mode in ["L", "LA", "P", "PA"]:
if greyscale: if greyscale:
if not linear: if not linear:
self.lut = [i8(c) for c in palette[:256]] self.lut = list(palette[:256])
else: else:
if self.mode in ["L", "P"]: if self.mode in ["L", "P"]:
self.mode = self.rawmode = "P" self.mode = self.rawmode = "P"
@ -240,7 +239,7 @@ class ImImageFile(ImageFile.ImageFile):
self.palette = ImagePalette.raw("RGB;L", palette) self.palette = ImagePalette.raw("RGB;L", palette)
elif self.mode == "RGB": elif self.mode == "RGB":
if not greyscale or not linear: if not greyscale or not linear:
self.lut = [i8(c) for c in palette] self.lut = list(palette)
self.frame = 0 self.frame = 0

View File

@ -50,7 +50,7 @@ from . import (
_plugins, _plugins,
_raise_version_warning, _raise_version_warning,
) )
from ._binary import i8, i32le from ._binary import i32le
from ._util import deferred_error, isPath from ._util import deferred_error, isPath
if sys.version_info >= (3, 7): if sys.version_info >= (3, 7):
@ -1378,7 +1378,7 @@ class Image:
self.load() self.load()
x, y = self.im.getprojection() x, y = self.im.getprojection()
return [i8(c) for c in x], [i8(c) for c in y] return list(x), list(y)
def histogram(self, mask=None, extrema=None): def histogram(self, mask=None, extrema=None):
""" """
@ -3374,7 +3374,7 @@ class Exif(MutableMapping):
if self[0x927C][:8] == b"FUJIFILM": if self[0x927C][:8] == b"FUJIFILM":
exif_data = self[0x927C] exif_data = self[0x927C]
ifd_offset = i32le(exif_data[8:12]) ifd_offset = i32le(exif_data, 8)
ifd_data = exif_data[ifd_offset:] ifd_data = exif_data[ifd_offset:]
makernote = {} makernote = {}

View File

@ -62,14 +62,14 @@ class IptcImageFile(ImageFile.ImageFile):
if not len(s): if not len(s):
return None, 0 return None, 0
tag = i8(s[1]), i8(s[2]) tag = s[1], s[2]
# syntax # syntax
if i8(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9: if s[0] != 0x1C or tag[0] < 1 or tag[0] > 9:
raise SyntaxError("invalid IPTC/NAA file") raise SyntaxError("invalid IPTC/NAA file")
# field size # field size
size = i8(s[3]) size = s[3]
if size > 132: if size > 132:
raise OSError("illegal field length in IPTC/NAA file") raise OSError("illegal field length in IPTC/NAA file")
elif size == 128: elif size == 128:
@ -77,7 +77,7 @@ class IptcImageFile(ImageFile.ImageFile):
elif size > 128: elif size > 128:
size = i(self.fp.read(size - 128)) size = i(self.fp.read(size - 128))
else: else:
size = i16(s[3:]) size = i16(s, 3)
return tag, size return tag, size

View File

@ -41,7 +41,6 @@ import tempfile
import warnings import warnings
from . import Image, ImageFile, TiffImagePlugin from . import Image, ImageFile, TiffImagePlugin
from ._binary import i8
from ._binary import i16be as i16 from ._binary import i16be as i16
from ._binary import i32be as i32 from ._binary import i32be as i32
from ._binary import o8 from ._binary import o8
@ -75,7 +74,7 @@ def APP(self, marker):
self.info["jfif_version"] = divmod(version, 256) self.info["jfif_version"] = divmod(version, 256)
# extract JFIF properties # extract JFIF properties
try: try:
jfif_unit = i8(s[7]) jfif_unit = s[7]
jfif_density = i16(s, 8), i16(s, 10) jfif_density = i16(s, 8), i16(s, 10)
except Exception: except Exception:
pass pass
@ -115,7 +114,7 @@ def APP(self, marker):
code = i16(s, offset) code = i16(s, offset)
offset += 2 offset += 2
# resource name (usually empty) # resource name (usually empty)
name_len = i8(s[offset]) name_len = s[offset]
# name = s[offset+1:offset+1+name_len] # name = s[offset+1:offset+1+name_len]
offset += 1 + name_len offset += 1 + name_len
offset += offset & 1 # align offset += offset & 1 # align
@ -125,10 +124,10 @@ def APP(self, marker):
data = s[offset : offset + size] data = s[offset : offset + size]
if code == 0x03ED: # ResolutionInfo if code == 0x03ED: # ResolutionInfo
data = { data = {
"XResolution": i32(data[:4]) / 65536, "XResolution": i32(data, 0) / 65536,
"DisplayedUnitsX": i16(data[4:8]), "DisplayedUnitsX": i16(data, 4),
"YResolution": i32(data[8:12]) / 65536, "YResolution": i32(data, 8) / 65536,
"DisplayedUnitsY": i16(data[12:]), "DisplayedUnitsY": i16(data, 12),
} }
photoshop[code] = data photoshop[code] = data
offset += size offset += size
@ -140,7 +139,7 @@ def APP(self, marker):
self.info["adobe"] = i16(s, 5) self.info["adobe"] = i16(s, 5)
# extract Adobe custom properties # extract Adobe custom properties
try: try:
adobe_transform = i8(s[1]) adobe_transform = s[1]
except Exception: except Exception:
pass pass
else: else:
@ -195,13 +194,13 @@ def SOF(self, marker):
n = i16(self.fp.read(2)) - 2 n = i16(self.fp.read(2)) - 2
s = ImageFile._safe_read(self.fp, n) s = ImageFile._safe_read(self.fp, n)
self._size = i16(s[3:]), i16(s[1:]) self._size = i16(s, 3), i16(s, 1)
self.bits = i8(s[0]) self.bits = s[0]
if self.bits != 8: if self.bits != 8:
raise SyntaxError(f"cannot handle {self.bits}-bit layers") raise SyntaxError(f"cannot handle {self.bits}-bit layers")
self.layers = i8(s[5]) self.layers = s[5]
if self.layers == 1: if self.layers == 1:
self.mode = "L" self.mode = "L"
elif self.layers == 3: elif self.layers == 3:
@ -217,7 +216,7 @@ def SOF(self, marker):
if self.icclist: if self.icclist:
# fixup icc profile # fixup icc profile
self.icclist.sort() # sort by sequence number self.icclist.sort() # sort by sequence number
if i8(self.icclist[0][13]) == len(self.icclist): if self.icclist[0][13] == len(self.icclist):
profile = [] profile = []
for p in self.icclist: for p in self.icclist:
profile.append(p[14:]) profile.append(p[14:])
@ -230,7 +229,7 @@ def SOF(self, marker):
for i in range(6, len(s), 3): for i in range(6, len(s), 3):
t = s[i : i + 3] t = s[i : i + 3]
# 4-tuples: id, vsamp, hsamp, qtable # 4-tuples: id, vsamp, hsamp, qtable
self.layer.append((t[0], i8(t[1]) // 16, i8(t[1]) & 15, i8(t[2]))) self.layer.append((t[0], t[1] // 16, t[1] & 15, t[2]))
def DQT(self, marker): def DQT(self, marker):
@ -244,7 +243,7 @@ def DQT(self, marker):
n = i16(self.fp.read(2)) - 2 n = i16(self.fp.read(2)) - 2
s = ImageFile._safe_read(self.fp, n) s = ImageFile._safe_read(self.fp, n)
while len(s): while len(s):
v = i8(s[0]) v = s[0]
precision = 1 if (v // 16 == 0) else 2 # in bytes precision = 1 if (v // 16 == 0) else 2 # in bytes
qt_length = 1 + precision * 64 qt_length = 1 + precision * 64
if len(s) < qt_length: if len(s) < qt_length:
@ -362,7 +361,7 @@ class JpegImageFile(ImageFile.ImageFile):
while True: while True:
i = i8(s) i = s[0]
if i == 0xFF: if i == 0xFF:
s = s + self.fp.read(1) s = s + self.fp.read(1)
i = i16(s) i = i16(s)

View File

@ -27,7 +27,6 @@ import io
import struct import struct
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import o16le as o16 from ._binary import o16le as o16
@ -59,12 +58,12 @@ class MspImageFile(ImageFile.ImageFile):
# Header checksum # Header checksum
checksum = 0 checksum = 0
for i in range(0, 32, 2): for i in range(0, 32, 2):
checksum = checksum ^ i16(s[i : i + 2]) checksum = checksum ^ i16(s, i)
if checksum != 0: if checksum != 0:
raise SyntaxError("bad MSP checksum") raise SyntaxError("bad MSP checksum")
self.mode = "1" self.mode = "1"
self._size = i16(s[4:]), i16(s[6:]) self._size = i16(s, 4), i16(s, 6)
if s[:4] == b"DanM": if s[:4] == b"DanM":
self.tile = [("raw", (0, 0) + self.size, 32, ("1", 0, 1))] self.tile = [("raw", (0, 0) + self.size, 32, ("1", 0, 1))]
@ -133,7 +132,7 @@ class MspDecoder(ImageFile.PyDecoder):
) )
idx = 0 idx = 0
while idx < rowlen: while idx < rowlen:
runtype = i8(row[idx]) runtype = row[idx]
idx += 1 idx += 1
if runtype == 0: if runtype == 0:
(runcount, runval) = struct.unpack_from("Bc", row, idx) (runcount, runval) = struct.unpack_from("Bc", row, idx)

View File

@ -16,7 +16,6 @@
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i8
## ##
# Image plugin for PhotoCD images. This plugin only reads the 768x512 # Image plugin for PhotoCD images. This plugin only reads the 768x512
@ -38,7 +37,7 @@ class PcdImageFile(ImageFile.ImageFile):
if s[:4] != b"PCD_": if s[:4] != b"PCD_":
raise SyntaxError("not a PCD file") raise SyntaxError("not a PCD file")
orientation = i8(s[1538]) & 3 orientation = s[1538] & 3
self.tile_post_rotate = None self.tile_post_rotate = None
if orientation == 1: if orientation == 1:
self.tile_post_rotate = 90 self.tile_post_rotate = 90

View File

@ -29,7 +29,6 @@ import io
import logging import logging
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import o8 from ._binary import o8
from ._binary import o16le as o16 from ._binary import o16le as o16
@ -38,7 +37,7 @@ logger = logging.getLogger(__name__)
def _accept(prefix): def _accept(prefix):
return i8(prefix[0]) == 10 and i8(prefix[1]) in [0, 2, 3, 5] return prefix[0] == 10 and prefix[1] in [0, 2, 3, 5]
## ##
@ -64,9 +63,9 @@ class PcxImageFile(ImageFile.ImageFile):
logger.debug("BBox: %s %s %s %s", *bbox) logger.debug("BBox: %s %s %s %s", *bbox)
# format # format
version = i8(s[1]) version = s[1]
bits = i8(s[3]) bits = s[3]
planes = i8(s[65]) planes = s[65]
stride = i16(s, 66) stride = i16(s, 66)
logger.debug( logger.debug(
"PCX version %s, bits %s, planes %s, stride %s", "PCX version %s, bits %s, planes %s, stride %s",
@ -91,7 +90,7 @@ class PcxImageFile(ImageFile.ImageFile):
# FIXME: hey, this doesn't work with the incremental loader !!! # FIXME: hey, this doesn't work with the incremental loader !!!
self.fp.seek(-769, io.SEEK_END) self.fp.seek(-769, io.SEEK_END)
s = self.fp.read(769) s = self.fp.read(769)
if len(s) == 769 and i8(s[0]) == 12: if len(s) == 769 and s[0] == 12:
# check if the palette is linear greyscale # check if the palette is linear greyscale
for i in range(256): for i in range(256):
if s[i * 3 + 1 : i * 3 + 4] != o8(i) * 3: if s[i * 3 + 1 : i * 3 + 4] != o8(i) * 3:

View File

@ -49,10 +49,10 @@ class PixarImageFile(ImageFile.ImageFile):
# read rest of header # read rest of header
s = s + self.fp.read(508) s = s + self.fp.read(508)
self._size = i16(s[418:420]), i16(s[416:418]) self._size = i16(s, 418), i16(s, 416)
# get channel/depth descriptions # get channel/depth descriptions
mode = i16(s[424:426]), i16(s[426:428]) mode = i16(s, 424), i16(s, 426)
if mode == (14, 2): if mode == (14, 2):
self.mode = "RGB" self.mode = "RGB"

View File

@ -39,7 +39,6 @@ import warnings
import zlib import zlib
from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence
from ._binary import i8
from ._binary import i16be as i16 from ._binary import i16be as i16
from ._binary import i32be as i32 from ._binary import i32be as i32
from ._binary import o8 from ._binary import o8
@ -193,7 +192,7 @@ class ChunkStream:
# Skip CRC checks for ancillary chunks if allowed to load truncated # Skip CRC checks for ancillary chunks if allowed to load truncated
# images # images
# 5th byte of first char is 1 [specs, section 5.4] # 5th byte of first char is 1 [specs, section 5.4]
if ImageFile.LOAD_TRUNCATED_IMAGES and (i8(cid[0]) >> 5 & 1): if ImageFile.LOAD_TRUNCATED_IMAGES and (cid[0] >> 5 & 1):
self.crc_skip(cid, data) self.crc_skip(cid, data)
return return
@ -390,8 +389,8 @@ class PngStream(ChunkStream):
# Compressed profile n bytes (zlib with deflate compression) # Compressed profile n bytes (zlib with deflate compression)
i = s.find(b"\0") i = s.find(b"\0")
logger.debug("iCCP profile name %r", s[:i]) logger.debug("iCCP profile name %r", s[:i])
logger.debug("Compression method %s", i8(s[i])) logger.debug("Compression method %s", s[i])
comp_method = i8(s[i]) comp_method = s[i]
if comp_method != 0: if comp_method != 0:
raise SyntaxError(f"Unknown compression method {comp_method} in iCCP chunk") raise SyntaxError(f"Unknown compression method {comp_method} in iCCP chunk")
try: try:
@ -410,14 +409,14 @@ class PngStream(ChunkStream):
# image header # image header
s = ImageFile._safe_read(self.fp, length) s = ImageFile._safe_read(self.fp, length)
self.im_size = i32(s), i32(s[4:]) self.im_size = i32(s, 0), i32(s, 4)
try: try:
self.im_mode, self.im_rawmode = _MODES[(i8(s[8]), i8(s[9]))] self.im_mode, self.im_rawmode = _MODES[(s[8], s[9])]
except Exception: except Exception:
pass pass
if i8(s[12]): if s[12]:
self.im_info["interlace"] = 1 self.im_info["interlace"] = 1
if i8(s[11]): if s[11]:
raise SyntaxError("unknown filter category") raise SyntaxError("unknown filter category")
return s return s
@ -465,7 +464,7 @@ class PngStream(ChunkStream):
elif self.im_mode in ("1", "L", "I"): elif self.im_mode in ("1", "L", "I"):
self.im_info["transparency"] = i16(s) self.im_info["transparency"] = i16(s)
elif self.im_mode == "RGB": elif self.im_mode == "RGB":
self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:]) self.im_info["transparency"] = i16(s), i16(s, 2), i16(s, 4)
return s return s
def chunk_gAMA(self, pos, length): def chunk_gAMA(self, pos, length):
@ -491,15 +490,15 @@ class PngStream(ChunkStream):
# 3 absolute colorimetric # 3 absolute colorimetric
s = ImageFile._safe_read(self.fp, length) s = ImageFile._safe_read(self.fp, length)
self.im_info["srgb"] = i8(s) self.im_info["srgb"] = s[0]
return s return s
def chunk_pHYs(self, pos, length): def chunk_pHYs(self, pos, length):
# pixels per unit # pixels per unit
s = ImageFile._safe_read(self.fp, length) s = ImageFile._safe_read(self.fp, length)
px, py = i32(s), i32(s[4:]) px, py = i32(s, 0), i32(s, 4)
unit = i8(s[8]) unit = s[8]
if unit == 1: # meter if unit == 1: # meter
dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5) dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
self.im_info["dpi"] = dpi self.im_info["dpi"] = dpi
@ -537,7 +536,7 @@ class PngStream(ChunkStream):
k = s k = s
v = b"" v = b""
if v: if v:
comp_method = i8(v[0]) comp_method = v[0]
else: else:
comp_method = 0 comp_method = 0
if comp_method != 0: if comp_method != 0:
@ -571,7 +570,7 @@ class PngStream(ChunkStream):
return s return s
if len(r) < 2: if len(r) < 2:
return s return s
cf, cm, r = i8(r[0]), i8(r[1]), r[2:] cf, cm, r = r[0], r[1], r[2:]
try: try:
lang, tk, v = r.split(b"\0", 2) lang, tk, v = r.split(b"\0", 2)
except ValueError: except ValueError:
@ -619,7 +618,7 @@ class PngStream(ChunkStream):
warnings.warn("Invalid APNG, will use default PNG image if possible") warnings.warn("Invalid APNG, will use default PNG image if possible")
return s return s
self.im_n_frames = n_frames self.im_n_frames = n_frames
self.im_info["loop"] = i32(s[4:]) self.im_info["loop"] = i32(s, 4)
self.im_custom_mimetype = "image/apng" self.im_custom_mimetype = "image/apng"
return s return s
@ -631,18 +630,18 @@ class PngStream(ChunkStream):
): ):
raise SyntaxError("APNG contains frame sequence errors") raise SyntaxError("APNG contains frame sequence errors")
self._seq_num = seq self._seq_num = seq
width, height = i32(s[4:]), i32(s[8:]) width, height = i32(s, 4), i32(s, 8)
px, py = i32(s[12:]), i32(s[16:]) px, py = i32(s, 12), i32(s, 16)
im_w, im_h = self.im_size im_w, im_h = self.im_size
if px + width > im_w or py + height > im_h: if px + width > im_w or py + height > im_h:
raise SyntaxError("APNG contains invalid frames") raise SyntaxError("APNG contains invalid frames")
self.im_info["bbox"] = (px, py, px + width, py + height) self.im_info["bbox"] = (px, py, px + width, py + height)
delay_num, delay_den = i16(s[20:]), i16(s[22:]) delay_num, delay_den = i16(s, 20), i16(s, 22)
if delay_den == 0: if delay_den == 0:
delay_den = 100 delay_den = 100
self.im_info["duration"] = float(delay_num) / float(delay_den) * 1000 self.im_info["duration"] = float(delay_num) / float(delay_den) * 1000
self.im_info["disposal"] = i8(s[24]) self.im_info["disposal"] = s[24]
self.im_info["blend"] = i8(s[25]) self.im_info["blend"] = s[25]
return s return s
def chunk_fdAT(self, pos, length): def chunk_fdAT(self, pos, length):

View File

@ -63,12 +63,12 @@ class PsdImageFile(ImageFile.ImageFile):
# header # header
s = read(26) s = read(26)
if not _accept(s) or i16(s[4:]) != 1: if not _accept(s) or i16(s, 4) != 1:
raise SyntaxError("not a PSD file") raise SyntaxError("not a PSD file")
psd_bits = i16(s[22:]) psd_bits = i16(s, 22)
psd_channels = i16(s[12:]) psd_channels = i16(s, 12)
psd_mode = i16(s[24:]) psd_mode = i16(s, 24)
mode, channels = MODES[(psd_mode, psd_bits)] mode, channels = MODES[(psd_mode, psd_bits)]
@ -76,7 +76,7 @@ class PsdImageFile(ImageFile.ImageFile):
raise OSError("not enough channels") raise OSError("not enough channels")
self.mode = mode self.mode = mode
self._size = i32(s[18:]), i32(s[14:]) self._size = i32(s, 18), i32(s, 14)
# #
# color mode data # color mode data
@ -291,7 +291,7 @@ def _maketile(file, mode, bbox, channels):
layer += ";I" layer += ";I"
tile.append(("packbits", bbox, offset, layer)) tile.append(("packbits", bbox, offset, layer))
for y in range(ysize): for y in range(ysize):
offset = offset + i16(bytecount[i : i + 2]) offset = offset + i16(bytecount, i)
i += 2 i += 2
file.seek(offset) file.seek(offset)

View File

@ -26,7 +26,6 @@ import os
import struct import struct
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i8
from ._binary import i16be as i16 from ._binary import i16be as i16
from ._binary import o8 from ._binary import o8
@ -64,22 +63,22 @@ class SgiImageFile(ImageFile.ImageFile):
raise ValueError("Not an SGI image file") raise ValueError("Not an SGI image file")
# compression : verbatim or RLE # compression : verbatim or RLE
compression = i8(s[2]) compression = s[2]
# bpc : 1 or 2 bytes (8bits or 16bits) # bpc : 1 or 2 bytes (8bits or 16bits)
bpc = i8(s[3]) bpc = s[3]
# dimension : 1, 2 or 3 (depending on xsize, ysize and zsize) # dimension : 1, 2 or 3 (depending on xsize, ysize and zsize)
dimension = i16(s[4:]) dimension = i16(s, 4)
# xsize : width # xsize : width
xsize = i16(s[6:]) xsize = i16(s, 6)
# ysize : height # ysize : height
ysize = i16(s[8:]) ysize = i16(s, 8)
# zsize : channels count # zsize : channels count
zsize = i16(s[10:]) zsize = i16(s, 10)
# layout # layout
layout = bpc, dimension, zsize layout = bpc, dimension, zsize

View File

@ -58,13 +58,13 @@ class SunImageFile(ImageFile.ImageFile):
offset = 32 offset = 32
self._size = i32(s[4:8]), i32(s[8:12]) self._size = i32(s, 4), i32(s, 8)
depth = i32(s[12:16]) depth = i32(s, 12)
# data_length = i32(s[16:20]) # unreliable, ignore. # data_length = i32(s, 16) # unreliable, ignore.
file_type = i32(s[20:24]) file_type = i32(s, 20)
palette_type = i32(s[24:28]) # 0: None, 1: RGB, 2: Raw/arbitrary palette_type = i32(s, 24) # 0: None, 1: RGB, 2: Raw/arbitrary
palette_length = i32(s[28:32]) palette_length = i32(s, 28)
if depth == 1: if depth == 1:
self.mode, rawmode = "1", "1;I" self.mode, rawmode = "1", "1;I"

View File

@ -20,7 +20,6 @@
import warnings import warnings
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8
from ._binary import i16le as i16 from ._binary import i16le as i16
from ._binary import o8 from ._binary import o8
from ._binary import o16le as o16 from ._binary import o16le as o16
@ -56,16 +55,16 @@ class TgaImageFile(ImageFile.ImageFile):
# process header # process header
s = self.fp.read(18) s = self.fp.read(18)
id_len = i8(s[0]) id_len = s[0]
colormaptype = i8(s[1]) colormaptype = s[1]
imagetype = i8(s[2]) imagetype = s[2]
depth = i8(s[16]) depth = s[16]
flags = i8(s[17]) flags = s[17]
self._size = i16(s[12:]), i16(s[14:]) self._size = i16(s, 12), i16(s, 14)
# validate header fields # validate header fields
if ( if (
@ -111,7 +110,7 @@ class TgaImageFile(ImageFile.ImageFile):
if colormaptype: if colormaptype:
# read palette # read palette
start, size, mapdepth = i16(s[3:]), i16(s[5:]), i16(s[7:]) start, size, mapdepth = i16(s, 3), i16(s, 5), i16(s, 7)
if mapdepth == 16: if mapdepth == 16:
self.palette = ImagePalette.raw( self.palette = ImagePalette.raw(
"BGR;16", b"\0" * 2 * start + self.fp.read(2 * size) "BGR;16", b"\0" * 2 * start + self.fp.read(2 * size)

View File

@ -49,7 +49,7 @@ from fractions import Fraction
from numbers import Number, Rational from numbers import Number, Rational
from . import Image, ImageFile, ImagePalette, TiffTags from . import Image, ImageFile, ImagePalette, TiffTags
from ._binary import i8, o8 from ._binary import o8
from .TiffTags import TYPES from .TiffTags import TYPES
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -1518,7 +1518,7 @@ def _save(im, fp, filename):
if im.mode in ["P", "PA"]: if im.mode in ["P", "PA"]:
lut = im.im.getpalette("RGB", "RGB;L") lut = im.im.getpalette("RGB", "RGB;L")
ifd[COLORMAP] = tuple(i8(v) * 256 for v in lut) ifd[COLORMAP] = tuple(v * 256 for v in lut)
# data orientation # data orientation
stride = len(bits) * ((im.size[0] * bits[0] + 7) // 8) stride = len(bits) * ((im.size[0] * bits[0] + 7) // 8)
ifd[ROWSPERSTRIP] = im.size[1] ifd[ROWSPERSTRIP] = im.size[1]

View File

@ -18,7 +18,7 @@
# #
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8, o8 from ._binary import o8
_MAGIC = b"P7 332" _MAGIC = b"P7 332"
@ -59,7 +59,7 @@ class XVThumbImageFile(ImageFile.ImageFile):
s = self.fp.readline() s = self.fp.readline()
if not s: if not s:
raise SyntaxError("Unexpected EOF reading XV thumbnail file") raise SyntaxError("Unexpected EOF reading XV thumbnail file")
if i8(s[0]) != 35: # ie. when not a comment: '#' if s[0] != 35: # ie. when not a comment: '#'
break break
# parse header line (already read) # parse header line (already read)

View File

@ -18,7 +18,7 @@
import re import re
from . import Image, ImageFile, ImagePalette from . import Image, ImageFile, ImagePalette
from ._binary import i8, o8 from ._binary import o8
# XPM header # XPM header
xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)') xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)')
@ -72,7 +72,7 @@ class XpmImageFile(ImageFile.ImageFile):
elif s[-1:] in b"\r\n": elif s[-1:] in b"\r\n":
s = s[:-1] s = s[:-1]
c = i8(s[1]) c = s[1]
s = s[2:-2].split() s = s[2:-2].split()
for i in range(0, len(s), 2): for i in range(0, len(s), 2):