mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 02:16:19 +03:00
Moved decoder names out of MODES
This commit is contained in:
parent
0215175e1d
commit
073acd4c82
|
@ -51,35 +51,45 @@ def test_pnm(tmp_path):
|
||||||
|
|
||||||
|
|
||||||
def test_plain_pbm(tmp_path):
|
def test_plain_pbm(tmp_path):
|
||||||
|
# P1
|
||||||
with Image.open("Tests/images/hopper_1bit_plain.pbm") as im:
|
with Image.open("Tests/images/hopper_1bit_plain.pbm") as im:
|
||||||
|
# P4
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper_1bit.pbm")
|
assert_image_equal_tofile(im, "Tests/images/hopper_1bit.pbm")
|
||||||
|
|
||||||
|
|
||||||
def test_8bit_plain_pgm(tmp_path):
|
def test_8bit_plain_pgm(tmp_path):
|
||||||
|
# P2
|
||||||
with Image.open("Tests/images/hopper_8bit_plain.pgm") as im:
|
with Image.open("Tests/images/hopper_8bit_plain.pgm") as im:
|
||||||
|
# P5
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper_8bit.pgm")
|
assert_image_equal_tofile(im, "Tests/images/hopper_8bit.pgm")
|
||||||
|
|
||||||
|
|
||||||
def test_8bit_plain_ppm(tmp_path):
|
def test_8bit_plain_ppm(tmp_path):
|
||||||
|
# P3
|
||||||
with Image.open("Tests/images/hopper_8bit_plain.ppm") as im:
|
with Image.open("Tests/images/hopper_8bit_plain.ppm") as im:
|
||||||
|
# P6
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper_8bit.ppm")
|
assert_image_equal_tofile(im, "Tests/images/hopper_8bit.ppm")
|
||||||
|
|
||||||
|
|
||||||
def test_16bit_plain_pgm(tmp_path):
|
def test_16bit_plain_pgm(tmp_path):
|
||||||
|
# P2 with maxval 2 ** 16 - 1
|
||||||
with Image.open("Tests/images/hopper_16bit_plain.pgm") as im:
|
with Image.open("Tests/images/hopper_16bit_plain.pgm") as im:
|
||||||
assert im.mode == "I"
|
assert im.mode == "I"
|
||||||
assert im.size == (128, 128)
|
assert im.size == (128, 128)
|
||||||
assert im.get_format_mimetype() == "image/x-portable-graymap"
|
assert im.get_format_mimetype() == "image/x-portable-graymap"
|
||||||
|
|
||||||
|
# P5 with maxval 2 ** 16 - 1
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper_16bit.pgm")
|
assert_image_equal_tofile(im, "Tests/images/hopper_16bit.pgm")
|
||||||
|
|
||||||
|
|
||||||
def test_32bit_plain_pgm(tmp_path):
|
def test_32bit_plain_pgm(tmp_path):
|
||||||
|
# P2 with maxval 2 ** 31 - 1
|
||||||
with Image.open("Tests/images/hopper_32bit_plain.pgm") as im:
|
with Image.open("Tests/images/hopper_32bit_plain.pgm") as im:
|
||||||
assert im.mode == "I"
|
assert im.mode == "I"
|
||||||
assert im.size == (128, 128)
|
assert im.size == (128, 128)
|
||||||
assert im.get_format_mimetype() == "image/x-portable-graymap"
|
assert im.get_format_mimetype() == "image/x-portable-graymap"
|
||||||
|
|
||||||
|
# P5 with maxval 2 ** 31 - 1
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper_32bit.pgm")
|
assert_image_equal_tofile(im, "Tests/images/hopper_32bit.pgm")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,20 +23,19 @@ from . import Image, ImageFile
|
||||||
b_whitespace = b"\x20\x09\x0a\x0b\x0c\x0d"
|
b_whitespace = b"\x20\x09\x0a\x0b\x0c\x0d"
|
||||||
|
|
||||||
MODES = {
|
MODES = {
|
||||||
# standard, plain
|
# standard
|
||||||
b"P1": ("ppm_plain", "1"),
|
b"P1": "1",
|
||||||
b"P2": ("ppm_plain", "L"),
|
b"P2": "L",
|
||||||
b"P3": ("ppm_plain", "RGB"),
|
b"P3": "RGB",
|
||||||
# standard, raw
|
b"P4": "1",
|
||||||
b"P4": ("raw", "1"),
|
b"P5": "L",
|
||||||
b"P5": ("raw", "L"),
|
b"P6": "RGB",
|
||||||
b"P6": ("raw", "RGB"),
|
|
||||||
# extensions
|
# extensions
|
||||||
b"P0CMYK": ("raw", "CMYK"),
|
b"P0CMYK": "CMYK",
|
||||||
# PIL extensions (for test purposes only)
|
# PIL extensions (for test purposes only)
|
||||||
b"PyP": ("raw", "P"),
|
b"PyP": "P",
|
||||||
b"PyRGBA": ("raw", "RGBA"),
|
b"PyRGBA": "RGBA",
|
||||||
b"PyCMYK": ("raw", "CMYK"),
|
b"PyCMYK": "CMYK",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,18 +89,16 @@ class PpmImageFile(ImageFile.ImageFile):
|
||||||
def _open(self):
|
def _open(self):
|
||||||
magic_number = self._read_magic()
|
magic_number = self._read_magic()
|
||||||
try:
|
try:
|
||||||
decoder, mode = MODES[magic_number]
|
mode = MODES[magic_number]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise SyntaxError("not a PPM file")
|
raise SyntaxError("not a PPM file")
|
||||||
|
|
||||||
self.custom_mimetype = {
|
if magic_number in (b"P1", b"P4"):
|
||||||
b"P1": "image/x-portable-bitmap",
|
self.custom_mimetype = "image/x-portable-bitmap"
|
||||||
b"P2": "image/x-portable-graymap",
|
elif magic_number in (b"P2", b"P5"):
|
||||||
b"P3": "image/x-portable-pixmap",
|
self.custom_mimetype = "image/x-portable-graymap"
|
||||||
b"P4": "image/x-portable-bitmap",
|
elif magic_number in (b"P3", b"P6"):
|
||||||
b"P5": "image/x-portable-graymap",
|
self.custom_mimetype = "image/x-portable-pixmap"
|
||||||
b"P6": "image/x-portable-pixmap",
|
|
||||||
}.get(magic_number)
|
|
||||||
|
|
||||||
for ix in range(3):
|
for ix in range(3):
|
||||||
token = int(self._read_token())
|
token = int(self._read_token())
|
||||||
|
@ -127,14 +124,12 @@ class PpmImageFile(ImageFile.ImageFile):
|
||||||
self.mode = "I"
|
self.mode = "I"
|
||||||
rawmode = "I;32B"
|
rawmode = "I;32B"
|
||||||
|
|
||||||
|
decoder_name = "raw"
|
||||||
|
if magic_number in (b"P1", b"P2", b"P3"):
|
||||||
|
decoder_name = "ppm_plain"
|
||||||
self._size = xsize, ysize
|
self._size = xsize, ysize
|
||||||
self.tile = [
|
self.tile = [
|
||||||
(
|
(decoder_name, (0, 0, xsize, ysize), self.fp.tell(), (rawmode, 0, 1))
|
||||||
decoder, # decoder
|
|
||||||
(0, 0, xsize, ysize), # region: whole image
|
|
||||||
self.fp.tell(), # offset to image data
|
|
||||||
(rawmode, 0, 1), # parameters for decoder
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,8 +140,8 @@ class PpmImageFile(ImageFile.ImageFile):
|
||||||
class PpmPlainDecoder(ImageFile.PyDecoder):
|
class PpmPlainDecoder(ImageFile.PyDecoder):
|
||||||
_pulls_fd = True
|
_pulls_fd = True
|
||||||
|
|
||||||
def _read_block(self, block_size=10**6):
|
def _read_block(self):
|
||||||
return bytearray(self.fd.read(block_size))
|
return self.fd.read(10**6)
|
||||||
|
|
||||||
def _find_comment_end(self, block, start=0):
|
def _find_comment_end(self, block, start=0):
|
||||||
a = block.find(b"\n", start)
|
a = block.find(b"\n", start)
|
||||||
|
@ -155,10 +150,9 @@ class PpmPlainDecoder(ImageFile.PyDecoder):
|
||||||
|
|
||||||
def _ignore_comments(self, block):
|
def _ignore_comments(self, block):
|
||||||
"""
|
"""
|
||||||
Deletes comments from block. If comment does not end in this
|
Deletes comments from block.
|
||||||
block, raises a flag.
|
If comment does not end in this block, raises a flag.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
comment_spans = False
|
comment_spans = False
|
||||||
while True:
|
while True:
|
||||||
comment_start = block.find(b"#") # look for next comment
|
comment_start = block.find(b"#") # look for next comment
|
||||||
|
@ -166,9 +160,8 @@ class PpmPlainDecoder(ImageFile.PyDecoder):
|
||||||
break
|
break
|
||||||
comment_end = self._find_comment_end(block, comment_start)
|
comment_end = self._find_comment_end(block, comment_start)
|
||||||
if comment_end != -1: # comment ends in this block
|
if comment_end != -1: # comment ends in this block
|
||||||
block = (
|
# delete comment
|
||||||
block[:comment_start] + block[comment_end + 1 :]
|
block = block[:comment_start] + block[comment_end + 1 :]
|
||||||
) # delete comment
|
|
||||||
else: # last comment continues to next block(s)
|
else: # last comment continues to next block(s)
|
||||||
block = block[:comment_start]
|
block = block[:comment_start]
|
||||||
comment_spans = True
|
comment_spans = True
|
||||||
|
@ -177,9 +170,8 @@ class PpmPlainDecoder(ImageFile.PyDecoder):
|
||||||
|
|
||||||
def _decode_bitonal(self):
|
def _decode_bitonal(self):
|
||||||
"""
|
"""
|
||||||
The reason this is a separate method is that in the plain PBM
|
This is a separate method because the plain PBM format all data tokens
|
||||||
format all data tokens are exactly one byte, and so the
|
are exactly one byte, and so the inter-token whitespace is optional.
|
||||||
inter-token whitespace is optional.
|
|
||||||
"""
|
"""
|
||||||
decoded_data = bytearray()
|
decoded_data = bytearray()
|
||||||
total_tokens = self.size
|
total_tokens = self.size
|
||||||
|
@ -217,10 +209,8 @@ class PpmPlainDecoder(ImageFile.PyDecoder):
|
||||||
|
|
||||||
def _decode_blocks(self, channels=1, depth=8):
|
def _decode_blocks(self, channels=1, depth=8):
|
||||||
decoded_data = bytearray()
|
decoded_data = bytearray()
|
||||||
if depth == 32:
|
# HACK: 32-bit grayscale uses signed int
|
||||||
maxval = 2**31 - 1 # HACK: 32-bit grayscale uses signed int
|
maxval = 2 ** (31 if depth == 32 else depth) - 1
|
||||||
else:
|
|
||||||
maxval = 2**depth - 1 # FIXME: should be passed by _open
|
|
||||||
max_len = 10
|
max_len = 10
|
||||||
bytes_per_sample = depth // 8
|
bytes_per_sample = depth // 8
|
||||||
total_tokens = self.size * channels
|
total_tokens = self.size * channels
|
||||||
|
|
Loading…
Reference in New Issue
Block a user