mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-26 09:14:27 +03:00
py3k: The big push
There are two main issues fixed with this commit: * bytes vs. str: All file, image, and palette data are now handled as bytes. A new _binary module consolidates the hacks needed to do this across Python versions. tostring/fromstring methods have been renamed to tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old names for compatibility. Users should move to tobytes/frombytes. One other potentially-breaking change is that text data in image files (such as tags, comments) are now explicitly handled with a specific character encoding in mind. This works well with the Unicode str in Python 3, but may trip up old code expecting a straight byte-for-byte translation to a Python string. This also required a change to Gohlke's tags tests (in Tests/test_file_png.py) to expect Unicode strings from the code. * True div vs. floor div: Many division operations used the "/" operator to do floor division, which is now the "//" operator in Python 3. These were fixed. As of this commit, on the first pass, I have one failing test (improper handling of a slice object in a C module, test_imagepath.py) in Python 3, and three that that I haven't tried running yet (test_imagegl, test_imagegrab, and test_imageqt). I also haven't tested anything on Windows. All but the three skipped tests run flawlessly against Pythons 2.6 and 2.7.
This commit is contained in:
parent
8b704e3005
commit
a7e3b2e47b
|
@ -24,9 +24,9 @@ __version__ = "0.4"
|
|||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
|
||||
from .PngImagePlugin import i16, i32, ChunkStream, _MODES
|
||||
from .PngImagePlugin import i8, i16, i32, ChunkStream, _MODES
|
||||
|
||||
MAGIC = "\212ARG\r\n\032\n"
|
||||
MAGIC = b"\212ARG\r\n\032\n"
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# ARG parser
|
||||
|
@ -67,7 +67,7 @@ class ArgStream(ChunkStream):
|
|||
s = self.fp.read(bytes)
|
||||
self.size = i32(s), i32(s[4:])
|
||||
try:
|
||||
self.mode, self.rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
self.mode, self.rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
except:
|
||||
raise SyntaxError("unknown ARG mode")
|
||||
|
||||
|
@ -154,14 +154,14 @@ class ArgStream(ChunkStream):
|
|||
size = i32(s), i32(s[4:])
|
||||
|
||||
try:
|
||||
mode, rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
mode, rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
except:
|
||||
raise SyntaxError("unknown image mode")
|
||||
|
||||
if full:
|
||||
if ord(s[12]):
|
||||
if i8(s[12]):
|
||||
pass # interlace not yet supported
|
||||
if ord(s[11]):
|
||||
if i8(s[11]):
|
||||
raise SyntaxError("unknown filter category")
|
||||
|
||||
return size, mode, rawmode
|
||||
|
@ -236,7 +236,7 @@ class ArgStream(ChunkStream):
|
|||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.zip_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -252,7 +252,7 @@ class ArgStream(ChunkStream):
|
|||
size, mode, rawmode = self.__getmodesize(s)
|
||||
|
||||
# delta header
|
||||
diff = ord(s[13])
|
||||
diff = i8(s[13])
|
||||
offs = i32(s[14:18]), i32(s[18:22])
|
||||
|
||||
bbox = offs + (offs[0]+size[0], offs[1]+size[1])
|
||||
|
@ -269,7 +269,7 @@ class ArgStream(ChunkStream):
|
|||
self.decoder = Image.core.zip_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -289,7 +289,7 @@ class ArgStream(ChunkStream):
|
|||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.jpeg_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -309,7 +309,7 @@ class ArgStream(ChunkStream):
|
|||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.raw_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
|
|
@ -47,27 +47,27 @@ def bdf_char(f):
|
|||
s = f.readline()
|
||||
if not s:
|
||||
return None
|
||||
if s[:9] == "STARTCHAR":
|
||||
if s[:9] == b"STARTCHAR":
|
||||
break
|
||||
id = s[9:].strip()
|
||||
id = s[9:].strip().decode('ascii')
|
||||
|
||||
# load symbol properties
|
||||
props = {}
|
||||
while True:
|
||||
s = f.readline()
|
||||
if not s or s[:6] == "BITMAP":
|
||||
if not s or s[:6] == b"BITMAP":
|
||||
break
|
||||
i = s.find(" ")
|
||||
props[s[:i]] = s[i+1:-1]
|
||||
i = s.find(b" ")
|
||||
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
|
||||
|
||||
# load bitmap
|
||||
bitmap = []
|
||||
while True:
|
||||
s = f.readline()
|
||||
if not s or s[:7] == "ENDCHAR":
|
||||
if not s or s[:7] == b"ENDCHAR":
|
||||
break
|
||||
bitmap.append(s[:-1])
|
||||
bitmap = "".join(bitmap)
|
||||
bitmap = b"".join(bitmap)
|
||||
|
||||
[x, y, l, d] = [int(s) for s in props["BBX"].split()]
|
||||
[dx, dy] = [int(s) for s in props["DWIDTH"].split()]
|
||||
|
@ -75,7 +75,7 @@ def bdf_char(f):
|
|||
bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
|
||||
|
||||
try:
|
||||
im = Image.fromstring("1", (x, y), bitmap, "hex", "1")
|
||||
im = Image.frombytes("1", (x, y), bitmap, "hex", "1")
|
||||
except ValueError:
|
||||
# deal with zero-width characters
|
||||
im = Image.new("1", (x, y))
|
||||
|
@ -92,7 +92,7 @@ class BdfFontFile(FontFile.FontFile):
|
|||
FontFile.FontFile.__init__(self)
|
||||
|
||||
s = fp.readline()
|
||||
if s[:13] != "STARTFONT 2.1":
|
||||
if s[:13] != b"STARTFONT 2.1":
|
||||
raise SyntaxError("not a valid BDF file")
|
||||
|
||||
props = {}
|
||||
|
@ -100,13 +100,13 @@ class BdfFontFile(FontFile.FontFile):
|
|||
|
||||
while True:
|
||||
s = fp.readline()
|
||||
if not s or s[:13] == "ENDPROPERTIES":
|
||||
if not s or s[:13] == b"ENDPROPERTIES":
|
||||
break
|
||||
i = s.find(" ")
|
||||
props[s[:i]] = s[i+1:-1]
|
||||
if s[:i] in ["COMMENT", "COPYRIGHT"]:
|
||||
if s.find("LogicalFontDescription") < 0:
|
||||
comments.append(s[i+1:-1])
|
||||
i = s.find(b" ")
|
||||
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
|
||||
if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
|
||||
if s.find(b"LogicalFontDescription") < 0:
|
||||
comments.append(s[i+1:-1].decode('ascii'))
|
||||
|
||||
font = props["FONT"].split("-")
|
||||
|
||||
|
|
|
@ -27,20 +27,19 @@
|
|||
__version__ = "0.7"
|
||||
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16le
|
||||
o32 = _binary.o32le
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read BMP file
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
|
||||
BIT2MODE = {
|
||||
# bits => mode, rawmode
|
||||
1: ("P", "P;1"),
|
||||
|
@ -52,7 +51,7 @@ BIT2MODE = {
|
|||
}
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:2] == "BM"
|
||||
return prefix[:2] == b"BM"
|
||||
|
||||
##
|
||||
# Image plugin for the Windows BMP format.
|
||||
|
@ -134,7 +133,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
indices = list(range(colors))
|
||||
for i in indices:
|
||||
rgb = read(lutsize)[:3]
|
||||
if rgb != chr(i)*3:
|
||||
if rgb != o8(i)*3:
|
||||
greyscale = 0
|
||||
palette.append(rgb)
|
||||
if greyscale:
|
||||
|
@ -145,7 +144,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
else:
|
||||
self.mode = "P"
|
||||
self.palette = ImagePalette.raw(
|
||||
"BGR", "".join(palette)
|
||||
"BGR", b"".join(palette)
|
||||
)
|
||||
|
||||
if not offset:
|
||||
|
@ -162,7 +161,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
|
||||
# HEAD
|
||||
s = self.fp.read(14)
|
||||
if s[:2] != "BM":
|
||||
if s[:2] != b"BM":
|
||||
raise SyntaxError("Not a BMP file")
|
||||
offset = i32(s[10:])
|
||||
|
||||
|
@ -181,12 +180,6 @@ class DibImageFile(BmpImageFile):
|
|||
# --------------------------------------------------------------------
|
||||
# Write BMP file
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
|
||||
SAVE = {
|
||||
"1": ("1", 1, 2),
|
||||
"L": ("L", 8, 256),
|
||||
|
@ -204,13 +197,13 @@ def _save(im, fp, filename, check=0):
|
|||
if check:
|
||||
return check
|
||||
|
||||
stride = ((im.size[0]*bits+7)/8+3)&(~3)
|
||||
stride = ((im.size[0]*bits+7)//8+3)&(~3)
|
||||
header = 40 # or 64 for OS/2 version 2
|
||||
offset = 14 + header + colors * 4
|
||||
image = stride * im.size[1]
|
||||
|
||||
# bitmap header
|
||||
fp.write("BM" + # file type (magic)
|
||||
fp.write(b"BM" + # file type (magic)
|
||||
o32(offset+image) + # file size
|
||||
o32(0) + # reserved
|
||||
o32(offset)) # image data offset
|
||||
|
@ -227,14 +220,14 @@ def _save(im, fp, filename, check=0):
|
|||
o32(colors) + # colors used
|
||||
o32(colors)) # colors important
|
||||
|
||||
fp.write("\000" * (header - 40)) # padding (for OS/2 format)
|
||||
fp.write(b"\0" * (header - 40)) # padding (for OS/2 format)
|
||||
|
||||
if im.mode == "1":
|
||||
for i in (0, 255):
|
||||
fp.write(chr(i) * 4)
|
||||
fp.write(o8(i) * 4)
|
||||
elif im.mode == "L":
|
||||
for i in range(256):
|
||||
fp.write(chr(i) * 4)
|
||||
fp.write(o8(i) * 4)
|
||||
elif im.mode == "P":
|
||||
fp.write(im.im.getpalette("RGB", "BGRX"))
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "BUFR" or prefix[:4] == "ZCZC"
|
||||
return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC"
|
||||
|
||||
class BufrStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -19,21 +19,19 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from . import Image, BmpImagePlugin
|
||||
from . import Image, BmpImagePlugin, _binary
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "\0\0\2\0"
|
||||
return prefix[:4] == b"\0\0\2\0"
|
||||
|
||||
##
|
||||
# Image plugin for Windows Cursor files.
|
||||
|
@ -53,17 +51,17 @@ class CurImageFile(BmpImagePlugin.BmpImageFile):
|
|||
raise SyntaxError("not an CUR file")
|
||||
|
||||
# pick the largest cursor in the file
|
||||
m = ""
|
||||
m = b""
|
||||
for i in range(i16(s[4:])):
|
||||
s = self.fp.read(16)
|
||||
if not m:
|
||||
m = s
|
||||
elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
|
||||
elif i8(s[0]) > i8(m[0]) and i8(s[1]) > i8(m[1]):
|
||||
m = s
|
||||
#print "width", ord(s[0])
|
||||
#print "height", ord(s[1])
|
||||
#print "colors", ord(s[2])
|
||||
#print "reserved", ord(s[3])
|
||||
#print "width", i8(s[0])
|
||||
#print "height", i8(s[1])
|
||||
#print "colors", i8(s[2])
|
||||
#print "reserved", i8(s[3])
|
||||
#print "hotspot x", i16(s[4:])
|
||||
#print "hotspot y", i16(s[6:])
|
||||
#print "bytes", i32(s[8:])
|
||||
|
@ -73,7 +71,7 @@ class CurImageFile(BmpImagePlugin.BmpImageFile):
|
|||
self._bitmap(i32(m[12:]) + offset)
|
||||
|
||||
# patch up the bitmap height
|
||||
self.size = self.size[0], self.size[1]/2
|
||||
self.size = self.size[0], self.size[1]//2
|
||||
d, e, o, a = self.tile[0]
|
||||
self.tile[0] = d, (0,0)+self.size, o, a
|
||||
|
||||
|
|
|
@ -23,14 +23,13 @@
|
|||
|
||||
__version__ = "0.2"
|
||||
|
||||
from . import Image
|
||||
from . import Image, _binary
|
||||
|
||||
from .PcxImagePlugin import PcxImageFile
|
||||
|
||||
MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i32 = _binary.i32le
|
||||
|
||||
def _accept(prefix):
|
||||
return i32(prefix) == MAGIC
|
||||
|
|
|
@ -21,16 +21,13 @@
|
|||
__version__ = "0.5"
|
||||
|
||||
import re
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
i32 = _binary.i32le
|
||||
o32 = _binary.o32le
|
||||
|
||||
split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$")
|
||||
field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$")
|
||||
|
@ -99,24 +96,24 @@ class PSFile:
|
|||
pos = pos - 1
|
||||
return pos
|
||||
def readline(self):
|
||||
s = ""
|
||||
s = b""
|
||||
if self.char:
|
||||
c = self.char
|
||||
self.char = None
|
||||
else:
|
||||
c = self.fp.read(1)
|
||||
while c not in "\r\n":
|
||||
while c not in b"\r\n":
|
||||
s = s + c
|
||||
c = self.fp.read(1)
|
||||
if c == "\r":
|
||||
if c == b"\r":
|
||||
self.char = self.fp.read(1)
|
||||
if self.char == "\n":
|
||||
if self.char == b"\n":
|
||||
self.char = None
|
||||
return s + "\n"
|
||||
return s + b"\n"
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5
|
||||
return prefix[:4] == b"%!PS" or i32(prefix) == 0xC6D3D0C5
|
||||
|
||||
##
|
||||
# Image plugin for Encapsulated Postscript. This plugin supports only
|
||||
|
@ -302,42 +299,42 @@ def _save(im, fp, filename, eps=1):
|
|||
#
|
||||
# determine postscript image mode
|
||||
if im.mode == "L":
|
||||
operator = (8, 1, "image")
|
||||
operator = (8, 1, b"image")
|
||||
elif im.mode == "RGB":
|
||||
operator = (8, 3, "false 3 colorimage")
|
||||
operator = (8, 3, b"false 3 colorimage")
|
||||
elif im.mode == "CMYK":
|
||||
operator = (8, 4, "false 4 colorimage")
|
||||
operator = (8, 4, b"false 4 colorimage")
|
||||
else:
|
||||
raise ValueError("image mode is not supported")
|
||||
|
||||
if eps:
|
||||
#
|
||||
# write EPS header
|
||||
fp.write("%!PS-Adobe-3.0 EPSF-3.0\n")
|
||||
fp.write("%%Creator: PIL 0.1 EpsEncode\n")
|
||||
fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n")
|
||||
fp.write(b"%%Creator: PIL 0.1 EpsEncode\n")
|
||||
#fp.write("%%CreationDate: %s"...)
|
||||
fp.write("%%%%BoundingBox: 0 0 %d %d\n" % im.size)
|
||||
fp.write("%%Pages: 1\n")
|
||||
fp.write("%%EndComments\n")
|
||||
fp.write("%%Page: 1 1\n")
|
||||
fp.write("%%ImageData: %d %d " % im.size)
|
||||
fp.write("%d %d 0 1 1 \"%s\"\n" % operator)
|
||||
fp.write(("%%%%BoundingBox: 0 0 %d %d\n" % im.size).encode('ascii'))
|
||||
fp.write(b"%%Pages: 1\n")
|
||||
fp.write(b"%%EndComments\n")
|
||||
fp.write(b"%%Page: 1 1\n")
|
||||
fp.write(("%%ImageData: %d %d " % im.size).encode('ascii'))
|
||||
fp.write(("%d %d 0 1 1 \"%s\"\n" % operator).encode('ascii'))
|
||||
|
||||
#
|
||||
# image header
|
||||
fp.write("gsave\n")
|
||||
fp.write("10 dict begin\n")
|
||||
fp.write("/buf %d string def\n" % (im.size[0] * operator[1]))
|
||||
fp.write("%d %d scale\n" % im.size)
|
||||
fp.write("%d %d 8\n" % im.size) # <= bits
|
||||
fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]))
|
||||
fp.write("{ currentfile buf readhexstring pop } bind\n")
|
||||
fp.write("%s\n" % operator[2])
|
||||
fp.write(b"gsave\n")
|
||||
fp.write(b"10 dict begin\n")
|
||||
fp.write(("/buf %d string def\n" % (im.size[0] * operator[1])).encode('ascii'))
|
||||
fp.write(("%d %d scale\n" % im.size).encode('ascii'))
|
||||
fp.write(("%d %d 8\n" % im.size).encode('ascii')) # <= bits
|
||||
fp.write(("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])).encode('ascii'))
|
||||
fp.write(b"{ currentfile buf readhexstring pop } bind\n")
|
||||
fp.write(operator[2] + b"\n")
|
||||
|
||||
ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)])
|
||||
|
||||
fp.write("\n%%%%EndBinary\n")
|
||||
fp.write("grestore end\n")
|
||||
fp.write(b"\n%%%%EndBinary\n")
|
||||
fp.write(b"grestore end\n")
|
||||
fp.flush()
|
||||
|
||||
#
|
||||
|
|
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:6] == "SIMPLE"
|
||||
return prefix[:6] == b"SIMPLE"
|
||||
|
||||
class FITSStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -18,14 +18,12 @@
|
|||
|
||||
__version__ = "0.2"
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
o8 = _binary.o8
|
||||
|
||||
#
|
||||
# decoder
|
||||
|
@ -82,7 +80,7 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
elif i16(s[4:6]) == 4:
|
||||
self._palette(palette, 0)
|
||||
|
||||
palette = [chr(r)+chr(g)+chr(b) for (r,g,b) in palette]
|
||||
palette = [o8(r)+o8(g)+o8(b) for (r,g,b) in palette]
|
||||
self.palette = ImagePalette.raw("RGB", "".join(palette))
|
||||
|
||||
# set things up to decode first frame
|
||||
|
@ -97,15 +95,15 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
i = 0
|
||||
for e in range(i16(self.fp.read(2))):
|
||||
s = self.fp.read(2)
|
||||
i = i + ord(s[0])
|
||||
n = ord(s[1])
|
||||
i = i + i8(s[0])
|
||||
n = i8(s[1])
|
||||
if n == 0:
|
||||
n = 256
|
||||
s = self.fp.read(n * 3)
|
||||
for n in range(0, len(s), 3):
|
||||
r = ord(s[n]) << shift
|
||||
g = ord(s[n+1]) << shift
|
||||
b = ord(s[n+2]) << shift
|
||||
r = i8(s[n]) << shift
|
||||
g = i8(s[n+1]) << shift
|
||||
b = i8(s[n+2]) << shift
|
||||
palette[i] = (r, g, b)
|
||||
i = i + 1
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#
|
||||
|
||||
import os
|
||||
from . import Image
|
||||
from . import Image, _binary
|
||||
|
||||
import marshal
|
||||
|
||||
|
@ -31,7 +31,7 @@ def puti16(fp, values):
|
|||
for v in values:
|
||||
if v < 0:
|
||||
v = v + 65536
|
||||
fp.write(chr(v>>8&255) + chr(v&255))
|
||||
fp.write(_binary.o16be(v))
|
||||
|
||||
##
|
||||
# Base class for raster font file handlers.
|
||||
|
@ -106,9 +106,9 @@ class FontFile:
|
|||
|
||||
# font metrics
|
||||
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
|
||||
fp.write("PILfont\n")
|
||||
fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!!
|
||||
fp.write("DATA\n")
|
||||
fp.write(b"PILfont\n")
|
||||
fp.write((";;;;;;%d;\n" % self.ysize).encode('ascii')) # HACK!!!
|
||||
fp.write(b"DATA\n")
|
||||
for id in range(256):
|
||||
m = self.metrics[id]
|
||||
if not m:
|
||||
|
@ -128,13 +128,13 @@ class FontFile:
|
|||
data = marshal.dumps((self.metrics, self.info))
|
||||
|
||||
if zlib:
|
||||
data = "z" + zlib.compress(data, 9)
|
||||
data = b"z" + zlib.compress(data, 9)
|
||||
else:
|
||||
data = "u" + data
|
||||
data = b"u" + data
|
||||
|
||||
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
|
||||
|
||||
fp.write("PILfont2\n" + self.name + "\n" + "DATA\n")
|
||||
fp.write(b"PILfont2\n" + self.name + "\n" + "DATA\n")
|
||||
|
||||
fp.write(data)
|
||||
|
||||
|
|
|
@ -170,8 +170,8 @@ class FpxImageFile(ImageFile.ImageFile):
|
|||
|
||||
elif compression == 2:
|
||||
|
||||
internal_color_conversion = ord(s[14])
|
||||
jpeg_tables = ord(s[15])
|
||||
internal_color_conversion = i8(s[14])
|
||||
jpeg_tables = i8(s[15])
|
||||
rawmode = self.rawmode
|
||||
|
||||
if internal_color_conversion:
|
||||
|
|
|
@ -13,10 +13,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i32 = _binary.i32be
|
||||
|
||||
def _accept(prefix):
|
||||
return i32(prefix) >= 20 and i32(prefix[4:8]) == 1
|
||||
|
@ -59,8 +58,8 @@ class GbrImageFile(ImageFile.ImageFile):
|
|||
|
||||
# create an image out of the brush data block
|
||||
self.im = Image.core.new(self.mode, self.size)
|
||||
self.im.fromstring(self.data)
|
||||
self.data = ""
|
||||
self.im.frombytes(self.data)
|
||||
self.data = b""
|
||||
|
||||
#
|
||||
# registry
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from . import ImageFile, ImagePalette
|
||||
from . import ImageFile, ImagePalette, _binary
|
||||
|
||||
try:
|
||||
import builtins
|
||||
|
@ -33,8 +33,7 @@ except ImportError:
|
|||
import __builtin__
|
||||
builtins = __builtin__
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
i16 = _binary.i16be
|
||||
|
||||
##
|
||||
# Image plugin for the GD uncompressed format. Note that this format
|
||||
|
|
|
@ -28,24 +28,23 @@
|
|||
__version__ = "0.9"
|
||||
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16le
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Identify/read GIF files
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:6] in ["GIF87a", "GIF89a"]
|
||||
return prefix[:6] in [b"GIF87a", b"GIF89a"]
|
||||
|
||||
##
|
||||
# Image plugin for GIF images. This plugin supports both GIF87 and
|
||||
|
@ -60,15 +59,15 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
def data(self):
|
||||
s = self.fp.read(1)
|
||||
if s and ord(s):
|
||||
return self.fp.read(ord(s))
|
||||
if s and i8(s):
|
||||
return self.fp.read(i8(s))
|
||||
return None
|
||||
|
||||
def _open(self):
|
||||
|
||||
# Screen
|
||||
s = self.fp.read(13)
|
||||
if s[:6] not in ["GIF87a", "GIF89a"]:
|
||||
if s[:6] not in [b"GIF87a", b"GIF89a"]:
|
||||
raise SyntaxError("not a GIF file")
|
||||
|
||||
self.info["version"] = s[:6]
|
||||
|
@ -77,17 +76,17 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.tile = []
|
||||
|
||||
flags = ord(s[10])
|
||||
flags = i8(s[10])
|
||||
|
||||
bits = (flags & 7) + 1
|
||||
|
||||
if flags & 128:
|
||||
# get global palette
|
||||
self.info["background"] = ord(s[11])
|
||||
self.info["background"] = i8(s[11])
|
||||
# check if palette contains colour indices
|
||||
p = self.fp.read(3<<bits)
|
||||
for i in range(0, len(p), 3):
|
||||
if not (chr(i/3) == p[i] == p[i+1] == p[i+2]):
|
||||
if not (i//3 == i8(p[i]) == i8(p[i+1]) == i8(p[i+2])):
|
||||
p = ImagePalette.raw("RGB", p)
|
||||
self.global_palette = self.palette = p
|
||||
break
|
||||
|
@ -128,22 +127,22 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
while True:
|
||||
|
||||
s = self.fp.read(1)
|
||||
if not s or s == ";":
|
||||
if not s or s == b";":
|
||||
break
|
||||
|
||||
elif s == "!":
|
||||
elif s == b"!":
|
||||
#
|
||||
# extensions
|
||||
#
|
||||
s = self.fp.read(1)
|
||||
block = self.data()
|
||||
if ord(s) == 249:
|
||||
if i8(s) == 249:
|
||||
#
|
||||
# graphic control extension
|
||||
#
|
||||
flags = ord(block[0])
|
||||
flags = i8(block[0])
|
||||
if flags & 1:
|
||||
self.info["transparency"] = ord(block[3])
|
||||
self.info["transparency"] = i8(block[3])
|
||||
self.info["duration"] = i16(block[1:3]) * 10
|
||||
try:
|
||||
# disposal methods
|
||||
|
@ -156,19 +155,19 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
self.dispose = self.im.copy()
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
elif ord(s) == 255:
|
||||
elif i8(s) == 255:
|
||||
#
|
||||
# application extension
|
||||
#
|
||||
self.info["extension"] = block, self.fp.tell()
|
||||
if block[:11] == "NETSCAPE2.0":
|
||||
if block[:11] == b"NETSCAPE2.0":
|
||||
block = self.data()
|
||||
if len(block) >= 3 and ord(block[0]) == 1:
|
||||
if len(block) >= 3 and i8(block[0]) == 1:
|
||||
self.info["loop"] = i16(block[1:3])
|
||||
while self.data():
|
||||
pass
|
||||
|
||||
elif s == ",":
|
||||
elif s == b",":
|
||||
#
|
||||
# local image
|
||||
#
|
||||
|
@ -177,7 +176,7 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
# extent
|
||||
x0, y0 = i16(s[0:]), i16(s[2:])
|
||||
x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:])
|
||||
flags = ord(s[8])
|
||||
flags = i8(s[8])
|
||||
|
||||
interlace = (flags & 64) != 0
|
||||
|
||||
|
@ -187,7 +186,7 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
ImagePalette.raw("RGB", self.fp.read(3<<bits))
|
||||
|
||||
# image data
|
||||
bits = ord(self.fp.read(1))
|
||||
bits = i8(self.fp.read(1))
|
||||
self.__offset = self.fp.tell()
|
||||
self.tile = [("gif",
|
||||
(x0, y0, x1, y1),
|
||||
|
@ -197,7 +196,7 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
else:
|
||||
pass
|
||||
# raise IOError, "illegal GIF tag `%x`" % ord(s)
|
||||
# raise IOError, "illegal GIF tag `%x`" % i8(s)
|
||||
|
||||
if not self.tile:
|
||||
# self.__fp = None
|
||||
|
@ -272,29 +271,29 @@ def _save(im, fp, filename):
|
|||
pass
|
||||
else:
|
||||
# transparency extension block
|
||||
fp.write("!" +
|
||||
chr(249) + # extension intro
|
||||
chr(4) + # length
|
||||
chr(1) + # transparency info present
|
||||
fp.write(b"!" +
|
||||
o8(249) + # extension intro
|
||||
o8(4) + # length
|
||||
o8(1) + # transparency info present
|
||||
o16(0) + # duration
|
||||
chr(int(transparency)) # transparency index
|
||||
+ chr(0))
|
||||
o8(int(transparency)) # transparency index
|
||||
+ o8(0))
|
||||
|
||||
# local image header
|
||||
fp.write("," +
|
||||
fp.write(b"," +
|
||||
o16(0) + o16(0) + # bounding box
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(flags) + # flags
|
||||
chr(8)) # bits
|
||||
o8(flags) + # flags
|
||||
o8(8)) # bits
|
||||
|
||||
imOut.encoderconfig = (8, interlace)
|
||||
|
||||
ImageFile._save(imOut, fp, [("gif", (0,0)+im.size, 0, rawmode)])
|
||||
|
||||
fp.write("\0") # end of image data
|
||||
fp.write(b"\0") # end of image data
|
||||
|
||||
fp.write(";") # end of file
|
||||
fp.write(b";") # end of file
|
||||
|
||||
try:
|
||||
fp.flush()
|
||||
|
@ -326,12 +325,12 @@ def getheader(im, info=None):
|
|||
optimize = info and info.get("optimize", 0)
|
||||
|
||||
s = [
|
||||
"GIF87a" + # magic
|
||||
b"GIF87a" + # magic
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(7 + 128) + # flags: bits + palette
|
||||
chr(0) + # background
|
||||
chr(0) # reserved/aspect
|
||||
o8(7 + 128) + # flags: bits + palette
|
||||
o8(0) + # background
|
||||
o8(0) # reserved/aspect
|
||||
]
|
||||
|
||||
if optimize:
|
||||
|
@ -352,7 +351,7 @@ def getheader(im, info=None):
|
|||
else:
|
||||
# greyscale
|
||||
for i in range(maxcolor):
|
||||
s.append(chr(i) * 3)
|
||||
s.append(o8(i) * 3)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -374,17 +373,17 @@ def getdata(im, offset = (0, 0), **params):
|
|||
im.encoderinfo = params
|
||||
|
||||
# local image header
|
||||
fp.write("," +
|
||||
fp.write(b"," +
|
||||
o16(offset[0]) + # offset
|
||||
o16(offset[1]) +
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(0) + # flags
|
||||
chr(8)) # bits
|
||||
o8(0) + # flags
|
||||
o8(8)) # bits
|
||||
|
||||
ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])])
|
||||
|
||||
fp.write("\0") # end of image data
|
||||
fp.write(b"\0") # end of image data
|
||||
|
||||
finally:
|
||||
del im.encoderinfo
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#
|
||||
|
||||
from math import pi, log, sin, sqrt
|
||||
from ._binary import o8
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Stuff to translate curve segments to palette values (derived from
|
||||
|
@ -78,15 +79,15 @@ class GradientFile:
|
|||
scale = segment((xm - x0) / w, (x - x0) / w)
|
||||
|
||||
# expand to RGBA
|
||||
r = chr(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
|
||||
g = chr(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
|
||||
b = chr(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
|
||||
a = chr(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
|
||||
r = o8(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
|
||||
g = o8(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
|
||||
b = o8(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
|
||||
a = o8(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
|
||||
|
||||
# add to palette
|
||||
palette.append(r + g + b + a)
|
||||
|
||||
return "".join(palette), "RGBA"
|
||||
return b"".join(palette), "RGBA"
|
||||
|
||||
##
|
||||
# File handler for GIMP's gradient format.
|
||||
|
@ -95,7 +96,7 @@ class GimpGradientFile(GradientFile):
|
|||
|
||||
def __init__(self, fp):
|
||||
|
||||
if fp.readline()[:13] != "GIMP Gradient":
|
||||
if fp.readline()[:13] != b"GIMP Gradient":
|
||||
raise SyntaxError("not a GIMP gradient file")
|
||||
|
||||
count = int(fp.readline())
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#
|
||||
|
||||
import re
|
||||
from ._binary import o8
|
||||
|
||||
##
|
||||
# File handler for GIMP's palette format.
|
||||
|
@ -25,9 +26,9 @@ class GimpPaletteFile:
|
|||
|
||||
def __init__(self, fp):
|
||||
|
||||
self.palette = [chr(i)*3 for i in range(256)]
|
||||
self.palette = [o8(i)*3 for i in range(256)]
|
||||
|
||||
if fp.readline()[:12] != "GIMP Palette":
|
||||
if fp.readline()[:12] != b"GIMP Palette":
|
||||
raise SyntaxError("not a GIMP palette file")
|
||||
|
||||
i = 0
|
||||
|
@ -39,7 +40,7 @@ class GimpPaletteFile:
|
|||
if not s:
|
||||
break
|
||||
# skip fields and comment lines
|
||||
if re.match("\w+:|#", s):
|
||||
if re.match(b"\w+:|#", s):
|
||||
continue
|
||||
if len(s) > 100:
|
||||
raise SyntaxError("bad palette file")
|
||||
|
@ -49,11 +50,11 @@ class GimpPaletteFile:
|
|||
raise ValueError("bad palette entry")
|
||||
|
||||
if 0 <= i <= 255:
|
||||
self.palette[i] = chr(v[0]) + chr(v[1]) + chr(v[2])
|
||||
self.palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2])
|
||||
|
||||
i = i + 1
|
||||
|
||||
self.palette = "".join(self.palette)
|
||||
self.palette = b"".join(self.palette)
|
||||
|
||||
|
||||
def getpalette(self):
|
||||
|
|
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0:4] == "GRIB" and prefix[7] == chr(1)
|
||||
return prefix[0:4] == b"GRIB" and prefix[7] == b'\x01'
|
||||
|
||||
class GribStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:8] == "\x89HDF\r\n\x1a\n"
|
||||
return prefix[:8] == b"\x89HDF\r\n\x1a\n"
|
||||
|
||||
class HDF5StubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
import struct
|
||||
|
||||
i8 = _binary.i8
|
||||
|
||||
HEADERSIZE = 8
|
||||
|
||||
def nextheader(fobj):
|
||||
|
@ -27,7 +29,7 @@ def read_32t(fobj, start_length, size):
|
|||
(start, length) = start_length
|
||||
fobj.seek(start)
|
||||
sig = fobj.read(4)
|
||||
if sig != '\x00\x00\x00\x00':
|
||||
if sig != b'\x00\x00\x00\x00':
|
||||
raise SyntaxError('Unknown signature, expecting 0x00000000')
|
||||
return read_32(fobj, (start + 4, length - 4), size)
|
||||
|
||||
|
@ -53,7 +55,7 @@ def read_32(fobj, start_length, size):
|
|||
byte = fobj.read(1)
|
||||
if not byte:
|
||||
break
|
||||
byte = ord(byte)
|
||||
byte = i8(byte)
|
||||
if byte & 0x80:
|
||||
blocksize = byte - 125
|
||||
byte = fobj.read(1)
|
||||
|
@ -70,7 +72,7 @@ def read_32(fobj, start_length, size):
|
|||
"Error reading channel [%r left]" % bytesleft
|
||||
)
|
||||
band = Image.frombuffer(
|
||||
"L", size, "".join(data), "raw", "L", 0, 1
|
||||
"L", size, b"".join(data), "raw", "L", 0, 1
|
||||
)
|
||||
im.im.putband(band.im, band_ix)
|
||||
return {"RGB": im}
|
||||
|
@ -88,20 +90,20 @@ class IcnsFile:
|
|||
|
||||
SIZES = {
|
||||
(128, 128): [
|
||||
('it32', read_32t),
|
||||
('t8mk', read_mk),
|
||||
(b'it32', read_32t),
|
||||
(b't8mk', read_mk),
|
||||
],
|
||||
(48, 48): [
|
||||
('ih32', read_32),
|
||||
('h8mk', read_mk),
|
||||
(b'ih32', read_32),
|
||||
(b'h8mk', read_mk),
|
||||
],
|
||||
(32, 32): [
|
||||
('il32', read_32),
|
||||
('l8mk', read_mk),
|
||||
(b'il32', read_32),
|
||||
(b'l8mk', read_mk),
|
||||
],
|
||||
(16, 16): [
|
||||
('is32', read_32),
|
||||
('s8mk', read_mk),
|
||||
(b'is32', read_32),
|
||||
(b's8mk', read_mk),
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -204,7 +206,7 @@ class IcnsImageFile(ImageFile.ImageFile):
|
|||
self.load_end()
|
||||
|
||||
|
||||
Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == 'icns')
|
||||
Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == b'icns')
|
||||
Image.register_extension("ICNS", '.icns')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -19,21 +19,19 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from . import Image, BmpImagePlugin
|
||||
from . import Image, BmpImagePlugin, _binary
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "\0\0\1\0"
|
||||
return prefix[:4] == b"\0\0\1\0"
|
||||
|
||||
##
|
||||
# Image plugin for Windows Icon files.
|
||||
|
@ -56,12 +54,12 @@ class IcoImageFile(BmpImagePlugin.BmpImageFile):
|
|||
s = self.fp.read(16)
|
||||
if not m:
|
||||
m = s
|
||||
elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
|
||||
elif i8(s[0]) > i8(m[0]) and i8(s[1]) > i8(m[1]):
|
||||
m = s
|
||||
#print "width", ord(s[0])
|
||||
#print "height", ord(s[1])
|
||||
#print "colors", ord(s[2])
|
||||
#print "reserved", ord(s[3])
|
||||
#print "width", i8(s[0])
|
||||
#print "height", i8(s[1])
|
||||
#print "colors", i8(s[2])
|
||||
#print "reserved", i8(s[3])
|
||||
#print "planes", i16(s[4:])
|
||||
#print "bitcount", i16(s[6:])
|
||||
#print "bytes", i32(s[8:])
|
||||
|
@ -71,7 +69,7 @@ class IcoImageFile(BmpImagePlugin.BmpImageFile):
|
|||
self._bitmap(i32(m[12:]))
|
||||
|
||||
# patch up the bitmap height
|
||||
self.size = self.size[0], self.size[1]/2
|
||||
self.size = self.size[0], self.size[1]//2
|
||||
d, e, o, a = self.tile[0]
|
||||
self.tile[0] = d, (0,0)+self.size, o, a
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ __version__ = "0.7"
|
|||
|
||||
import re
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from ._binary import i8, o8
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -91,7 +92,7 @@ for i in range(2, 33):
|
|||
# --------------------------------------------------------------------
|
||||
# Read IM directory
|
||||
|
||||
split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
|
||||
split = re.compile(br"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
|
||||
|
||||
def number(s):
|
||||
try:
|
||||
|
@ -112,7 +113,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
# Quick rejection: if there's not an LF among the first
|
||||
# 100 bytes, this is (probably) not a text header.
|
||||
|
||||
if not "\n" in self.fp.read(100):
|
||||
if not b"\n" in self.fp.read(100):
|
||||
raise SyntaxError("not an IM file")
|
||||
self.fp.seek(0)
|
||||
|
||||
|
@ -130,10 +131,10 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
s = self.fp.read(1)
|
||||
|
||||
# Some versions of IFUNC uses \n\r instead of \r\n...
|
||||
if s == "\r":
|
||||
if s == b"\r":
|
||||
continue
|
||||
|
||||
if not s or s[0] == chr(0) or s[0] == chr(26):
|
||||
if not s or s == b'\0' or s == b'\x1A':
|
||||
break
|
||||
|
||||
# FIXME: this may read whole file if not a text file
|
||||
|
@ -142,9 +143,9 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
if len(s) > 100:
|
||||
raise SyntaxError("not an IM file")
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
if s[-2:] == b'\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] == '\n':
|
||||
elif s[-1:] == b'\n':
|
||||
s = s[:-1]
|
||||
|
||||
try:
|
||||
|
@ -156,6 +157,11 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
|
||||
k, v = m.group(1,2)
|
||||
|
||||
# Don't know if this is the correct encoding, but a decent guess
|
||||
# (I guess)
|
||||
k = k.decode('latin-1', 'replace')
|
||||
v = v.decode('latin-1', 'replace')
|
||||
|
||||
# Convert value as appropriate
|
||||
if k in [FRAMES, SCALE, SIZE]:
|
||||
v = v.replace("*", ",")
|
||||
|
@ -180,7 +186,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
|
||||
else:
|
||||
|
||||
raise SyntaxError("Syntax error in IM header: " + s)
|
||||
raise SyntaxError("Syntax error in IM header: " + s.decode('ascii', 'replace'))
|
||||
|
||||
if not n:
|
||||
raise SyntaxError("Not an IM file")
|
||||
|
@ -190,7 +196,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
self.mode = self.info[MODE]
|
||||
|
||||
# Skip forward to start of image data
|
||||
while s and s[0] != chr(26):
|
||||
while s and s[0:1] != b'\x1A':
|
||||
s = self.fp.read(1)
|
||||
if not s:
|
||||
raise SyntaxError("File truncated")
|
||||
|
@ -202,14 +208,14 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
linear = 1 # linear greyscale palette
|
||||
for i in range(256):
|
||||
if palette[i] == palette[i+256] == palette[i+512]:
|
||||
if palette[i] != chr(i):
|
||||
if i8(palette[i]) != i:
|
||||
linear = 0
|
||||
else:
|
||||
greyscale = 0
|
||||
if self.mode == "L" or self.mode == "LA":
|
||||
if greyscale:
|
||||
if not linear:
|
||||
self.lut = [ord(c) for c in palette[:256]]
|
||||
self.lut = [i8(c) for c in palette[:256]]
|
||||
else:
|
||||
if self.mode == "L":
|
||||
self.mode = self.rawmode = "P"
|
||||
|
@ -218,7 +224,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
self.palette = ImagePalette.raw("RGB;L", palette)
|
||||
elif self.mode == "RGB":
|
||||
if not greyscale or not linear:
|
||||
self.lut = [ord(c) for c in palette]
|
||||
self.lut = [i8(c) for c in palette]
|
||||
|
||||
self.frame = 0
|
||||
|
||||
|
@ -265,7 +271,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
else:
|
||||
bits = 8 * len(self.mode)
|
||||
|
||||
size = ((self.size[0] * bits + 7) / 8) * self.size[1]
|
||||
size = ((self.size[0] * bits + 7) // 8) * self.size[1]
|
||||
offs = self.__offset + frame * size
|
||||
|
||||
self.fp = self.__fp
|
||||
|
@ -314,14 +320,14 @@ def _save(im, fp, filename, check=0):
|
|||
if check:
|
||||
return check
|
||||
|
||||
fp.write("Image type: %s image\r\n" % type)
|
||||
fp.write(("Image type: %s image\r\n" % type).encode('ascii'))
|
||||
if filename:
|
||||
fp.write("Name: %s\r\n" % filename)
|
||||
fp.write("Image size (x*y): %d*%d\r\n" % im.size)
|
||||
fp.write("File size (no of images): %d\r\n" % frames)
|
||||
fp.write(("Name: %s\r\n" % filename).encode('ascii'))
|
||||
fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode('ascii'))
|
||||
fp.write(("File size (no of images): %d\r\n" % frames).encode('ascii'))
|
||||
if im.mode == "P":
|
||||
fp.write("Lut: 1\r\n")
|
||||
fp.write("\000" * (511-fp.tell()) + "\032")
|
||||
fp.write(b"Lut: 1\r\n")
|
||||
fp.write(b"\000" * (511-fp.tell()) + b"\032")
|
||||
if im.mode == "P":
|
||||
fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
|
||||
|
|
112
PIL/Image.py
112
PIL/Image.py
|
@ -73,6 +73,7 @@ except ImportError:
|
|||
builtins = __builtin__
|
||||
|
||||
from . import ImageMode
|
||||
from ._binary import i8, o8
|
||||
|
||||
import os, sys
|
||||
|
||||
|
@ -80,12 +81,12 @@ import os, sys
|
|||
import collections
|
||||
import numbers
|
||||
|
||||
if sys.version_info >= (3,0):
|
||||
def isStringType(t):
|
||||
return isinstance(t, str)
|
||||
else:
|
||||
if bytes is str:
|
||||
def isStringType(t):
|
||||
return isinstance(t, basestring)
|
||||
else:
|
||||
def isStringType(t):
|
||||
return isinstance(t, str)
|
||||
|
||||
##
|
||||
# (Internal) Checks if an object is an image object.
|
||||
|
@ -181,16 +182,7 @@ _MODEINFO = {
|
|||
|
||||
}
|
||||
|
||||
try:
|
||||
byteorder = sys.byteorder
|
||||
except AttributeError:
|
||||
import struct
|
||||
if struct.unpack("h", "\0\1")[0] == 1:
|
||||
byteorder = "big"
|
||||
else:
|
||||
byteorder = "little"
|
||||
|
||||
if byteorder == 'little':
|
||||
if sys.byteorder == 'little':
|
||||
_ENDIAN = '<'
|
||||
else:
|
||||
_ENDIAN = '>'
|
||||
|
@ -358,7 +350,7 @@ def init():
|
|||
return 1
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Codec factories (used by tostring/fromstring and ImageFile.load)
|
||||
# Codec factories (used by tobytes/frombytes and ImageFile.load)
|
||||
|
||||
def _getdecoder(mode, decoder_name, args, extra=()):
|
||||
|
||||
|
@ -436,7 +428,7 @@ def _getscaleoffset(expr):
|
|||
#
|
||||
# @see #open
|
||||
# @see #new
|
||||
# @see #fromstring
|
||||
# @see #frombytes
|
||||
|
||||
class Image:
|
||||
|
||||
|
@ -505,7 +497,7 @@ class Image:
|
|||
shape, typestr = _conv_type_shape(self)
|
||||
new['shape'] = shape
|
||||
new['typestr'] = typestr
|
||||
new['data'] = self.tostring()
|
||||
new['data'] = self.tobytes()
|
||||
return new
|
||||
raise AttributeError(name)
|
||||
|
||||
|
@ -515,10 +507,10 @@ class Image:
|
|||
# @param encoder_name What encoder to use. The default is to
|
||||
# use the standard "raw" encoder.
|
||||
# @param *args Extra arguments to the encoder.
|
||||
# @return An 8-bit string.
|
||||
# @return A bytes object.
|
||||
|
||||
def tostring(self, encoder_name="raw", *args):
|
||||
"Return image as a binary string"
|
||||
def tobytes(self, encoder_name="raw", *args):
|
||||
"Return image as a bytes object"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
|
@ -542,9 +534,13 @@ class Image:
|
|||
if s:
|
||||
break
|
||||
if s < 0:
|
||||
raise RuntimeError("encoder error %d in tostring" % s)
|
||||
raise RuntimeError("encoder error %d in tobytes" % s)
|
||||
|
||||
return "".join(data)
|
||||
return b"".join(data)
|
||||
|
||||
if bytes is str:
|
||||
# Declare tostring as alias to tobytes
|
||||
tostring = tobytes
|
||||
|
||||
##
|
||||
# Returns the image converted to an X11 bitmap. This method
|
||||
|
@ -560,20 +556,20 @@ class Image:
|
|||
self.load()
|
||||
if self.mode != "1":
|
||||
raise ValueError("not a bitmap")
|
||||
data = self.tostring("xbm")
|
||||
return "".join(["#define %s_width %d\n" % (name, self.size[0]),
|
||||
"#define %s_height %d\n"% (name, self.size[1]),
|
||||
"static char %s_bits[] = {\n" % name, data, "};"])
|
||||
data = self.tobytes("xbm")
|
||||
return b"".join([("#define %s_width %d\n" % (name, self.size[0])).encode('ascii'),
|
||||
("#define %s_height %d\n"% (name, self.size[1])).encode('ascii'),
|
||||
("static char %s_bits[] = {\n" % name).encode('ascii'), data, b"};"])
|
||||
|
||||
##
|
||||
# Loads this image with pixel data from a string.
|
||||
# Loads this image with pixel data from a bytes object.
|
||||
# <p>
|
||||
# This method is similar to the {@link #fromstring} function, but
|
||||
# This method is similar to the {@link #frombytes} function, but
|
||||
# loads data into this image instead of creating a new image
|
||||
# object.
|
||||
|
||||
def fromstring(self, data, decoder_name="raw", *args):
|
||||
"Load data to image from binary string"
|
||||
def frombytes(self, data, decoder_name="raw", *args):
|
||||
"Load data to image from a bytes object"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
|
@ -593,6 +589,10 @@ class Image:
|
|||
if s[1] != 0:
|
||||
raise ValueError("cannot decode image data")
|
||||
|
||||
if bytes is str:
|
||||
# Declare fromstring as alias to frombytes
|
||||
fromstring = frombytes
|
||||
|
||||
##
|
||||
# Allocates storage for the image and loads the pixel data. In
|
||||
# normal cases, you don't need to call this method, since the
|
||||
|
@ -929,7 +929,10 @@ class Image:
|
|||
|
||||
self.load()
|
||||
try:
|
||||
return [ord(c) for c in self.im.getpalette()]
|
||||
if bytes is str:
|
||||
return [i8(c) for c in self.im.getpalette()]
|
||||
else:
|
||||
return list(self.im.getpalette())
|
||||
except ValueError:
|
||||
return None # no palette
|
||||
|
||||
|
@ -958,7 +961,7 @@ class Image:
|
|||
|
||||
self.load()
|
||||
x, y = self.im.getprojection()
|
||||
return [ord(c) for c in x], [ord(c) for c in y]
|
||||
return [i8(c) for c in x], [i8(c) for c in y]
|
||||
|
||||
##
|
||||
# Returns a histogram for the image. The histogram is returned as
|
||||
|
@ -1233,8 +1236,11 @@ class Image:
|
|||
if isinstance(data, ImagePalette.ImagePalette):
|
||||
palette = ImagePalette.raw(data.rawmode, data.palette)
|
||||
else:
|
||||
if not isStringType(data):
|
||||
data = "".join(map(chr, data))
|
||||
if not isinstance(data, bytes):
|
||||
if bytes is str:
|
||||
data = "".join(chr(x) for x in data)
|
||||
else:
|
||||
data = bytes(data)
|
||||
palette = ImagePalette.raw(rawmode, data)
|
||||
self.mode = "P"
|
||||
self.palette = palette
|
||||
|
@ -1762,7 +1768,7 @@ def new(mode, size, color=0):
|
|||
return Image()._new(core.fill(mode, size, color))
|
||||
|
||||
##
|
||||
# Creates an image memory from pixel data in a string.
|
||||
# Creates a copy of an image memory from pixel data in a buffer.
|
||||
# <p>
|
||||
# In its simplest form, this function takes three arguments
|
||||
# (mode, size, and unpacked pixel data).
|
||||
|
@ -1773,17 +1779,17 @@ def new(mode, size, color=0):
|
|||
# <p>
|
||||
# Note that this function decodes pixel data only, not entire images.
|
||||
# If you have an entire image in a string, wrap it in a
|
||||
# <b>StringIO</b> object, and use {@link #open} to load it.
|
||||
# <b>BytesIO</b> object, and use {@link #open} to load it.
|
||||
#
|
||||
# @param mode The image mode.
|
||||
# @param size The image size.
|
||||
# @param data An 8-bit string containing raw data for the given mode.
|
||||
# @param data A byte buffer containing raw data for the given mode.
|
||||
# @param decoder_name What decoder to use.
|
||||
# @param *args Additional parameters for the given decoder.
|
||||
# @return An Image object.
|
||||
|
||||
def fromstring(mode, size, data, decoder_name="raw", *args):
|
||||
"Load image from string"
|
||||
def frombytes(mode, size, data, decoder_name="raw", *args):
|
||||
"Load image from byte buffer"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
|
@ -1793,14 +1799,18 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
args = mode
|
||||
|
||||
im = new(mode, size)
|
||||
im.fromstring(data, decoder_name, args)
|
||||
im.frombytes(data, decoder_name, args)
|
||||
return im
|
||||
|
||||
if bytes is str:
|
||||
# Declare fromstring as an alias for frombytes
|
||||
fromstring = frombytes
|
||||
|
||||
##
|
||||
# (New in 1.1.4) Creates an image memory from pixel data in a string
|
||||
# or byte buffer.
|
||||
# (New in 1.1.4) Creates an image memory referencing pixel data in a
|
||||
# byte buffer.
|
||||
# <p>
|
||||
# This function is similar to {@link #fromstring}, but uses data in
|
||||
# This function is similar to {@link #frombytes}, but uses data in
|
||||
# the byte buffer, where possible. This means that changes to the
|
||||
# original buffer object are reflected in this image). Not all modes
|
||||
# can share memory; supported modes include "L", "RGBX", "RGBA", and
|
||||
|
@ -1808,7 +1818,7 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
# <p>
|
||||
# Note that this function decodes pixel data only, not entire images.
|
||||
# If you have an entire image file in a string, wrap it in a
|
||||
# <b>StringIO</b> object, and use {@link #open} to load it.
|
||||
# <b>BytesIO</b> object, and use {@link #open} to load it.
|
||||
# <p>
|
||||
# In the current version, the default parameters used for the "raw"
|
||||
# decoder differs from that used for {@link fromstring}. This is a
|
||||
|
@ -1819,7 +1829,7 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
#
|
||||
# @param mode The image mode.
|
||||
# @param size The image size.
|
||||
# @param data An 8-bit string or other buffer object containing raw
|
||||
# @param data A bytes or other buffer object containing raw
|
||||
# data for the given mode.
|
||||
# @param decoder_name What decoder to use.
|
||||
# @param *args Additional parameters for the given decoder. For the
|
||||
|
@ -1830,7 +1840,7 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
# @since 1.1.4
|
||||
|
||||
def frombuffer(mode, size, data, decoder_name="raw", *args):
|
||||
"Load image from string or buffer"
|
||||
"Load image from bytes or buffer"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
|
@ -1854,14 +1864,14 @@ def frombuffer(mode, size, data, decoder_name="raw", *args):
|
|||
im.readonly = 1
|
||||
return im
|
||||
|
||||
return fromstring(mode, size, data, decoder_name, args)
|
||||
return frombytes(mode, size, data, decoder_name, args)
|
||||
|
||||
|
||||
##
|
||||
# (New in 1.1.6) Creates an image memory from an object exporting
|
||||
# the array interface (using the buffer protocol).
|
||||
#
|
||||
# If obj is not contiguous, then the tostring method is called
|
||||
# If obj is not contiguous, then the tobytes method is called
|
||||
# and {@link frombuffer} is used.
|
||||
#
|
||||
# @param obj Object with array interface
|
||||
|
@ -1896,7 +1906,7 @@ def fromarray(obj, mode=None):
|
|||
|
||||
size = shape[1], shape[0]
|
||||
if strides is not None:
|
||||
obj = obj.tostring()
|
||||
obj = obj.tobytes()
|
||||
|
||||
return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
|
||||
|
||||
|
@ -1962,6 +1972,8 @@ def open(fp, mode="r"):
|
|||
fp.seek(0)
|
||||
return factory(fp, filename)
|
||||
except (SyntaxError, IndexError, TypeError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
if init():
|
||||
|
@ -1973,6 +1985,8 @@ def open(fp, mode="r"):
|
|||
fp.seek(0)
|
||||
return factory(fp, filename)
|
||||
except (SyntaxError, IndexError, TypeError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
raise IOError("cannot identify image file")
|
||||
|
|
|
@ -142,7 +142,7 @@ class ImageCmsProfile:
|
|||
if Image.isStringType(profile):
|
||||
self._set(core.profile_open(profile), profile)
|
||||
elif hasattr(profile, "read"):
|
||||
self._set(core.profile_fromstring(profile.read()))
|
||||
self._set(core.profile_frombytes(profile.read()))
|
||||
else:
|
||||
self._set(profile) # assume it's already a profile
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ def getcolor(color, mode):
|
|||
return r, g, b, 255
|
||||
if Image.getmodebase(mode) == "L":
|
||||
r, g, b = color
|
||||
return (r*299 + g*587 + b*114)/1000
|
||||
return (r*299 + g*587 + b*114)//1000
|
||||
return color
|
||||
|
||||
colormap = {
|
||||
|
|
|
@ -184,7 +184,7 @@ class ImageFile(Image.Image):
|
|||
# FIXME: This is a hack to handle TIFF's JpegTables tag.
|
||||
prefix = self.tile_prefix
|
||||
except AttributeError:
|
||||
prefix = ""
|
||||
prefix = b""
|
||||
|
||||
for d, e, o, a in self.tile:
|
||||
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
|
||||
|
@ -314,13 +314,13 @@ class _ParserFile:
|
|||
|
||||
def readline(self):
|
||||
# FIXME: this is slow!
|
||||
s = ""
|
||||
s = b""
|
||||
while True:
|
||||
c = self.read(1)
|
||||
if not c:
|
||||
break
|
||||
s = s + c
|
||||
if c == "\n":
|
||||
if c == b"\n":
|
||||
break
|
||||
return s
|
||||
|
||||
|
@ -404,6 +404,7 @@ class Parser:
|
|||
finally:
|
||||
fp.close() # explicitly close the virtual file
|
||||
except IOError:
|
||||
# traceback.print_exc()
|
||||
pass # not enough data
|
||||
else:
|
||||
flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
|
||||
|
@ -438,7 +439,7 @@ class Parser:
|
|||
# finish decoding
|
||||
if self.decoder:
|
||||
# get rid of what's left in the buffers
|
||||
self.feed("")
|
||||
self.feed(b"")
|
||||
self.data = self.decoder = None
|
||||
if not self.finished:
|
||||
raise IOError("image was incomplete")
|
||||
|
@ -516,7 +517,7 @@ def _save(im, fp, tile):
|
|||
|
||||
def _safe_read(fp, size):
|
||||
if size <= 0:
|
||||
return ""
|
||||
return b""
|
||||
if size <= SAFEBLOCK:
|
||||
return fp.read(size)
|
||||
data = []
|
||||
|
@ -526,4 +527,4 @@ def _safe_read(fp, size):
|
|||
break
|
||||
data.append(block)
|
||||
size = size - len(block)
|
||||
return "".join(data)
|
||||
return b"".join(data)
|
||||
|
|
|
@ -82,7 +82,7 @@ class RankFilter(Filter):
|
|||
def filter(self, image):
|
||||
if image.mode == "P":
|
||||
raise ValueError("cannot filter palette images")
|
||||
image = image.expand(self.size/2, self.size/2)
|
||||
image = image.expand(self.size//2, self.size//2)
|
||||
return image.rankfilter(self.size, self.rank)
|
||||
|
||||
##
|
||||
|
@ -99,7 +99,7 @@ class MedianFilter(RankFilter):
|
|||
|
||||
def __init__(self, size=3):
|
||||
self.size = size
|
||||
self.rank = size*size/2
|
||||
self.rank = size*size//2
|
||||
|
||||
##
|
||||
# Min filter. Picks the lowest pixel value in a window with the given
|
||||
|
|
|
@ -99,13 +99,13 @@ class ImageFont:
|
|||
def _load_pilfont_data(self, file, image):
|
||||
|
||||
# read PILfont header
|
||||
if file.readline() != "PILfont\n":
|
||||
if file.readline() != b"PILfont\n":
|
||||
raise SyntaxError("Not a PILfont file")
|
||||
d = file.readline().split(";")
|
||||
d = file.readline().split(b";")
|
||||
self.info = [] # FIXME: should be a dictionary
|
||||
while True:
|
||||
s = file.readline()
|
||||
if not s or s == "DATA\n":
|
||||
if not s or s == b"DATA\n":
|
||||
break
|
||||
self.info.append(s)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ except AttributeError:
|
|||
|
||||
def grab(bbox=None):
|
||||
size, data = grabber()
|
||||
im = Image.fromstring(
|
||||
im = Image.frombytes(
|
||||
"RGB", size, data,
|
||||
# RGB, 32-bit line padding, origo in lower left corner
|
||||
"raw", "BGR", (size[0]*3 + 3) & -4, -1
|
||||
|
@ -65,7 +65,7 @@ def grab(bbox=None):
|
|||
def grabclipboard():
|
||||
debug = 0 # temporary interface
|
||||
data = Image.core.grabclipboard(debug)
|
||||
if Image.isStringType(data):
|
||||
if isinstance(data, bytes):
|
||||
from . import BmpImagePlugin
|
||||
import io
|
||||
return BmpImagePlugin.DibImageFile(io.BytesIO(data))
|
||||
|
|
|
@ -91,14 +91,14 @@ class _Operand:
|
|||
return _Operand(out)
|
||||
|
||||
# unary operators
|
||||
if sys.version_info >= (3,0):
|
||||
def __bool__(self):
|
||||
# an image is "true" if it contains at least one non-zero pixel
|
||||
return self.im.getbbox() is not None
|
||||
else:
|
||||
def __nonzero__(self):
|
||||
# an image is "true" if it contains at least one non-zero pixel
|
||||
return self.im.getbbox() is not None
|
||||
def __bool__(self):
|
||||
# an image is "true" if it contains at least one non-zero pixel
|
||||
return self.im.getbbox() is not None
|
||||
|
||||
if bytes is str:
|
||||
# Provide __nonzero__ for pre-Py3k
|
||||
__nonzero__ = __bool__
|
||||
del __bool__
|
||||
|
||||
def __abs__(self):
|
||||
return self.apply("abs", self)
|
||||
|
@ -120,9 +120,9 @@ class _Operand:
|
|||
return self.apply("mul", self, other)
|
||||
def __rmul__(self, other):
|
||||
return self.apply("mul", other, self)
|
||||
def __div__(self, other):
|
||||
def __truediv__(self, other):
|
||||
return self.apply("div", self, other)
|
||||
def __rdiv__(self, other):
|
||||
def __rtruediv__(self, other):
|
||||
return self.apply("div", other, self)
|
||||
def __mod__(self, other):
|
||||
return self.apply("mod", self, other)
|
||||
|
@ -133,6 +133,13 @@ class _Operand:
|
|||
def __rpow__(self, other):
|
||||
return self.apply("pow", other, self)
|
||||
|
||||
if bytes is str:
|
||||
# Provide __div__ and __rdiv__ for pre-Py3k
|
||||
__div__ = __truediv__
|
||||
__rdiv__ = __rtruediv__
|
||||
del __truediv__
|
||||
del __rtruediv__
|
||||
|
||||
# bitwise
|
||||
def __invert__(self):
|
||||
return self.apply("invert", self)
|
||||
|
|
|
@ -95,7 +95,7 @@ def autocontrast(image, cutoff=0, ignore=None):
|
|||
for ix in range(256):
|
||||
n = n + h[ix]
|
||||
# remove cutoff% pixels from the low end
|
||||
cut = n * cutoff / 100
|
||||
cut = n * cutoff // 100
|
||||
for lo in range(256):
|
||||
if cut > h[lo]:
|
||||
cut = cut - h[lo]
|
||||
|
@ -106,7 +106,7 @@ def autocontrast(image, cutoff=0, ignore=None):
|
|||
if cut <= 0:
|
||||
break
|
||||
# remove cutoff% samples from the hi end
|
||||
cut = n * cutoff / 100
|
||||
cut = n * cutoff // 100
|
||||
for hi in range(255, -1, -1):
|
||||
if cut > h[hi]:
|
||||
cut = cut - h[hi]
|
||||
|
@ -125,7 +125,7 @@ def autocontrast(image, cutoff=0, ignore=None):
|
|||
break
|
||||
if hi <= lo:
|
||||
# don't bother
|
||||
lut.extend(range(256))
|
||||
lut.extend(list(range(256)))
|
||||
else:
|
||||
scale = 255.0 / (hi - lo)
|
||||
offset = -lo * scale
|
||||
|
@ -156,9 +156,9 @@ def colorize(image, black, white):
|
|||
white = _color(white, "RGB")
|
||||
red = []; green = []; blue = []
|
||||
for i in range(256):
|
||||
red.append(black[0]+i*(white[0]-black[0])/255)
|
||||
green.append(black[1]+i*(white[1]-black[1])/255)
|
||||
blue.append(black[2]+i*(white[2]-black[2])/255)
|
||||
red.append(black[0]+i*(white[0]-black[0])//255)
|
||||
green.append(black[1]+i*(white[1]-black[1])//255)
|
||||
blue.append(black[2]+i*(white[2]-black[2])//255)
|
||||
image = image.convert("RGB")
|
||||
return _lut(image, red + green + blue)
|
||||
|
||||
|
@ -212,15 +212,15 @@ def equalize(image, mask=None):
|
|||
for b in range(0, len(h), 256):
|
||||
histo = [_f for _f in h[b:b+256] if _f]
|
||||
if len(histo) <= 1:
|
||||
lut.extend(range(256))
|
||||
lut.extend(list(range(256)))
|
||||
else:
|
||||
step = (reduce(operator.add, histo) - histo[-1]) / 255
|
||||
step = (reduce(operator.add, histo) - histo[-1]) // 255
|
||||
if not step:
|
||||
lut.extend(range(256))
|
||||
lut.extend(list(range(256)))
|
||||
else:
|
||||
n = step / 2
|
||||
n = step // 2
|
||||
for i in range(256):
|
||||
lut.append(n / step)
|
||||
lut.append(n // step)
|
||||
n = n + h[i+b]
|
||||
return _lut(image, lut)
|
||||
|
||||
|
|
|
@ -39,16 +39,20 @@ class ImagePalette:
|
|||
# for the low-level im.putpalette primitive
|
||||
if self.rawmode:
|
||||
return self.rawmode, self.palette
|
||||
return self.mode + ";L", self.tostring()
|
||||
return self.mode + ";L", self.tobytes()
|
||||
|
||||
def tostring(self):
|
||||
# experimental: convert palette to string
|
||||
def tobytes(self):
|
||||
# experimental: convert palette to bytes
|
||||
if self.rawmode:
|
||||
raise ValueError("palette contains raw palette data")
|
||||
if Image.isStringType(self.palette):
|
||||
if isinstance(self.palette, bytes):
|
||||
return self.palette
|
||||
return array.array("B", self.palette).tostring()
|
||||
|
||||
if bytes is str:
|
||||
# Declare tostring as an alias for tobytes
|
||||
tostring = tobytes
|
||||
|
||||
def getcolor(self, color):
|
||||
# experimental: given an rgb tuple, allocate palette entry
|
||||
if self.rawmode:
|
||||
|
@ -58,7 +62,7 @@ class ImagePalette:
|
|||
return self.colors[color]
|
||||
except KeyError:
|
||||
# allocate new color slot
|
||||
if Image.isStringType(self.palette):
|
||||
if isinstance(self.palette, bytes):
|
||||
self.palette = [int(x) for x in self.palette]
|
||||
index = len(self.colors)
|
||||
if index >= 256:
|
||||
|
@ -104,7 +108,7 @@ def _make_linear_lut(black, white):
|
|||
lut = []
|
||||
if black == 0:
|
||||
for i in range(256):
|
||||
lut.append(white*i/255)
|
||||
lut.append(white*i//255)
|
||||
else:
|
||||
raise NotImplementedError # FIXME
|
||||
return lut
|
||||
|
@ -155,6 +159,8 @@ def load(filename):
|
|||
p = GimpPaletteFile.GimpPaletteFile(fp)
|
||||
lut = p.getpalette()
|
||||
except (SyntaxError, ValueError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
if not lut:
|
||||
|
@ -164,6 +170,8 @@ def load(filename):
|
|||
p = GimpGradientFile.GimpGradientFile(fp)
|
||||
lut = p.getpalette()
|
||||
except (SyntaxError, ValueError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
if not lut:
|
||||
|
@ -173,6 +181,8 @@ def load(filename):
|
|||
p = PaletteFile.PaletteFile(fp)
|
||||
lut = p.getpalette()
|
||||
except (SyntaxError, ValueError):
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
pass
|
||||
|
||||
if not lut:
|
||||
|
|
|
@ -62,11 +62,11 @@ class ImageQt(QImage):
|
|||
for i in range(0, len(palette), 3):
|
||||
colortable.append(rgb(*palette[i:i+3]))
|
||||
elif im.mode == "RGB":
|
||||
data = im.tostring("raw", "BGRX")
|
||||
data = im.tobytes("raw", "BGRX")
|
||||
format = QImage.Format_RGB32
|
||||
elif im.mode == "RGBA":
|
||||
try:
|
||||
data = im.tostring("raw", "BGRA")
|
||||
data = im.tobytes("raw", "BGRA")
|
||||
except SystemError:
|
||||
# workaround for earlier versions
|
||||
r, g, b, a = im.split()
|
||||
|
@ -76,7 +76,7 @@ class ImageQt(QImage):
|
|||
raise ValueError("unsupported image mode %r" % im.mode)
|
||||
|
||||
# must keep a reference, or Qt will crash!
|
||||
self.__data = data or im.tostring()
|
||||
self.__data = data or im.tobytes()
|
||||
|
||||
QImage.__init__(self, self.__data, im.size[0], im.size[1], format)
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ class Stat:
|
|||
v = []
|
||||
for i in self.bands:
|
||||
s = 0
|
||||
l = self.count[i]/2
|
||||
l = self.count[i]//2
|
||||
b = i * 256
|
||||
for j in range(256):
|
||||
s = s + self.h[b+j]
|
||||
|
|
|
@ -151,22 +151,25 @@ class Dib:
|
|||
self.image.paste(im.im)
|
||||
|
||||
##
|
||||
# Load display memory contents from string buffer.
|
||||
# Load display memory contents from byte data.
|
||||
#
|
||||
# @param buffer A string buffer containing display data (usually
|
||||
# data returned from <b>tostring</b>)
|
||||
# @param buffer A buffer containing display data (usually
|
||||
# data returned from <b>tobytes</b>)
|
||||
|
||||
def fromstring(self, buffer):
|
||||
return self.image.fromstring(buffer)
|
||||
def frombytes(self, buffer):
|
||||
return self.image.frombytes(buffer)
|
||||
|
||||
##
|
||||
# Copy display memory contents to string buffer.
|
||||
# Copy display memory contents to bytes object.
|
||||
#
|
||||
# @return A string buffer containing display data.
|
||||
# @return A bytes object containing display data.
|
||||
|
||||
def tostring(self):
|
||||
return self.image.tostring()
|
||||
def tobytes(self):
|
||||
return self.image.tobytes()
|
||||
|
||||
if bytes is str:
|
||||
tostring = tobytes
|
||||
fromstring = frombytes
|
||||
|
||||
##
|
||||
# Create a Window with the given title size.
|
||||
|
|
|
@ -24,7 +24,7 @@ from . import Image, ImageFile
|
|||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
field = re.compile(r"([a-z]*) ([^ \r\n]*)")
|
||||
field = re.compile(br"([a-z]*) ([^ \r\n]*)")
|
||||
|
||||
##
|
||||
# Image plugin for IM Tools images.
|
||||
|
@ -39,7 +39,7 @@ class ImtImageFile(ImageFile.ImageFile):
|
|||
# Quick rejection: if there's not a LF among the first
|
||||
# 100 bytes, this is (probably) not a text header.
|
||||
|
||||
if not "\n" in self.fp.read(100):
|
||||
if not b"\n" in self.fp.read(100):
|
||||
raise SyntaxError("not an IM file")
|
||||
self.fp.seek(0)
|
||||
|
||||
|
@ -51,7 +51,7 @@ class ImtImageFile(ImageFile.ImageFile):
|
|||
if not s:
|
||||
break
|
||||
|
||||
if s == chr(12):
|
||||
if s == b'\x0C':
|
||||
|
||||
# image data begins
|
||||
self.tile = [("raw", (0,0)+self.size,
|
||||
|
@ -67,7 +67,7 @@ class ImtImageFile(ImageFile.ImageFile):
|
|||
s = s + self.fp.readline()
|
||||
if len(s) == 1 or len(s) > 100:
|
||||
break
|
||||
if s[0] == "*":
|
||||
if s[0] == b"*":
|
||||
continue # comment
|
||||
|
||||
m = field.match(s)
|
||||
|
|
|
@ -20,32 +20,30 @@ from __future__ import print_function
|
|||
__version__ = "0.3"
|
||||
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
import os, tempfile
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
o8 = _binary.o8
|
||||
|
||||
COMPRESSION = {
|
||||
1: "raw",
|
||||
5: "jpeg"
|
||||
}
|
||||
|
||||
PAD = chr(0) * 4
|
||||
PAD = o8(0) * 4
|
||||
|
||||
#
|
||||
# Helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
|
||||
def i(c):
|
||||
return i32((PAD + c)[-4:])
|
||||
|
||||
def dump(c):
|
||||
for i in c:
|
||||
print("%02x" % ord(i), end=' ')
|
||||
print("%02x" % i8(i), end=' ')
|
||||
print()
|
||||
|
||||
##
|
||||
|
@ -67,14 +65,14 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
if not len(s):
|
||||
return None, 0
|
||||
|
||||
tag = ord(s[1]), ord(s[2])
|
||||
tag = i8(s[1]), i8(s[2])
|
||||
|
||||
# syntax
|
||||
if ord(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9:
|
||||
if i8(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9:
|
||||
raise SyntaxError("invalid IPTC/NAA file")
|
||||
|
||||
# field size
|
||||
size = ord(s[3])
|
||||
size = i8(s[3])
|
||||
if size > 132:
|
||||
raise IOError("illegal field length in IPTC/NAA file")
|
||||
elif size == 128:
|
||||
|
@ -131,10 +129,10 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
# print tag, self.info[tag]
|
||||
|
||||
# mode
|
||||
layers = ord(self.info[(3,60)][0])
|
||||
component = ord(self.info[(3,60)][1])
|
||||
layers = i8(self.info[(3,60)][0])
|
||||
component = i8(self.info[(3,60)][1])
|
||||
if (3,65) in self.info:
|
||||
id = ord(self.info[(3,65)][0])-1
|
||||
id = i8(self.info[(3,65)][0])-1
|
||||
else:
|
||||
id = 0
|
||||
if layers == 1 and not component:
|
||||
|
@ -242,7 +240,7 @@ def getiptcinfo(im):
|
|||
code = JpegImagePlugin.i16(app, offset)
|
||||
offset = offset + 2
|
||||
# resource name (usually empty)
|
||||
name_len = ord(app[offset])
|
||||
name_len = i8(app[offset])
|
||||
name = app[offset+1:offset+1+name_len]
|
||||
offset = 1 + offset + name_len
|
||||
if offset & 1:
|
||||
|
|
|
@ -35,13 +35,12 @@
|
|||
__version__ = "0.6"
|
||||
|
||||
import array, struct
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
def i16(c,o=0):
|
||||
return ord(c[o+1]) + (ord(c[o])<<8)
|
||||
|
||||
def i32(c,o=0):
|
||||
return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
|
||||
i8 = _binary.i8
|
||||
o8 = _binary.o8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
#
|
||||
# Parser
|
||||
|
@ -63,13 +62,13 @@ def APP(self, marker):
|
|||
self.app[app] = s # compatibility
|
||||
self.applist.append((app, s))
|
||||
|
||||
if marker == 0xFFE0 and s[:4] == "JFIF":
|
||||
if marker == 0xFFE0 and s[:4] == b"JFIF":
|
||||
# extract JFIF information
|
||||
self.info["jfif"] = version = i16(s, 5) # version
|
||||
self.info["jfif_version"] = divmod(version, 256)
|
||||
# extract JFIF properties
|
||||
try:
|
||||
jfif_unit = ord(s[7])
|
||||
jfif_unit = i8(s[7])
|
||||
jfif_density = i16(s, 8), i16(s, 10)
|
||||
except:
|
||||
pass
|
||||
|
@ -78,13 +77,13 @@ def APP(self, marker):
|
|||
self.info["dpi"] = jfif_density
|
||||
self.info["jfif_unit"] = jfif_unit
|
||||
self.info["jfif_density"] = jfif_density
|
||||
elif marker == 0xFFE1 and s[:5] == "Exif\0":
|
||||
elif marker == 0xFFE1 and s[:5] == b"Exif\0":
|
||||
# extract Exif information (incomplete)
|
||||
self.info["exif"] = s # FIXME: value will change
|
||||
elif marker == 0xFFE2 and s[:5] == "FPXR\0":
|
||||
elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
|
||||
# extract FlashPix information (incomplete)
|
||||
self.info["flashpix"] = s # FIXME: value will change
|
||||
elif marker == 0xFFE2 and s[:12] == "ICC_PROFILE\0":
|
||||
elif marker == 0xFFE2 and s[:12] == b"ICC_PROFILE\0":
|
||||
# Since an ICC profile can be larger than the maximum size of
|
||||
# a JPEG marker (64K), we need provisions to split it into
|
||||
# multiple markers. The format defined by the ICC specifies
|
||||
|
@ -97,11 +96,11 @@ def APP(self, marker):
|
|||
# reassemble the profile, rather than assuming that the APP2
|
||||
# markers appear in the correct sequence.
|
||||
self.icclist.append(s)
|
||||
elif marker == 0xFFEE and s[:5] == "Adobe":
|
||||
elif marker == 0xFFEE and s[:5] == b"Adobe":
|
||||
self.info["adobe"] = i16(s, 5)
|
||||
# extract Adobe custom properties
|
||||
try:
|
||||
adobe_transform = ord(s[1])
|
||||
adobe_transform = i8(s[1])
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
|
@ -129,11 +128,11 @@ def SOF(self, marker):
|
|||
s = ImageFile._safe_read(self.fp, n)
|
||||
self.size = i16(s[3:]), i16(s[1:])
|
||||
|
||||
self.bits = ord(s[0])
|
||||
self.bits = i8(s[0])
|
||||
if self.bits != 8:
|
||||
raise SyntaxError("cannot handle %d-bit layers" % self.bits)
|
||||
|
||||
self.layers = ord(s[5])
|
||||
self.layers = i8(s[5])
|
||||
if self.layers == 1:
|
||||
self.mode = "L"
|
||||
elif self.layers == 3:
|
||||
|
@ -149,11 +148,11 @@ def SOF(self, marker):
|
|||
if self.icclist:
|
||||
# fixup icc profile
|
||||
self.icclist.sort() # sort by sequence number
|
||||
if ord(self.icclist[0][13]) == len(self.icclist):
|
||||
if i8(self.icclist[0][13]) == len(self.icclist):
|
||||
profile = []
|
||||
for p in self.icclist:
|
||||
profile.append(p[14:])
|
||||
icc_profile = "".join(profile)
|
||||
icc_profile = b"".join(profile)
|
||||
else:
|
||||
icc_profile = None # wrong number of fragments
|
||||
self.info["icc_profile"] = icc_profile
|
||||
|
@ -162,7 +161,7 @@ def SOF(self, marker):
|
|||
for i in range(6, len(s), 3):
|
||||
t = s[i:i+3]
|
||||
# 4-tuples: id, vsamp, hsamp, qtable
|
||||
self.layer.append((t[0], ord(t[1])/16, ord(t[1])&15, ord(t[2])))
|
||||
self.layer.append((t[0], i8(t[1])//16, i8(t[1])&15, i8(t[2])))
|
||||
|
||||
def DQT(self, marker):
|
||||
#
|
||||
|
@ -178,8 +177,8 @@ def DQT(self, marker):
|
|||
while len(s):
|
||||
if len(s) < 65:
|
||||
raise SyntaxError("bad quantization table marker")
|
||||
v = ord(s[0])
|
||||
if v/16 == 0:
|
||||
v = i8(s[0])
|
||||
if v//16 == 0:
|
||||
self.quantization[v&15] = array.array("b", s[1:65])
|
||||
s = s[65:]
|
||||
else:
|
||||
|
@ -258,7 +257,7 @@ MARKER = {
|
|||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0] == "\377"
|
||||
return prefix[0:1] == b"\377"
|
||||
|
||||
##
|
||||
# Image plugin for JPEG and JFIF images.
|
||||
|
@ -272,7 +271,7 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
|
||||
s = self.fp.read(1)
|
||||
|
||||
if ord(s[0]) != 255:
|
||||
if i8(s[0]) != 255:
|
||||
raise SyntaxError("not a JPEG file")
|
||||
|
||||
# Create attributes
|
||||
|
@ -325,12 +324,12 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
a = mode, ""
|
||||
|
||||
if size:
|
||||
scale = max(self.size[0] / size[0], self.size[1] / size[1])
|
||||
scale = max(self.size[0] // size[0], self.size[1] // size[1])
|
||||
for s in [8, 4, 2, 1]:
|
||||
if scale >= s:
|
||||
break
|
||||
e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1]
|
||||
self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s)
|
||||
e = e[0], e[1], (e[2]-e[0]+s-1)//s+e[0], (e[3]-e[1]+s-1)//s+e[1]
|
||||
self.size = ((self.size[0]+s-1)//s, (self.size[1]+s-1)//s)
|
||||
scale = s
|
||||
|
||||
self.tile = [(d, e, o, a)]
|
||||
|
@ -436,7 +435,7 @@ def _save(im, fp, filename):
|
|||
elif subsampling == "4:1:1":
|
||||
subsampling = 2
|
||||
|
||||
extra = ""
|
||||
extra = b""
|
||||
|
||||
icc_profile = info.get("icc_profile")
|
||||
if icc_profile:
|
||||
|
@ -450,7 +449,7 @@ def _save(im, fp, filename):
|
|||
i = 1
|
||||
for marker in markers:
|
||||
size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker))
|
||||
extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker)
|
||||
extra = extra + (b"\xFF\xE2" + size + b"ICC_PROFILE\0" + o8(i) + o8(len(markers)) + marker)
|
||||
i = i + 1
|
||||
|
||||
# get keyword arguments
|
||||
|
|
|
@ -22,7 +22,7 @@ import struct
|
|||
from . import Image, ImageFile
|
||||
|
||||
def _accept(s):
|
||||
return s[:8] == "\x00\x00\x00\x00\x00\x00\x00\x04"
|
||||
return s[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04"
|
||||
|
||||
##
|
||||
# Image plugin for McIdas area images.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
__version__ = "0.1"
|
||||
|
||||
from . import Image, ImageFile
|
||||
from ._binary import i8
|
||||
|
||||
#
|
||||
# Bitstream parser
|
||||
|
@ -28,7 +29,7 @@ class BitStream:
|
|||
self.bitbuffer = 0
|
||||
|
||||
def next(self):
|
||||
return ord(self.fp.read(1))
|
||||
return i8(self.fp.read(1))
|
||||
|
||||
def peek(self, bits):
|
||||
while self.bits < bits:
|
||||
|
@ -42,7 +43,7 @@ class BitStream:
|
|||
|
||||
def skip(self, bits):
|
||||
while self.bits < bits:
|
||||
self.bitbuffer = (self.bitbuffer << 8) + ord(self.fp.read(1))
|
||||
self.bitbuffer = (self.bitbuffer << 8) + i8(self.fp.read(1))
|
||||
self.bits = self.bits + 8
|
||||
self.bits = self.bits - bits
|
||||
|
||||
|
|
|
@ -19,17 +19,16 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
|
||||
#
|
||||
# read MSP files
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
i16 = _binary.i16le
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] in ["DanM", "LinS"]
|
||||
return prefix[:4] in [b"DanM", b"LinS"]
|
||||
|
||||
##
|
||||
# Image plugin for Windows MSP images. This plugin supports both
|
||||
|
@ -44,7 +43,7 @@ class MspImageFile(ImageFile.ImageFile):
|
|||
|
||||
# Header
|
||||
s = self.fp.read(32)
|
||||
if s[:4] not in ["DanM", "LinS"]:
|
||||
if s[:4] not in [b"DanM", b"LinS"]:
|
||||
raise SyntaxError("not an MSP file")
|
||||
|
||||
# Header checksum
|
||||
|
@ -57,7 +56,7 @@ class MspImageFile(ImageFile.ImageFile):
|
|||
self.mode = "1"
|
||||
self.size = i16(s[4:]), i16(s[6:])
|
||||
|
||||
if s[:4] == "DanM":
|
||||
if s[:4] == b"DanM":
|
||||
self.tile = [("raw", (0,0)+self.size, 32, ("1", 0, 1))]
|
||||
else:
|
||||
self.tile = [("msp", (0,0)+self.size, 32+2*self.size[1], None)]
|
||||
|
@ -65,8 +64,7 @@ class MspImageFile(ImageFile.ImageFile):
|
|||
#
|
||||
# write MSP files (uncompressed only)
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
o16 = _binary.o16le
|
||||
|
||||
def _save(im, fp, filename):
|
||||
|
||||
|
@ -76,7 +74,7 @@ def _save(im, fp, filename):
|
|||
# create MSP header
|
||||
header = [0] * 16
|
||||
|
||||
header[0], header[1] = i16("Da"), i16("nM") # version 1
|
||||
header[0], header[1] = i16(b"Da"), i16(b"nM") # version 1
|
||||
header[2], header[3] = im.size
|
||||
header[4], header[5] = 1, 1
|
||||
header[6], header[7] = 1, 1
|
||||
|
|
|
@ -40,18 +40,17 @@ from __future__ import print_function
|
|||
|
||||
import io
|
||||
import sys
|
||||
from . import _binary
|
||||
|
||||
if str != bytes:
|
||||
if str is not bytes:
|
||||
long = int
|
||||
|
||||
def i16(c, o = 0):
|
||||
return ord(c[o])+(ord(c[o+1])<<8)
|
||||
|
||||
def i32(c, o = 0):
|
||||
return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
MAGIC = '\320\317\021\340\241\261\032\341'
|
||||
MAGIC = b'\320\317\021\340\241\261\032\341'
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -332,12 +331,12 @@ class OleFileIO:
|
|||
def _unicode(self, s):
|
||||
# Map unicode string to Latin 1
|
||||
|
||||
if sys.version_info >= (3,0):
|
||||
# Provide actual Unicode string
|
||||
return s.decode('utf-16')
|
||||
else:
|
||||
if bytes is str:
|
||||
# Old version tried to produce a Latin-1 str
|
||||
return s.decode('utf-16').encode('latin-1', 'replace')
|
||||
else:
|
||||
# Provide actual Unicode string
|
||||
return s.decode('utf-16')
|
||||
|
||||
def loaddirectory(self, sect):
|
||||
# Load the directory. The directory is stored in a standard
|
||||
|
@ -352,7 +351,7 @@ class OleFileIO:
|
|||
entry = fp.read(128)
|
||||
if not entry:
|
||||
break
|
||||
type = ord(entry[66])
|
||||
type = i8(entry[66])
|
||||
name = self._unicode(entry[0:0+i16(entry, 64)])
|
||||
ptrs = i32(entry, 68), i32(entry, 72), i32(entry, 76)
|
||||
sect, size = i32(entry, 116), i32(entry, 120)
|
||||
|
@ -372,7 +371,7 @@ class OleFileIO:
|
|||
return ""
|
||||
return (("%08X-%04X-%04X-%02X%02X-" + "%02X" * 6) %
|
||||
((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) +
|
||||
tuple(map(ord, clsid[8:16]))))
|
||||
tuple(map(i8, clsid[8:16]))))
|
||||
|
||||
def _list(self, files, prefix, node):
|
||||
# listdir helper
|
||||
|
@ -488,9 +487,9 @@ class OleFileIO:
|
|||
value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32)
|
||||
# FIXME: this is a 64-bit int: "number of 100ns periods
|
||||
# since Jan 1,1601". Should map this to Python time
|
||||
value = value / 10000000 # seconds
|
||||
value = value // 10000000 # seconds
|
||||
elif type == VT_UI1:
|
||||
value = ord(s[offset+4])
|
||||
value = i8(s[offset+4])
|
||||
elif type == VT_CLSID:
|
||||
value = self._clsid(s[offset+4:offset+20])
|
||||
elif type == VT_CF:
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from ._binary import o8
|
||||
|
||||
##
|
||||
# File handler for Teragon-style palette files.
|
||||
|
||||
|
@ -30,7 +32,7 @@ class PaletteFile:
|
|||
|
||||
if not s:
|
||||
break
|
||||
if s[0] == "#":
|
||||
if s[0:1] == b"#":
|
||||
continue
|
||||
if len(s) > 100:
|
||||
raise SyntaxError("bad palette file")
|
||||
|
@ -43,9 +45,9 @@ class PaletteFile:
|
|||
g = b = r
|
||||
|
||||
if 0 <= i <= 255:
|
||||
self.palette[i] = chr(r) + chr(g) + chr(b)
|
||||
self.palette[i] = o8(r) + o8(g) + o8(b)
|
||||
|
||||
self.palette = "".join(self.palette)
|
||||
self.palette = b"".join(self.palette)
|
||||
|
||||
|
||||
def getpalette(self):
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
__version__ = "1.0"
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
_Palm8BitColormapValues = (
|
||||
( 255, 255, 255 ), ( 255, 204, 255 ), ( 255, 153, 255 ), ( 255, 102, 255 ),
|
||||
|
@ -107,8 +107,8 @@ _COMPRESSION_TYPES = {
|
|||
"scanline": 0x00,
|
||||
}
|
||||
|
||||
def o16b(i):
|
||||
return chr(i>>8&255) + chr(i&255)
|
||||
o8 = _binary.o8
|
||||
o16b = _binary.o16be
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -172,7 +172,7 @@ def _save(im, fp, filename, check=0):
|
|||
cols = im.size[0]
|
||||
rows = im.size[1]
|
||||
|
||||
rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2;
|
||||
rowbytes = ((cols + (16//bpp - 1)) / (16 // bpp)) * 2;
|
||||
transparent_index = 0
|
||||
compression_type = _COMPRESSION_TYPES["none"]
|
||||
|
||||
|
@ -186,16 +186,16 @@ def _save(im, fp, filename, check=0):
|
|||
colormapsize = 0
|
||||
|
||||
if "offset" in im.info:
|
||||
offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4;
|
||||
offset = (rowbytes * rows + 16 + 3 + colormapsize) // 4;
|
||||
else:
|
||||
offset = 0
|
||||
|
||||
fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags))
|
||||
fp.write(chr(bpp))
|
||||
fp.write(chr(version))
|
||||
fp.write(o8(bpp))
|
||||
fp.write(o8(version))
|
||||
fp.write(o16b(offset))
|
||||
fp.write(chr(transparent_index))
|
||||
fp.write(chr(compression_type))
|
||||
fp.write(o8(transparent_index))
|
||||
fp.write(o8(compression_type))
|
||||
fp.write(o16b(0)) # reserved by Palm
|
||||
|
||||
# now write colormap if necessary
|
||||
|
@ -203,11 +203,11 @@ def _save(im, fp, filename, check=0):
|
|||
if colormapsize > 0:
|
||||
fp.write(o16b(256))
|
||||
for i in range(256):
|
||||
fp.write(chr(i))
|
||||
fp.write(o8(i))
|
||||
if colormapmode == 'RGB':
|
||||
fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2]))
|
||||
fp.write(o8(colormap[3 * i]) + o8(colormap[3 * i + 1]) + o8(colormap[3 * i + 2]))
|
||||
elif colormapmode == 'RGBA':
|
||||
fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2]))
|
||||
fp.write(o8(colormap[4 * i]) + o8(colormap[4 * i + 1]) + o8(colormap[4 * i + 2]))
|
||||
|
||||
# now convert data to raw form
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))])
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
__version__ = "0.1"
|
||||
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
i8 = _binary.i8
|
||||
|
||||
##
|
||||
# Image plugin for PhotoCD images. This plugin only reads the 768x512
|
||||
|
@ -36,10 +38,10 @@ class PcdImageFile(ImageFile.ImageFile):
|
|||
self.fp.seek(2048)
|
||||
s = self.fp.read(2048)
|
||||
|
||||
if s[:4] != "PCD_":
|
||||
if s[:4] != b"PCD_":
|
||||
raise SyntaxError("not a PCD file")
|
||||
|
||||
orientation = ord(s[1538]) & 3
|
||||
orientation = i8(s[1538]) & 3
|
||||
if orientation == 1:
|
||||
self.tile_post_rotate = 90 # hack
|
||||
elif orientation == 3:
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
from . import Image
|
||||
from . import FontFile
|
||||
from . import _binary
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# declarations
|
||||
|
@ -41,19 +42,14 @@ BYTES_PER_ROW = [
|
|||
lambda bits: ((bits+63) >> 3) & ~7,
|
||||
]
|
||||
|
||||
|
||||
def l16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
def l32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
def b16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
def b32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i8 = _binary.i8
|
||||
l16 = _binary.i16le
|
||||
l32 = _binary.i32le
|
||||
b16 = _binary.i16be
|
||||
b32 = _binary.i32be
|
||||
|
||||
def sz(s, o):
|
||||
return s[o:s.index("\0", o)]
|
||||
return s[o:s.index(b"\0", o)]
|
||||
|
||||
##
|
||||
# Font file plugin for the X11 PCF format.
|
||||
|
@ -124,7 +120,7 @@ class PcfFontFile(FontFile.FontFile):
|
|||
# read property description
|
||||
p = []
|
||||
for i in range(nprops):
|
||||
p.append((i32(fp.read(4)), ord(fp.read(1)), i32(fp.read(4))))
|
||||
p.append((i32(fp.read(4)), i8(fp.read(1)), i32(fp.read(4))))
|
||||
if nprops & 3:
|
||||
fp.seek(4 - (nprops & 3), 1) # pad
|
||||
|
||||
|
@ -153,11 +149,11 @@ class PcfFontFile(FontFile.FontFile):
|
|||
|
||||
# "compressed" metrics
|
||||
for i in range(i16(fp.read(2))):
|
||||
left = ord(fp.read(1)) - 128
|
||||
right = ord(fp.read(1)) - 128
|
||||
width = ord(fp.read(1)) - 128
|
||||
ascent = ord(fp.read(1)) - 128
|
||||
descent = ord(fp.read(1)) - 128
|
||||
left = i8(fp.read(1)) - 128
|
||||
right = i8(fp.read(1)) - 128
|
||||
width = i8(fp.read(1)) - 128
|
||||
ascent = i8(fp.read(1)) - 128
|
||||
descent = i8(fp.read(1)) - 128
|
||||
xsize = right - left
|
||||
ysize = ascent + descent
|
||||
append(
|
||||
|
@ -224,7 +220,7 @@ class PcfFontFile(FontFile.FontFile):
|
|||
x, y, l, r, w, a, d, f = metrics[i]
|
||||
b, e = offsets[i], offsets[i+1]
|
||||
bitmaps.append(
|
||||
Image.fromstring("1", (x, y), data[b:e], "raw", mode, pad(x))
|
||||
Image.frombytes("1", (x, y), data[b:e], "raw", mode, pad(x))
|
||||
)
|
||||
|
||||
return bitmaps
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
|
||||
__version__ = "0.6"
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
def i16(c,o):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
o8 = _binary.o8
|
||||
|
||||
def _accept(prefix):
|
||||
return ord(prefix[0]) == 10 and ord(prefix[1]) in [0, 2, 3, 5]
|
||||
return i8(prefix[0]) == 10 and i8(prefix[1]) in [0, 2, 3, 5]
|
||||
|
||||
##
|
||||
# Image plugin for Paintbrush images.
|
||||
|
@ -56,9 +57,9 @@ class PcxImageFile(ImageFile.ImageFile):
|
|||
raise SyntaxError("bad PCX image size")
|
||||
|
||||
# format
|
||||
version = ord(s[1])
|
||||
bits = ord(s[3])
|
||||
planes = ord(s[65])
|
||||
version = i8(s[1])
|
||||
bits = i8(s[3])
|
||||
planes = i8(s[65])
|
||||
stride = i16(s,66)
|
||||
|
||||
self.info["dpi"] = i16(s,12), i16(s,14)
|
||||
|
@ -76,10 +77,10 @@ class PcxImageFile(ImageFile.ImageFile):
|
|||
# FIXME: hey, this doesn't work with the incremental loader !!!
|
||||
self.fp.seek(-769, 2)
|
||||
s = self.fp.read(769)
|
||||
if len(s) == 769 and ord(s[0]) == 12:
|
||||
if len(s) == 769 and i8(s[0]) == 12:
|
||||
# check if the palette is linear greyscale
|
||||
for i in range(256):
|
||||
if s[i*3+1:i*3+4] != chr(i)*3:
|
||||
if s[i*3+1:i*3+4] != o8(i)*3:
|
||||
mode = rawmode = "P"
|
||||
break
|
||||
if mode == "P":
|
||||
|
@ -111,8 +112,7 @@ SAVE = {
|
|||
"RGB": (5, 8, 3, "RGB;L"),
|
||||
}
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
o16 = _binary.o16le
|
||||
|
||||
def _save(im, fp, filename, check=0):
|
||||
|
||||
|
@ -125,7 +125,7 @@ def _save(im, fp, filename, check=0):
|
|||
return check
|
||||
|
||||
# bytes per plane
|
||||
stride = (im.size[0] * bits + 7) / 8
|
||||
stride = (im.size[0] * bits + 7) // 8
|
||||
|
||||
# under windows, we could determine the current screen size with
|
||||
# "Image.core.display_mode()[1]", but I think that's overkill...
|
||||
|
@ -136,11 +136,11 @@ def _save(im, fp, filename, check=0):
|
|||
|
||||
# PCX header
|
||||
fp.write(
|
||||
chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) +
|
||||
o8(10) + o8(version) + o8(1) + o8(bits) + o16(0) +
|
||||
o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +
|
||||
o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) +
|
||||
o16(dpi[1]) + b"\0"*24 + b"\xFF"*24 + b"\0" + o8(planes) +
|
||||
o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +
|
||||
chr(0)*54
|
||||
b"\0"*54
|
||||
)
|
||||
|
||||
assert fp.tell() == 128
|
||||
|
@ -150,13 +150,13 @@ def _save(im, fp, filename, check=0):
|
|||
|
||||
if im.mode == "P":
|
||||
# colour palette
|
||||
fp.write(chr(12))
|
||||
fp.write(o8(12))
|
||||
fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes
|
||||
elif im.mode == "L":
|
||||
# greyscale palette
|
||||
fp.write(chr(12))
|
||||
fp.write(o8(12))
|
||||
for i in range(256):
|
||||
fp.write(chr(i)*3)
|
||||
fp.write(o8(i)*3)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# registry
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
__version__ = "0.4"
|
||||
|
||||
from . import Image, ImageFile
|
||||
from ._binary import i8
|
||||
import io
|
||||
|
||||
|
||||
|
@ -37,12 +38,15 @@ import io
|
|||
# 5. page contents
|
||||
|
||||
def _obj(fp, obj, **dict):
|
||||
fp.write(b"%d 0 obj\n" % obj)
|
||||
fp.write(("%d 0 obj\n" % obj).encode('ascii'))
|
||||
if dict:
|
||||
fp.write(b"<<\n")
|
||||
for k, v in dict.items():
|
||||
if v is not None:
|
||||
fp.write(b"/%s %s\n" % (k, v))
|
||||
if not isinstance(v, bytes):
|
||||
v = str(v).encode('ascii')
|
||||
|
||||
fp.write(b"/" + k.encode('ascii') + b" " + v + b"\n")
|
||||
fp.write(b">>\n")
|
||||
|
||||
def _endobj(fp):
|
||||
|
@ -61,7 +65,7 @@ def _save(im, fp, filename):
|
|||
xref = [0]*(5+1) # placeholders
|
||||
|
||||
fp.write(b"%PDF-1.2\n")
|
||||
fp.write(b"% created by PIL PDF driver " + __version__ + "\n")
|
||||
fp.write(b"% created by PIL PDF driver " + __version__.encode('ascii') + b"\n")
|
||||
|
||||
#
|
||||
# Get image characteristics
|
||||
|
@ -78,32 +82,32 @@ def _save(im, fp, filename):
|
|||
if im.mode == "1":
|
||||
filter = b"/ASCIIHexDecode"
|
||||
colorspace = b"/DeviceGray"
|
||||
procset = b"/ImageB" # grayscale
|
||||
procset = "/ImageB" # grayscale
|
||||
bits = 1
|
||||
elif im.mode == "L":
|
||||
filter = b"/DCTDecode"
|
||||
# params = "<< /Predictor 15 /Columns %d >>" % (width-2)
|
||||
colorspace = b"/DeviceGray"
|
||||
procset = b"/ImageB" # grayscale
|
||||
procset = "/ImageB" # grayscale
|
||||
elif im.mode == "P":
|
||||
filter = b"/ASCIIHexDecode"
|
||||
colorspace = b"[ /Indexed /DeviceRGB 255 <"
|
||||
palette = im.im.getpalette("RGB")
|
||||
for i in range(256):
|
||||
r = ord(palette[i*3])
|
||||
g = ord(palette[i*3+1])
|
||||
b = ord(palette[i*3+2])
|
||||
colorspace = colorspace + b"%02x%02x%02x " % (r, g, b)
|
||||
r = i8(palette[i*3])
|
||||
g = i8(palette[i*3+1])
|
||||
b = i8(palette[i*3+2])
|
||||
colorspace = colorspace + ("%02x%02x%02x " % (r, g, b)).encode('ascii')
|
||||
colorspace = colorspace + b"> ]"
|
||||
procset = b"/ImageI" # indexed color
|
||||
procset = "/ImageI" # indexed color
|
||||
elif im.mode == "RGB":
|
||||
filter = b"/DCTDecode"
|
||||
colorspace = b"/DeviceRGB"
|
||||
procset = b"/ImageC" # color images
|
||||
procset = "/ImageC" # color images
|
||||
elif im.mode == "CMYK":
|
||||
filter = b"/DCTDecode"
|
||||
colorspace = b"/DeviceCMYK"
|
||||
procset = b"/ImageC" # color images
|
||||
procset = "/ImageC" # color images
|
||||
else:
|
||||
raise ValueError("cannot save mode %s" % im.mode)
|
||||
|
||||
|
@ -168,11 +172,11 @@ def _save(im, fp, filename):
|
|||
|
||||
xref[4] = fp.tell()
|
||||
_obj(fp, 4)
|
||||
fp.write(b"<<\n/Type /Page\n/Parent 2 0 R\n"\
|
||||
b"/Resources <<\n/ProcSet [ /PDF %s ]\n"\
|
||||
b"/XObject << /image 3 0 R >>\n>>\n"\
|
||||
b"/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
|
||||
(procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution)))
|
||||
fp.write(("<<\n/Type /Page\n/Parent 2 0 R\n"\
|
||||
"/Resources <<\n/ProcSet [ /PDF %s ]\n"\
|
||||
"/XObject << /image 3 0 R >>\n>>\n"\
|
||||
"/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
|
||||
(procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution))).encode('ascii'))
|
||||
_endobj(fp)
|
||||
|
||||
#
|
||||
|
@ -180,7 +184,7 @@ def _save(im, fp, filename):
|
|||
|
||||
op = io.BytesIO()
|
||||
|
||||
op.write(b"q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution)))
|
||||
op.write(("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution))).encode('ascii'))
|
||||
|
||||
xref[5] = fp.tell()
|
||||
_obj(fp, 5, Length = len(op.getvalue()))
|
||||
|
@ -194,11 +198,11 @@ def _save(im, fp, filename):
|
|||
#
|
||||
# trailer
|
||||
startxref = fp.tell()
|
||||
fp.write(b"xref\n0 %d\n0000000000 65535 f \n" % len(xref))
|
||||
fp.write(("xref\n0 %d\n0000000000 65535 f \n" % len(xref)).encode('ascii'))
|
||||
for x in xref[1:]:
|
||||
fp.write(b"%010d 00000 n \n" % x)
|
||||
fp.write(b"trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref))
|
||||
fp.write(b"startxref\n%d\n%%%%EOF\n" % startxref)
|
||||
fp.write(("%010d 00000 n \n" % x).encode('ascii'))
|
||||
fp.write(("trailer\n<<\n/Size %d\n/Root 1 0 R\n>>\n" % len(xref)).encode('ascii'))
|
||||
fp.write(("startxref\n%d\n%%%%EOF\n" % startxref).encode('ascii'))
|
||||
fp.flush()
|
||||
|
||||
#
|
||||
|
|
|
@ -21,16 +21,13 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
#
|
||||
# helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
##
|
||||
# Image plugin for PIXAR raster images.
|
||||
|
@ -44,7 +41,7 @@ class PixarImageFile(ImageFile.ImageFile):
|
|||
|
||||
# assuming a 4-byte magic label (FIXME: add "_accept" hook)
|
||||
s = self.fp.read(4)
|
||||
if s != "\200\350\000\000":
|
||||
if s != b"\200\350\000\000":
|
||||
raise SyntaxError("not a PIXAR file")
|
||||
|
||||
# read rest of header
|
||||
|
|
|
@ -37,19 +37,17 @@ __version__ = "0.9"
|
|||
|
||||
import re
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
import zlib
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
|
||||
is_cid = re.compile("\w\w\w\w").match
|
||||
is_cid = re.compile(b"\w\w\w\w").match
|
||||
|
||||
|
||||
_MAGIC = "\211PNG\r\n\032\n"
|
||||
_MAGIC = b"\211PNG\r\n\032\n"
|
||||
|
||||
|
||||
_MODES = {
|
||||
|
@ -115,7 +113,7 @@ class ChunkStream:
|
|||
|
||||
if Image.DEBUG:
|
||||
print("STREAM", cid, pos, len)
|
||||
return getattr(self, "chunk_" + cid)(pos, len)
|
||||
return getattr(self, "chunk_" + cid.decode('ascii'))(pos, len)
|
||||
|
||||
def crc(self, cid, data):
|
||||
"Read and verify checksum"
|
||||
|
@ -131,7 +129,7 @@ class ChunkStream:
|
|||
|
||||
self.fp.read(4)
|
||||
|
||||
def verify(self, endchunk = "IEND"):
|
||||
def verify(self, endchunk = b"IEND"):
|
||||
|
||||
# Simple approach; just calculate checksum for all remaining
|
||||
# blocks. Must be called directly after open.
|
||||
|
@ -160,11 +158,18 @@ class PngInfo:
|
|||
self.chunks.append((cid, data))
|
||||
|
||||
def add_text(self, key, value, zip=0):
|
||||
# The tEXt chunk stores latin-1 text
|
||||
if not isinstance(key, bytes):
|
||||
key = key.encode('latin-1', 'strict')
|
||||
|
||||
if not isinstance(value, bytes):
|
||||
value = value.encode('latin-1', 'replace')
|
||||
|
||||
if zip:
|
||||
import zlib
|
||||
self.add("zTXt", key + "\0\0" + zlib.compress(value))
|
||||
self.add(b"zTXt", key + b"\0\0" + zlib.compress(value))
|
||||
else:
|
||||
self.add("tEXt", key + "\0" + value)
|
||||
self.add(b"tEXt", key + b"\0" + value)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# PNG image stream (IHDR/IEND)
|
||||
|
@ -192,11 +197,11 @@ class PngStream(ChunkStream):
|
|||
# Null separator 1 byte (null character)
|
||||
# Compression method 1 byte (0)
|
||||
# Compressed profile n bytes (zlib with deflate compression)
|
||||
i = s.find(chr(0))
|
||||
i = s.find(b"\0")
|
||||
if Image.DEBUG:
|
||||
print("iCCP profile name", s[:i])
|
||||
print("Compression method", ord(s[i]))
|
||||
comp_method = ord(s[i])
|
||||
print("Compression method", i8(s[i]))
|
||||
comp_method = i8(s[i])
|
||||
if comp_method != 0:
|
||||
raise SyntaxError("Unknown compression method %s in iCCP chunk" % comp_method)
|
||||
try:
|
||||
|
@ -212,12 +217,12 @@ class PngStream(ChunkStream):
|
|||
s = ImageFile._safe_read(self.fp, len)
|
||||
self.im_size = i32(s), i32(s[4:])
|
||||
try:
|
||||
self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
self.im_mode, self.im_rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
except:
|
||||
pass
|
||||
if ord(s[12]):
|
||||
if i8(s[12]):
|
||||
self.im_info["interlace"] = 1
|
||||
if ord(s[11]):
|
||||
if i8(s[11]):
|
||||
raise SyntaxError("unknown filter category")
|
||||
return s
|
||||
|
||||
|
@ -246,7 +251,7 @@ class PngStream(ChunkStream):
|
|||
# transparency
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
if self.im_mode == "P":
|
||||
i = s.find(chr(0))
|
||||
i = s.find(b"\0")
|
||||
if i >= 0:
|
||||
self.im_info["transparency"] = i
|
||||
elif self.im_mode == "L":
|
||||
|
@ -267,7 +272,7 @@ class PngStream(ChunkStream):
|
|||
# pixels per unit
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
px, py = i32(s), i32(s[4:])
|
||||
unit = ord(s[8])
|
||||
unit = i8(s[8])
|
||||
if unit == 1: # meter
|
||||
dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
|
||||
self.im_info["dpi"] = dpi
|
||||
|
@ -280,10 +285,14 @@ class PngStream(ChunkStream):
|
|||
# text
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
try:
|
||||
k, v = s.split("\0", 1)
|
||||
k, v = s.split(b"\0", 1)
|
||||
except ValueError:
|
||||
k = s; v = "" # fallback for broken tEXt tags
|
||||
k = s; v = b"" # fallback for broken tEXt tags
|
||||
if k:
|
||||
if bytes is not str:
|
||||
k = k.decode('latin-1', 'strict')
|
||||
v = v.decode('latin-1', 'replace')
|
||||
|
||||
self.im_info[k] = self.im_text[k] = v
|
||||
return s
|
||||
|
||||
|
@ -291,12 +300,18 @@ class PngStream(ChunkStream):
|
|||
|
||||
# compressed text
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
k, v = s.split("\0", 1)
|
||||
comp_method = ord(v[0])
|
||||
k, v = s.split(b"\0", 1)
|
||||
comp_method = i8(v[0])
|
||||
if comp_method != 0:
|
||||
raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method)
|
||||
import zlib
|
||||
self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:])
|
||||
v = zlib.decompress(v[1:])
|
||||
|
||||
if bytes is not str:
|
||||
k = k.decode('latin-1', 'strict')
|
||||
v = v.decode('latin-1', 'replace')
|
||||
|
||||
self.im_info[k] = self.im_text[k] = v
|
||||
return s
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -393,9 +408,9 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
|
||||
cid, pos, len = self.png.read()
|
||||
|
||||
if cid not in ["IDAT", "DDAT"]:
|
||||
if cid not in [b"IDAT", b"DDAT"]:
|
||||
self.png.push(cid, pos, len)
|
||||
return ""
|
||||
return b""
|
||||
|
||||
self.__idat = len # empty chunks are allowed
|
||||
|
||||
|
@ -420,33 +435,31 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
# --------------------------------------------------------------------
|
||||
# PNG writer
|
||||
|
||||
def o16(i):
|
||||
return chr(i>>8&255) + chr(i&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255)
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16be
|
||||
o32 = _binary.o32be
|
||||
|
||||
_OUTMODES = {
|
||||
# supported PIL modes, and corresponding rawmodes/bits/color combinations
|
||||
"1": ("1", chr(1)+chr(0)),
|
||||
"L;1": ("L;1", chr(1)+chr(0)),
|
||||
"L;2": ("L;2", chr(2)+chr(0)),
|
||||
"L;4": ("L;4", chr(4)+chr(0)),
|
||||
"L": ("L", chr(8)+chr(0)),
|
||||
"LA": ("LA", chr(8)+chr(4)),
|
||||
"I": ("I;16B", chr(16)+chr(0)),
|
||||
"P;1": ("P;1", chr(1)+chr(3)),
|
||||
"P;2": ("P;2", chr(2)+chr(3)),
|
||||
"P;4": ("P;4", chr(4)+chr(3)),
|
||||
"P": ("P", chr(8)+chr(3)),
|
||||
"RGB": ("RGB", chr(8)+chr(2)),
|
||||
"RGBA":("RGBA", chr(8)+chr(6)),
|
||||
"1": ("1", b'\x01\x00'),
|
||||
"L;1": ("L;1", b'\x01\x00'),
|
||||
"L;2": ("L;2", b'\x02\x00'),
|
||||
"L;4": ("L;4", b'\x04\x00'),
|
||||
"L": ("L", b'\x08\x00'),
|
||||
"LA": ("LA", b'\x08\x04'),
|
||||
"I": ("I;16B", b'\x10\x00'),
|
||||
"P;1": ("P;1", b'\x01\x03'),
|
||||
"P;2": ("P;2", b'\x02\x03'),
|
||||
"P;4": ("P;4", b'\x04\x03'),
|
||||
"P": ("P", b'\x08\x03'),
|
||||
"RGB": ("RGB", b'\x08\x02'),
|
||||
"RGBA":("RGBA", b'\x08\x06'),
|
||||
}
|
||||
|
||||
def putchunk(fp, cid, *data):
|
||||
"Write a PNG chunk (including CRC field)"
|
||||
|
||||
data = "".join(data)
|
||||
data = b"".join(data)
|
||||
|
||||
fp.write(o32(len(data)) + cid)
|
||||
fp.write(data)
|
||||
|
@ -460,7 +473,7 @@ class _idat:
|
|||
self.fp = fp
|
||||
self.chunk = chunk
|
||||
def write(self, data):
|
||||
self.chunk(self.fp, "IDAT", data)
|
||||
self.chunk(self.fp, b"IDAT", data)
|
||||
|
||||
def _save(im, fp, filename, chunk=putchunk, check=0):
|
||||
# save an image to disk (called by the save method)
|
||||
|
@ -498,7 +511,7 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
if "dictionary" in im.encoderinfo:
|
||||
dictionary = im.encoderinfo["dictionary"]
|
||||
else:
|
||||
dictionary = ""
|
||||
dictionary = b""
|
||||
|
||||
im.encoderconfig = ("optimize" in im.encoderinfo, dictionary)
|
||||
|
||||
|
@ -516,39 +529,39 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
|
||||
fp.write(_MAGIC)
|
||||
|
||||
chunk(fp, "IHDR",
|
||||
chunk(fp, b"IHDR",
|
||||
o32(im.size[0]), o32(im.size[1]), # 0: size
|
||||
mode, # 8: depth/type
|
||||
chr(0), # 10: compression
|
||||
chr(0), # 11: filter category
|
||||
chr(0)) # 12: interlace flag
|
||||
b'\0', # 10: compression
|
||||
b'\0', # 11: filter category
|
||||
b'\0') # 12: interlace flag
|
||||
|
||||
if im.mode == "P":
|
||||
chunk(fp, "PLTE", im.im.getpalette("RGB"))
|
||||
chunk(fp, b"PLTE", im.im.getpalette("RGB"))
|
||||
|
||||
if "transparency" in im.encoderinfo:
|
||||
if im.mode == "P":
|
||||
transparency = max(0, min(255, im.encoderinfo["transparency"]))
|
||||
chunk(fp, "tRNS", chr(255) * transparency + chr(0))
|
||||
chunk(fp, b"tRNS", b'\xFF' * transparency + b'\0')
|
||||
elif im.mode == "L":
|
||||
transparency = max(0, min(65535, im.encoderinfo["transparency"]))
|
||||
chunk(fp, "tRNS", o16(transparency))
|
||||
chunk(fp, b"tRNS", o16(transparency))
|
||||
elif im.mode == "RGB":
|
||||
red, green, blue = im.encoderinfo["transparency"]
|
||||
chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue))
|
||||
chunk(fp, b"tRNS", o16(red) + o16(green) + o16(blue))
|
||||
else:
|
||||
raise IOError("cannot use transparency for this mode")
|
||||
|
||||
if 0:
|
||||
# FIXME: to be supported some day
|
||||
chunk(fp, "gAMA", o32(int(gamma * 100000.0)))
|
||||
chunk(fp, b"gAMA", o32(int(gamma * 100000.0)))
|
||||
|
||||
dpi = im.encoderinfo.get("dpi")
|
||||
if dpi:
|
||||
chunk(fp, "pHYs",
|
||||
chunk(fp, b"pHYs",
|
||||
o32(int(dpi[0] / 0.0254 + 0.5)),
|
||||
o32(int(dpi[1] / 0.0254 + 0.5)),
|
||||
chr(1))
|
||||
b'\x01')
|
||||
|
||||
info = im.encoderinfo.get("pnginfo")
|
||||
if info:
|
||||
|
@ -568,13 +581,13 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
p = ICCProfile.ICCProfile(im.info["icc_profile"])
|
||||
name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79]
|
||||
except ImportError:
|
||||
name = "ICC Profile"
|
||||
data = name + "\0\0" + zlib.compress(im.info["icc_profile"])
|
||||
chunk(fp, "iCCP", data)
|
||||
name = b"ICC Profile"
|
||||
data = name + b"\0\0" + zlib.compress(im.info["icc_profile"])
|
||||
chunk(fp, b"iCCP", data)
|
||||
|
||||
ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)])
|
||||
|
||||
chunk(fp, "IEND", "")
|
||||
chunk(fp, b"IEND", b"")
|
||||
|
||||
try:
|
||||
fp.flush()
|
||||
|
@ -596,7 +609,7 @@ def getchunks(im, **params):
|
|||
self.data.append(chunk)
|
||||
|
||||
def append(fp, cid, *data):
|
||||
data = "".join(data)
|
||||
data = b"".join(data)
|
||||
hi, lo = Image.core.crc32(data, Image.core.crc32(cid))
|
||||
crc = o16(hi) + o16(lo)
|
||||
fp.append((cid, data, crc))
|
||||
|
|
|
@ -24,21 +24,23 @@ from . import Image, ImageFile
|
|||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
b_whitespace = string.whitespace.encode()
|
||||
|
||||
MODES = {
|
||||
# standard
|
||||
"P4": "1",
|
||||
"P5": "L",
|
||||
"P6": "RGB",
|
||||
b"P4": "1",
|
||||
b"P5": "L",
|
||||
b"P6": "RGB",
|
||||
# extensions
|
||||
"P0CMYK": "CMYK",
|
||||
b"P0CMYK": "CMYK",
|
||||
# PIL extensions (for test purposes only)
|
||||
"PyP": "P",
|
||||
"PyRGBA": "RGBA",
|
||||
"PyCMYK": "CMYK"
|
||||
b"PyP": "P",
|
||||
b"PyRGBA": "RGBA",
|
||||
b"PyCMYK": "CMYK"
|
||||
}
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0] == "P" and prefix[1] in "0456y"
|
||||
return prefix[0:1] == b"P" and prefix[1] in b"0456y"
|
||||
|
||||
##
|
||||
# Image plugin for PBM, PGM, and PPM images.
|
||||
|
@ -48,10 +50,10 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
format = "PPM"
|
||||
format_description = "Pbmplus image"
|
||||
|
||||
def _token(self, s = ""):
|
||||
def _token(self, s = b""):
|
||||
while True: # read until next whitespace
|
||||
c = self.fp.read(1)
|
||||
if not c or c in string.whitespace:
|
||||
if not c or c in b_whitespace:
|
||||
break
|
||||
s = s + c
|
||||
return s
|
||||
|
@ -60,7 +62,7 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
|
||||
# check magic
|
||||
s = self.fp.read(1)
|
||||
if s != "P":
|
||||
if s != b"P":
|
||||
raise SyntaxError("not a PPM file")
|
||||
mode = MODES[self._token(s)]
|
||||
|
||||
|
@ -74,9 +76,9 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
while True:
|
||||
while True:
|
||||
s = self.fp.read(1)
|
||||
if s not in string.whitespace:
|
||||
if s not in b_whitespace:
|
||||
break
|
||||
if s != "#":
|
||||
if s != b"#":
|
||||
break
|
||||
s = self.fp.readline()
|
||||
s = int(self._token(s))
|
||||
|
@ -103,18 +105,18 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
|
||||
def _save(im, fp, filename):
|
||||
if im.mode == "1":
|
||||
rawmode, head = "1;I", "P4"
|
||||
rawmode, head = "1;I", b"P4"
|
||||
elif im.mode == "L":
|
||||
rawmode, head = "L", "P5"
|
||||
rawmode, head = "L", b"P5"
|
||||
elif im.mode == "RGB":
|
||||
rawmode, head = "RGB", "P6"
|
||||
rawmode, head = "RGB", b"P6"
|
||||
elif im.mode == "RGBA":
|
||||
rawmode, head = "RGB", "P6"
|
||||
rawmode, head = "RGB", b"P6"
|
||||
else:
|
||||
raise IOError("cannot write mode %s as PPM" % im.mode)
|
||||
fp.write(head + "\n%d %d\n" % im.size)
|
||||
if head != "P4":
|
||||
fp.write("255\n")
|
||||
fp.write(head + ("\n%d %d\n" % im.size).encode('ascii'))
|
||||
if head != b"P4":
|
||||
fp.write(b"255\n")
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
|
||||
|
||||
# ALTERNATIVE: save via builtin debug function
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
__version__ = "0.4"
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
MODES = {
|
||||
# (photoshop mode, bits) -> (pil mode, required channels)
|
||||
|
@ -36,17 +36,15 @@ MODES = {
|
|||
#
|
||||
# helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
# read PSD images
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "8BPS"
|
||||
return prefix[:4] == b"8BPS"
|
||||
|
||||
##
|
||||
# Image plugin for Photoshop images.
|
||||
|
@ -64,7 +62,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
# header
|
||||
|
||||
s = read(26)
|
||||
if s[:4] != "8BPS" or i16(s[4:]) != 1:
|
||||
if s[:4] != b"8BPS" or i16(s[4:]) != 1:
|
||||
raise SyntaxError("not a PSD file")
|
||||
|
||||
psd_bits = i16(s[22:])
|
||||
|
@ -100,7 +98,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
while self.fp.tell() < end:
|
||||
signature = read(4)
|
||||
id = i16(read(2))
|
||||
name = read(ord(read(1)))
|
||||
name = read(i8(read(1)))
|
||||
if not (len(name) & 1):
|
||||
read(1) # padding
|
||||
data = read(i32(read(4)))
|
||||
|
@ -219,9 +217,10 @@ def _layerinfo(file):
|
|||
file.seek(length, 1)
|
||||
combined += length + 4
|
||||
|
||||
length = ord(read(1))
|
||||
length = i8(read(1))
|
||||
if length:
|
||||
name = read(length)
|
||||
# Don't know the proper encoding, Latin-1 should be a good guess
|
||||
name = read(length).decode('latin-1', 'replace')
|
||||
combined += length + 1
|
||||
|
||||
file.seek(size - combined, 1)
|
||||
|
|
|
@ -21,14 +21,11 @@
|
|||
__version__ = "0.2"
|
||||
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
|
@ -50,10 +47,10 @@ class SgiImageFile(ImageFile.ImageFile):
|
|||
raise SyntaxError("not an SGI image file")
|
||||
|
||||
# relevant header entries
|
||||
compression = ord(s[2])
|
||||
compression = i8(s[2])
|
||||
|
||||
# bytes, dimension, zsize
|
||||
layout = ord(s[3]), i16(s[4:]), i16(s[10:])
|
||||
layout = i8(s[3]), i16(s[4:]), i16(s[10:])
|
||||
|
||||
# determine mode from bytes/zsize
|
||||
if layout == (1, 2, 1) or layout == (1, 1, 1):
|
||||
|
|
|
@ -20,14 +20,10 @@
|
|||
__version__ = "0.3"
|
||||
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
|
@ -71,7 +67,7 @@ class SunImageFile(ImageFile.ImageFile):
|
|||
if self.mode == "L":
|
||||
self.mode = rawmode = "P"
|
||||
|
||||
stride = (((self.size[0] * depth + 7) / 8) + 3) & (~3)
|
||||
stride = (((self.size[0] * depth + 7) // 8) + 3) & (~3)
|
||||
|
||||
if compression == 1:
|
||||
self.tile = [("raw", (0,0)+self.size, offset, (rawmode, stride))]
|
||||
|
|
|
@ -38,8 +38,8 @@ class TarIO(ContainerIO.ContainerIO):
|
|||
if len(s) != 512:
|
||||
raise IOError("unexpected end of tar file")
|
||||
|
||||
name = s[:100]
|
||||
i = name.find(chr(0))
|
||||
name = s[:100].decode('utf-8')
|
||||
i = name.find(b'\0')
|
||||
if i == 0:
|
||||
raise IOError("cannot find subfile")
|
||||
if i > 0:
|
||||
|
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
__version__ = "0.3"
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read RGA file
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
MODES = {
|
||||
|
@ -45,7 +43,7 @@ MODES = {
|
|||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0] == "\0"
|
||||
return prefix[0:1] == b"\0"
|
||||
|
||||
##
|
||||
# Image plugin for Targa files.
|
||||
|
@ -60,14 +58,14 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
# process header
|
||||
s = self.fp.read(18)
|
||||
|
||||
id = ord(s[0])
|
||||
id = i8(s[0])
|
||||
|
||||
colormaptype = ord(s[1])
|
||||
imagetype = ord(s[2])
|
||||
colormaptype = i8(s[1])
|
||||
imagetype = i8(s[2])
|
||||
|
||||
depth = ord(s[16])
|
||||
depth = i8(s[16])
|
||||
|
||||
flags = ord(s[17])
|
||||
flags = i8(s[17])
|
||||
|
||||
self.size = i16(s[12:]), i16(s[14:])
|
||||
|
||||
|
@ -110,13 +108,13 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
start, size, mapdepth = i16(s[3:]), i16(s[5:]), i16(s[7:])
|
||||
if mapdepth == 16:
|
||||
self.palette = ImagePalette.raw("BGR;16",
|
||||
"\0"*2*start + self.fp.read(2*size))
|
||||
b"\0"*2*start + self.fp.read(2*size))
|
||||
elif mapdepth == 24:
|
||||
self.palette = ImagePalette.raw("BGR",
|
||||
"\0"*3*start + self.fp.read(3*size))
|
||||
b"\0"*3*start + self.fp.read(3*size))
|
||||
elif mapdepth == 32:
|
||||
self.palette = ImagePalette.raw("BGRA",
|
||||
"\0"*4*start + self.fp.read(4*size))
|
||||
b"\0"*4*start + self.fp.read(4*size))
|
||||
|
||||
# setup tile descriptor
|
||||
try:
|
||||
|
@ -135,11 +133,8 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
# --------------------------------------------------------------------
|
||||
# Write TGA file
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
o16 = _binary.o16le
|
||||
o32 = _binary.o32le
|
||||
|
||||
SAVE = {
|
||||
"1": ("1", 1, 0, 3),
|
||||
|
@ -173,18 +168,18 @@ def _save(im, fp, filename, check=0):
|
|||
if orientation > 0:
|
||||
flags = flags | 0x20
|
||||
|
||||
fp.write("\000" +
|
||||
chr(colormaptype) +
|
||||
chr(imagetype) +
|
||||
fp.write(b"\000" +
|
||||
o8(colormaptype) +
|
||||
o8(imagetype) +
|
||||
o16(colormapfirst) +
|
||||
o16(colormaplength) +
|
||||
chr(colormapentry) +
|
||||
o8(colormapentry) +
|
||||
o16(0) +
|
||||
o16(0) +
|
||||
o16(im.size[0]) +
|
||||
o16(im.size[1]) +
|
||||
chr(bits) +
|
||||
chr(flags))
|
||||
o8(bits) +
|
||||
o8(flags))
|
||||
|
||||
if colormaptype:
|
||||
fp.write(im.im.getpalette("RGB", "BGR"))
|
||||
|
|
|
@ -45,46 +45,36 @@ __version__ = "1.3.5"
|
|||
|
||||
from . import Image, ImageFile
|
||||
from . import ImagePalette
|
||||
from . import _binary
|
||||
|
||||
import array, sys
|
||||
import collections
|
||||
import itertools
|
||||
|
||||
II = "II" # little-endian (intel-style)
|
||||
MM = "MM" # big-endian (motorola-style)
|
||||
II = b"II" # little-endian (intel-style)
|
||||
MM = b"MM" # big-endian (motorola-style)
|
||||
|
||||
try:
|
||||
if sys.byteorder == "little":
|
||||
native_prefix = II
|
||||
else:
|
||||
native_prefix = MM
|
||||
except AttributeError:
|
||||
if ord(array.array("i",[1]).tostring()[0]):
|
||||
native_prefix = II
|
||||
else:
|
||||
native_prefix = MM
|
||||
i8 = _binary.i8
|
||||
o8 = _binary.o8
|
||||
|
||||
if sys.byteorder == "little":
|
||||
native_prefix = II
|
||||
else:
|
||||
native_prefix = MM
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read TIFF files
|
||||
|
||||
def il16(c,o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8)
|
||||
def il32(c,o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24)
|
||||
def ol16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
def ol32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
il16 = _binary.i16le
|
||||
il32 = _binary.i32le
|
||||
ol16 = _binary.o16le
|
||||
ol32 = _binary.o32le
|
||||
|
||||
def ib16(c,o=0):
|
||||
return ord(c[o+1]) + (ord(c[o])<<8)
|
||||
def ib32(c,o=0):
|
||||
return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
|
||||
def ob16(i):
|
||||
return chr(i>>8&255) + chr(i&255)
|
||||
def ob32(i):
|
||||
return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255)
|
||||
ib16 = _binary.i16be
|
||||
ib32 = _binary.i32be
|
||||
ob16 = _binary.o16be
|
||||
ob32 = _binary.o32be
|
||||
|
||||
# a few tag names, just to make the code below a bit more readable
|
||||
IMAGEWIDTH = 256
|
||||
|
@ -200,7 +190,7 @@ OPEN_INFO = {
|
|||
|
||||
}
|
||||
|
||||
PREFIXES = ["MM\000\052", "II\052\000", "II\xBC\000"]
|
||||
PREFIXES = [b"MM\000\052", b"II\052\000", b"II\xBC\000"]
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] in PREFIXES
|
||||
|
@ -264,7 +254,7 @@ class ImageFileDirectory(collections.MutableMapping):
|
|||
def __contains__(self, tag):
|
||||
return tag in self.tags or tag in self.tagdata
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
if bytes is str:
|
||||
def has_key(self, tag):
|
||||
return tag in self
|
||||
|
||||
|
@ -284,16 +274,13 @@ class ImageFileDirectory(collections.MutableMapping):
|
|||
load_dispatch = {}
|
||||
|
||||
def load_byte(self, data):
|
||||
l = []
|
||||
for i in range(len(data)):
|
||||
l.append(ord(data[i]))
|
||||
return tuple(l)
|
||||
return data
|
||||
load_dispatch[1] = (1, load_byte)
|
||||
|
||||
def load_string(self, data):
|
||||
if data[-1:] == '\0':
|
||||
if data[-1:] == b'\0':
|
||||
data = data[:-1]
|
||||
return data
|
||||
return data.decode('latin-1', 'replace')
|
||||
load_dispatch[2] = (1, load_string)
|
||||
|
||||
def load_short(self, data):
|
||||
|
@ -420,14 +407,14 @@ class ImageFileDirectory(collections.MutableMapping):
|
|||
|
||||
if typ == 1:
|
||||
# byte data
|
||||
data = value = "".join(map(chr, value))
|
||||
data = value
|
||||
elif typ == 7:
|
||||
# untyped data
|
||||
data = value = "".join(value)
|
||||
data = value = b"".join(value)
|
||||
elif isinstance(value[0], str):
|
||||
# string data
|
||||
typ = 2
|
||||
data = value = "\0".join(value) + "\0"
|
||||
data = value = b"\0".join(value.encode('ascii', 'replace')) + b"\0"
|
||||
else:
|
||||
# integer data
|
||||
if tag == STRIPOFFSETS:
|
||||
|
@ -442,9 +429,9 @@ class ImageFileDirectory(collections.MutableMapping):
|
|||
if v >= 65536:
|
||||
typ = 4
|
||||
if typ == 3:
|
||||
data = "".join(map(o16, value))
|
||||
data = b"".join(map(o16, value))
|
||||
else:
|
||||
data = "".join(map(o32, value))
|
||||
data = b"".join(map(o32, value))
|
||||
|
||||
if Image.DEBUG:
|
||||
from . import TiffTags
|
||||
|
@ -460,13 +447,13 @@ class ImageFileDirectory(collections.MutableMapping):
|
|||
|
||||
# figure out if data fits into the directory
|
||||
if len(data) == 4:
|
||||
append((tag, typ, len(value), data, ""))
|
||||
append((tag, typ, len(value), data, b""))
|
||||
elif len(data) < 4:
|
||||
append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
|
||||
append((tag, typ, len(value), data + (4-len(data))*b"\0", b""))
|
||||
else:
|
||||
count = len(value)
|
||||
if typ == 5:
|
||||
count = count / 2 # adjust for rational data field
|
||||
count = count // 2 # adjust for rational data field
|
||||
append((tag, typ, count, o32(offset), data))
|
||||
offset = offset + len(data)
|
||||
if offset & 1:
|
||||
|
@ -486,13 +473,13 @@ class ImageFileDirectory(collections.MutableMapping):
|
|||
fp.write(o16(tag) + o16(typ) + o32(count) + value)
|
||||
|
||||
# -- overwrite here for multi-page --
|
||||
fp.write("\0\0\0\0") # end of directory
|
||||
fp.write(b"\0\0\0\0") # end of directory
|
||||
|
||||
# pass 3: write auxiliary data to file
|
||||
for tag, typ, count, value, data in directory:
|
||||
fp.write(data)
|
||||
if len(data) & 1:
|
||||
fp.write("\0")
|
||||
fp.write(b"\0")
|
||||
|
||||
return offset
|
||||
|
||||
|
@ -702,8 +689,8 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
# fixup palette descriptor
|
||||
|
||||
if self.mode == "P":
|
||||
palette = [chr(a / 256) for a in self.tag[COLORMAP]]
|
||||
self.palette = ImagePalette.raw("RGB;L", "".join(palette))
|
||||
palette = [o8(a // 256) for a in self.tag[COLORMAP]]
|
||||
self.palette = ImagePalette.raw("RGB;L", b"".join(palette))
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Write TIFF files
|
||||
|
@ -824,10 +811,10 @@ def _save(im, fp, filename):
|
|||
|
||||
if im.mode == "P":
|
||||
lut = im.im.getpalette("RGB", "RGB;L")
|
||||
ifd[COLORMAP] = tuple(ord(v) * 256 for v in lut)
|
||||
ifd[COLORMAP] = tuple(i8(v) * 256 for v in lut)
|
||||
|
||||
# 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[STRIPBYTECOUNTS] = stride * im.size[1]
|
||||
ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
from __future__ import print_function
|
||||
|
||||
from . import Image
|
||||
from . import Image, _binary
|
||||
|
||||
try:
|
||||
import builtins
|
||||
|
@ -31,8 +31,7 @@ except ImportError:
|
|||
import __builtin__
|
||||
builtins = __builtin__
|
||||
|
||||
def i32(c, o=0):
|
||||
return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
|
||||
i32 = _binary.i32le
|
||||
|
||||
##
|
||||
# Load texture from a Quake2 WAL texture file.
|
||||
|
@ -60,15 +59,15 @@ def open(filename):
|
|||
# load pixel data
|
||||
fp.seek(offset)
|
||||
|
||||
im = Image.fromstring("P", size, fp.read(size[0] * size[1]))
|
||||
im = Image.frombytes("P", size, fp.read(size[0] * size[1]))
|
||||
im.putpalette(quake2palette)
|
||||
|
||||
im.format = "WAL"
|
||||
im.format_description = "Quake2 Texture"
|
||||
|
||||
# strings are null-terminated
|
||||
im.info["name"] = header[:32].split("\0", 1)[0]
|
||||
next_name = header[56:56+32].split("\0", 1)[0]
|
||||
im.info["name"] = header[:32].split(b"\0", 1)[0]
|
||||
next_name = header[56:56+32].split(b"\0", 1)[0]
|
||||
if next_name:
|
||||
im.info["next_name"] = next_name
|
||||
|
||||
|
@ -77,54 +76,54 @@ def open(filename):
|
|||
|
||||
quake2palette = (
|
||||
# default palette taken from piffo 0.93 by Hans Häggström
|
||||
"\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e"
|
||||
"\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f"
|
||||
"\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c"
|
||||
"\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b"
|
||||
"\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10"
|
||||
"\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07"
|
||||
"\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f"
|
||||
"\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16"
|
||||
"\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d"
|
||||
"\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31"
|
||||
"\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28"
|
||||
"\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07"
|
||||
"\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27"
|
||||
"\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b"
|
||||
"\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01"
|
||||
"\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21"
|
||||
"\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14"
|
||||
"\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07"
|
||||
"\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14"
|
||||
"\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f"
|
||||
"\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34"
|
||||
"\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d"
|
||||
"\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14"
|
||||
"\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01"
|
||||
"\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24"
|
||||
"\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10"
|
||||
"\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01"
|
||||
"\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27"
|
||||
"\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c"
|
||||
"\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a"
|
||||
"\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26"
|
||||
"\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d"
|
||||
"\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01"
|
||||
"\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20"
|
||||
"\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17"
|
||||
"\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07"
|
||||
"\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25"
|
||||
"\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c"
|
||||
"\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01"
|
||||
"\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23"
|
||||
"\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f"
|
||||
"\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b"
|
||||
"\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37"
|
||||
"\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b"
|
||||
"\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01"
|
||||
"\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10"
|
||||
"\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b"
|
||||
"\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20"
|
||||
b"\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e"
|
||||
b"\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f"
|
||||
b"\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c"
|
||||
b"\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b"
|
||||
b"\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10"
|
||||
b"\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07"
|
||||
b"\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f"
|
||||
b"\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16"
|
||||
b"\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d"
|
||||
b"\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31"
|
||||
b"\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28"
|
||||
b"\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07"
|
||||
b"\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27"
|
||||
b"\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b"
|
||||
b"\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01"
|
||||
b"\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21"
|
||||
b"\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14"
|
||||
b"\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07"
|
||||
b"\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14"
|
||||
b"\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f"
|
||||
b"\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34"
|
||||
b"\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d"
|
||||
b"\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14"
|
||||
b"\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01"
|
||||
b"\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24"
|
||||
b"\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10"
|
||||
b"\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01"
|
||||
b"\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27"
|
||||
b"\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c"
|
||||
b"\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a"
|
||||
b"\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26"
|
||||
b"\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d"
|
||||
b"\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01"
|
||||
b"\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20"
|
||||
b"\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17"
|
||||
b"\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07"
|
||||
b"\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25"
|
||||
b"\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c"
|
||||
b"\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01"
|
||||
b"\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23"
|
||||
b"\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f"
|
||||
b"\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b"
|
||||
b"\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37"
|
||||
b"\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b"
|
||||
b"\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01"
|
||||
b"\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10"
|
||||
b"\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b"
|
||||
b"\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
__version__ = "0.2"
|
||||
|
||||
from . import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
_handler = None
|
||||
|
||||
|
@ -44,7 +44,7 @@ if hasattr(Image.core, "drawwmf"):
|
|||
|
||||
def load(self, im):
|
||||
im.fp.seek(0) # rewind
|
||||
return Image.fromstring(
|
||||
return Image.frombytes(
|
||||
"RGB", im.size,
|
||||
Image.core.drawwmf(im.fp.read(), im.size, self.bbox),
|
||||
"raw", "BGR", (im.size[0]*3 + 3) & -4, -1
|
||||
|
@ -54,20 +54,15 @@ if hasattr(Image.core, "drawwmf"):
|
|||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def word(c, o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8)
|
||||
word = _binary.i16le
|
||||
|
||||
def short(c, o=0):
|
||||
v = ord(c[o]) + (ord(c[o+1])<<8)
|
||||
v = word(c, o)
|
||||
if v >= 32768:
|
||||
v = v - 65536
|
||||
return v
|
||||
|
||||
def dword(c, o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24)
|
||||
|
||||
def long(c, o=0):
|
||||
return dword(c, o)
|
||||
dword = _binary.i32le
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -75,8 +70,8 @@ def long(c, o=0):
|
|||
|
||||
def _accept(prefix):
|
||||
return (
|
||||
prefix[:6] == "\xd7\xcd\xc6\x9a\x00\x00" or
|
||||
prefix[:4] == "\x01\x00\x00\x00"
|
||||
prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or
|
||||
prefix[:4] == b"\x01\x00\x00\x00"
|
||||
)
|
||||
|
||||
##
|
||||
|
@ -92,7 +87,7 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
|||
# check placable header
|
||||
s = self.fp.read(80)
|
||||
|
||||
if s[:6] == "\xd7\xcd\xc6\x9a\x00\x00":
|
||||
if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00":
|
||||
|
||||
# placeable windows metafile
|
||||
|
||||
|
@ -104,7 +99,7 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
|||
x1 = short(s, 10); y1 = short(s, 12)
|
||||
|
||||
# normalize size to 72 dots per inch
|
||||
size = (x1 - x0) * 72 / inch, (y1 - y0) * 72 / inch
|
||||
size = (x1 - x0) * 72 // inch, (y1 - y0) * 72 // inch
|
||||
|
||||
self.info["wmf_bbox"] = x0, y0, x1, y1
|
||||
|
||||
|
@ -113,25 +108,25 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
|||
# print self.mode, self.size, self.info
|
||||
|
||||
# sanity check (standard metafile header)
|
||||
if s[22:26] != "\x01\x00\t\x00":
|
||||
if s[22:26] != b"\x01\x00\t\x00":
|
||||
raise SyntaxError("Unsupported WMF file format")
|
||||
|
||||
elif long(s) == 1 and s[40:44] == " EMF":
|
||||
elif dword(s) == 1 and s[40:44] == b" EMF":
|
||||
# enhanced metafile
|
||||
|
||||
# get bounding box
|
||||
x0 = long(s, 8); y0 = long(s, 12)
|
||||
x1 = long(s, 16); y1 = long(s, 20)
|
||||
x0 = dword(s, 8); y0 = dword(s, 12)
|
||||
x1 = dword(s, 16); y1 = dword(s, 20)
|
||||
|
||||
# get frame (in 0.01 millimeter units)
|
||||
frame = long(s, 24), long(s, 28), long(s, 32), long(s, 36)
|
||||
frame = dword(s, 24), dword(s, 28), dword(s, 32), dword(s, 36)
|
||||
|
||||
# normalize size to 72 dots per inch
|
||||
size = x1 - x0, y1 - y0
|
||||
|
||||
# calculate dots per inch from bbox and frame
|
||||
xdpi = 2540 * (x1 - y0) / (frame[2] - frame[0])
|
||||
ydpi = 2540 * (y1 - y0) / (frame[3] - frame[1])
|
||||
xdpi = 2540 * (x1 - y0) // (frame[2] - frame[0])
|
||||
ydpi = 2540 * (y1 - y0) // (frame[3] - frame[1])
|
||||
|
||||
self.info["wmf_bbox"] = x0, y0, x1, y1
|
||||
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
o8 = _binary.o8
|
||||
|
||||
# standard color palette for thumbnails (RGB332)
|
||||
PALETTE = ""
|
||||
PALETTE = b""
|
||||
for r in range(8):
|
||||
for g in range(8):
|
||||
for b in range(4):
|
||||
PALETTE = PALETTE + (chr((r*255)/7)+chr((g*255)/7)+chr((b*255)/3))
|
||||
PALETTE = PALETTE + (o8((r*255)//7)+o8((g*255)//7)+o8((b*255)//3))
|
||||
|
||||
##
|
||||
# Image plugin for XV thumbnail images.
|
||||
|
@ -40,7 +42,7 @@ class XVThumbImageFile(ImageFile.ImageFile):
|
|||
|
||||
# check magic
|
||||
s = self.fp.read(6)
|
||||
if s != "P7 332":
|
||||
if s != b"P7 332":
|
||||
raise SyntaxError("not an XV thumbnail file")
|
||||
|
||||
# Skip to beginning of next line
|
||||
|
@ -51,14 +53,14 @@ class XVThumbImageFile(ImageFile.ImageFile):
|
|||
s = self.fp.readline()
|
||||
if not s:
|
||||
raise SyntaxError("Unexpected EOF reading XV thumbnail file")
|
||||
if s[0] != '#':
|
||||
if s[0] != b'#':
|
||||
break
|
||||
|
||||
# parse header line (already read)
|
||||
s = s.strip().split()
|
||||
|
||||
self.mode = "P"
|
||||
self.size = int(s[0]), int(s[1])
|
||||
self.size = int(s[0:1]), int(s[1:2])
|
||||
|
||||
self.palette = ImagePalette.raw("RGB", PALETTE)
|
||||
|
||||
|
|
|
@ -26,17 +26,17 @@ from . import Image, ImageFile
|
|||
|
||||
# XBM header
|
||||
xbm_head = re.compile(
|
||||
"\s*#define[ \t]+[^_]*_width[ \t]+(?P<width>[0-9]+)[\r\n]+"
|
||||
"#define[ \t]+[^_]*_height[ \t]+(?P<height>[0-9]+)[\r\n]+"
|
||||
"(?P<hotspot>"
|
||||
"#define[ \t]+[^_]*_x_hot[ \t]+(?P<xhot>[0-9]+)[\r\n]+"
|
||||
"#define[ \t]+[^_]*_y_hot[ \t]+(?P<yhot>[0-9]+)[\r\n]+"
|
||||
")?"
|
||||
"[\\000-\\377]*_bits\\[\\]"
|
||||
b"\s*#define[ \t]+[^_]*_width[ \t]+(?P<width>[0-9]+)[\r\n]+"
|
||||
b"#define[ \t]+[^_]*_height[ \t]+(?P<height>[0-9]+)[\r\n]+"
|
||||
b"(?P<hotspot>"
|
||||
b"#define[ \t]+[^_]*_x_hot[ \t]+(?P<xhot>[0-9]+)[\r\n]+"
|
||||
b"#define[ \t]+[^_]*_y_hot[ \t]+(?P<yhot>[0-9]+)[\r\n]+"
|
||||
b")?"
|
||||
b"[\\000-\\377]*_bits\\[\\]"
|
||||
)
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix.lstrip()[:7] == "#define"
|
||||
return prefix.lstrip()[:7] == b"#define"
|
||||
|
||||
##
|
||||
# Image plugin for X11 bitmaps.
|
||||
|
@ -71,19 +71,19 @@ def _save(im, fp, filename):
|
|||
if im.mode != "1":
|
||||
raise IOError("cannot write mode %s as XBM" % im.mode)
|
||||
|
||||
fp.write("#define im_width %d\n" % im.size[0])
|
||||
fp.write("#define im_height %d\n" % im.size[1])
|
||||
fp.write(("#define im_width %d\n" % im.size[0]).encode('ascii'))
|
||||
fp.write(("#define im_height %d\n" % im.size[1]).encode('ascii'))
|
||||
|
||||
hotspot = im.encoderinfo.get("hotspot")
|
||||
if hotspot:
|
||||
fp.write("#define im_x_hot %d\n" % hotspot[0])
|
||||
fp.write("#define im_y_hot %d\n" % hotspot[1])
|
||||
fp.write(("#define im_x_hot %d\n" % hotspot[0]).encode('ascii'))
|
||||
fp.write(("#define im_y_hot %d\n" % hotspot[1]).encode('ascii'))
|
||||
|
||||
fp.write("static char im_bits[] = {\n")
|
||||
fp.write(b"static char im_bits[] = {\n")
|
||||
|
||||
ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)])
|
||||
|
||||
fp.write("};\n")
|
||||
fp.write(b"};\n")
|
||||
|
||||
|
||||
Image.register_open("XBM", XbmImageFile, _accept)
|
||||
|
|
|
@ -20,13 +20,14 @@ __version__ = "0.2"
|
|||
|
||||
import re
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from ._binary import i8, o8
|
||||
|
||||
# XPM header
|
||||
xpm_head = re.compile("\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
|
||||
xpm_head = re.compile(b"\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:9] == "/* XPM */"
|
||||
return prefix[:9] == b"/* XPM */"
|
||||
|
||||
##
|
||||
# Image plugin for X11 pixel maps.
|
||||
|
@ -61,17 +62,17 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
#
|
||||
# load palette description
|
||||
|
||||
palette = ["\0\0\0"] * 256
|
||||
palette = [b"\0\0\0"] * 256
|
||||
|
||||
for i in range(pal):
|
||||
|
||||
s = self.fp.readline()
|
||||
if s[-2:] == '\r\n':
|
||||
if s[-2:] == b'\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] in '\r\n':
|
||||
elif s[-1:] in b'\r\n':
|
||||
s = s[:-1]
|
||||
|
||||
c = ord(s[1])
|
||||
c = i8(s[1])
|
||||
s = s[2:-2].split()
|
||||
|
||||
for i in range(0, len(s), 2):
|
||||
|
@ -80,14 +81,14 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
|
||||
# process colour key
|
||||
rgb = s[i+1]
|
||||
if rgb == "None":
|
||||
if rgb == b"None":
|
||||
self.info["transparency"] = c
|
||||
elif rgb[0] == "#":
|
||||
elif rgb[0] == b"#":
|
||||
# FIXME: handle colour names (see ImagePalette.py)
|
||||
rgb = int(rgb[1:], 16)
|
||||
palette[c] = chr((rgb >> 16) & 255) +\
|
||||
chr((rgb >> 8) & 255) +\
|
||||
chr(rgb & 255)
|
||||
palette[c] = o8((rgb >> 16) & 255) +\
|
||||
o8((rgb >> 8) & 255) +\
|
||||
o8(rgb & 255)
|
||||
else:
|
||||
# unknown colour
|
||||
raise ValueError("cannot read this XPM file")
|
||||
|
@ -99,7 +100,7 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
raise ValueError("cannot read this XPM file")
|
||||
|
||||
self.mode = "P"
|
||||
self.palette = ImagePalette.raw("RGB", "".join(palette))
|
||||
self.palette = ImagePalette.raw("RGB", b"".join(palette))
|
||||
|
||||
self.tile = [("raw", (0, 0)+self.size, self.fp.tell(), ("P", 0, 1))]
|
||||
|
||||
|
@ -117,7 +118,7 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.fp = None
|
||||
|
||||
return "".join(s)
|
||||
return b"".join(s)
|
||||
|
||||
#
|
||||
# Registry
|
||||
|
|
52
PIL/_binary.py
Normal file
52
PIL/_binary.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# Binary input/output support routines.
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB
|
||||
# Copyright (c) 1995-2003 by Fredrik Lundh
|
||||
# Copyright (c) 2012 by Brian Crowell
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
if bytes is str:
|
||||
def i8(c):
|
||||
return ord(c)
|
||||
|
||||
def o8(i):
|
||||
return chr(i&255)
|
||||
else:
|
||||
def i8(c):
|
||||
return c if c.__class__ is int else c[0]
|
||||
|
||||
def o8(i):
|
||||
return bytes((i&255,))
|
||||
|
||||
# Input, le = little endian, be = big endian
|
||||
def i16le(c, o=0):
|
||||
return i8(c[o]) | (i8(c[o+1])<<8)
|
||||
|
||||
def i32le(c, o=0):
|
||||
return i8(c[o]) | (i8(c[o+1])<<8) | (i8(c[o+2])<<16) | (i8(c[o+3])<<24)
|
||||
|
||||
def i16be(c, o=0):
|
||||
return (i8(c[o])<<8) | i8(c[o+1])
|
||||
|
||||
def i32be(c, o=0):
|
||||
return (i8(c[o])<<24) | (i8(c[o+1])<<16) | (i8(c[o+2])<<8) | i8(c[o+3])
|
||||
|
||||
# Output, le = little endian, be = big endian
|
||||
def o16le(i):
|
||||
return o8(i) + o8(i>>8)
|
||||
|
||||
def o32le(i):
|
||||
return o8(i) + o8(i>>8) + o8(i>>16) + o8(i>>24)
|
||||
|
||||
def o16be(i):
|
||||
return o8(i>>8) + o8(i)
|
||||
|
||||
def o32be(i):
|
||||
return o8(i>>24) + o8(i>>16) + o8(i>>8) + o8(i)
|
||||
|
|
@ -16,13 +16,13 @@ import Image
|
|||
def toImage(arr):
|
||||
if arr.type().bytes == 1:
|
||||
# need to swap coordinates btw array and image (with [::-1])
|
||||
im = Image.fromstring('L', arr.shape[::-1], arr.tostring())
|
||||
im = Image.frombytes('L', arr.shape[::-1], arr.tostring())
|
||||
else:
|
||||
arr_c = arr - arr.min()
|
||||
arr_c *= (255./arr_c.max())
|
||||
arr = arr_c.astype(UInt8)
|
||||
# need to swap coordinates btw array and image (with [::-1])
|
||||
im = Image.fromstring('L', arr.shape[::-1], arr.tostring())
|
||||
im = Image.frombytes('L', arr.shape[::-1], arr.tostring())
|
||||
return im
|
||||
|
||||
print('SANE version:', sane.init())
|
||||
|
|
|
@ -88,16 +88,16 @@ def test_bad_text():
|
|||
assert_equal(im.info, {})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam') + TAIL)
|
||||
assert_equal(im.info, {b'spam': b''})
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam\0') + TAIL)
|
||||
assert_equal(im.info, {b'spam': b''})
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam\0egg') + TAIL)
|
||||
assert_equal(im.info, {b'spam': b'egg'})
|
||||
assert_equal(im.info, {'spam': 'egg'})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam\0egg\0') + TAIL)
|
||||
assert_equal(im.info, {b'spam': b'egg\x00'})
|
||||
assert_equal(im.info, {'spam': 'egg\x00'})
|
||||
|
||||
def test_interlace():
|
||||
|
||||
|
@ -141,12 +141,12 @@ def test_roundtrip_text():
|
|||
im = Image.open(file)
|
||||
|
||||
info = PngImagePlugin.PngInfo()
|
||||
info.add_text(b"TXT", b"VALUE")
|
||||
info.add_text(b"ZIP", b"VALUE", 1)
|
||||
info.add_text("TXT", "VALUE")
|
||||
info.add_text("ZIP", "VALUE", 1)
|
||||
|
||||
im = roundtrip(im, pnginfo=info)
|
||||
assert_equal(im.info, {b'TXT': b'VALUE', b'ZIP': b'VALUE'})
|
||||
assert_equal(im.text, {b'TXT': b'VALUE', b'ZIP': b'VALUE'})
|
||||
assert_equal(im.info, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||
assert_equal(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||
|
||||
def test_scary():
|
||||
# Check reading of evil PNG file. For information, see:
|
||||
|
|
|
@ -33,11 +33,11 @@ The PIL.Image Module
|
|||
|
||||
**frombuffer(mode, size, data, decoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.frombuffer-function>`_]
|
||||
(New in 1.1.4) Creates an image memory from pixel data in a string
|
||||
or byte buffer.
|
||||
(New in 1.1.4) Creates an image memory referencing pixel data in a
|
||||
byte buffer.
|
||||
|
||||
This function is similar to
|
||||
`**fromstring** <#PIL.Image.fromstring-function>`_, but uses data in
|
||||
`**frombytes** <#PIL.Image.frombytes-function>`_, but uses data in
|
||||
the byte buffer, where possible. This means that changes to the
|
||||
original buffer object are reflected in this image). Not all modes
|
||||
can share memory; support modes include "L", "RGBX", "RGBA", and
|
||||
|
@ -56,9 +56,9 @@ The PIL.Image Module
|
|||
*\*args*
|
||||
Returns:
|
||||
|
||||
**fromstring(mode, size, data, decoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.fromstring-function>`_]
|
||||
Creates an image memory from pixel data in a string.
|
||||
**frombytes(mode, size, data, decoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.frombytes-function>`_]
|
||||
Creates a copy of an image memory from pixel data in a buffer.
|
||||
|
||||
In its simplest form, this function takes three arguments (mode,
|
||||
size, and unpacked pixel data).
|
||||
|
@ -233,14 +233,16 @@ The Image Class
|
|||
*filter*
|
||||
Returns:
|
||||
|
||||
**fromstring(data, decoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.Image.fromstring-method>`_]
|
||||
Loads this image with pixel data from a string.
|
||||
**frombytes(data, decoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.Image.frombytes-method>`_]
|
||||
Loads this image with pixel data from a byte uffer.
|
||||
|
||||
This method is similar to the
|
||||
`**fromstring** <#PIL.Image.fromstring-function>`_ function, but
|
||||
`**frombytes** <#PIL.Image.frombytes-function>`_ function, but
|
||||
loads data into this image instead of creating a new image object.
|
||||
|
||||
(In Python 2.6 and 2.7, this is also available as fromstring().)
|
||||
|
||||
**getbands()** [`# <#PIL.Image.Image.getbands-method>`_]
|
||||
Returns a tuple containing the name of each band in this image. For
|
||||
example, **getbands** on an RGB image returns ("R", "G", "B").
|
||||
|
@ -516,8 +518,9 @@ The Image Class
|
|||
Returns:
|
||||
Raises **ValueError**:
|
||||
|
||||
**tostring(encoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.Image.tostring-method>`_]
|
||||
**tobytes(encoder\_name="raw", \*args)**
|
||||
[`# <#PIL.Image.Image.tobytes-method>`_]
|
||||
(In Python 2.6 and 2.7, this is also available as tostring().)
|
||||
|
||||
*encoder\_name*
|
||||
*\*args*
|
||||
|
|
|
@ -58,11 +58,12 @@ The Dib Class
|
|||
instance. In PythonWin, you can use the **GetHandleAttrib**
|
||||
method of the **CDC** class to get a suitable handle.
|
||||
|
||||
**fromstring(buffer)** [`# <#PIL.ImageWin.Dib.fromstring-method>`_]
|
||||
**frombytes(buffer)** [`# <#PIL.ImageWin.Dib.frombytes-method>`_]
|
||||
(For Python 2.6/2.7, this is also available as fromstring(buffer).)
|
||||
|
||||
*buffer*
|
||||
A string buffer containing display data (usually data returned
|
||||
from **tostring**)
|
||||
A byte buffer containing display data (usually data returned
|
||||
from **tobytes**)
|
||||
|
||||
**paste(im, box=None)** [`# <#PIL.ImageWin.Dib.paste-method>`_]
|
||||
|
||||
|
@ -82,7 +83,7 @@ The Dib Class
|
|||
*handle*
|
||||
Returns:
|
||||
|
||||
**tostring()** [`# <#PIL.ImageWin.Dib.tostring-method>`_]
|
||||
**tobytes()** [`# <#PIL.ImageWin.Dib.tobytes-method>`_]
|
||||
|
||||
Returns:
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user