Fixed reading 9 and 11-15-bit PGM
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
Tests/images/ppm/11_bit.pgm
Normal file
BIN
Tests/images/ppm/11_bit.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
Tests/images/ppm/12_bit.pgm
Normal file
BIN
Tests/images/ppm/12_bit.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
Tests/images/ppm/13_bit.pgm
Normal file
BIN
Tests/images/ppm/13_bit.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
Tests/images/ppm/14_bit.pgm
Normal file
BIN
Tests/images/ppm/14_bit.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
Tests/images/ppm/15_bit.pgm
Normal file
BIN
Tests/images/ppm/15_bit.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
Tests/images/ppm/9_bit.pgm
Normal file
BIN
Tests/images/ppm/9_bit.png
Normal file
After Width: | Height: | Size: 15 KiB |
|
@ -20,14 +20,16 @@ def test_sanity():
|
|||
assert im.get_format_mimetype() == "image/x-portable-pixmap"
|
||||
|
||||
|
||||
def test_10bit_pgm():
|
||||
with Image.open("Tests/images/10_bit_binary.pgm") as im:
|
||||
@pytest.mark.parametrize("depth", range(9, 16))
|
||||
def test_less_than_16bit_pgm(depth):
|
||||
name = "Tests/images/ppm/" + str(depth) + "_bit"
|
||||
with Image.open(name + ".pgm") as im:
|
||||
im.load()
|
||||
assert im.mode == "I"
|
||||
assert im.size == (128, 128)
|
||||
assert im.get_format_mimetype() == "image/x-portable-graymap"
|
||||
|
||||
assert_image_equal_tofile(im, "Tests/images/10_bit_binary_pgm.png")
|
||||
assert_image_equal_tofile(im, name + ".png")
|
||||
|
||||
|
||||
def test_16bit_pgm():
|
||||
|
|
|
@ -115,15 +115,13 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
if maxval > 255:
|
||||
if mode != "L":
|
||||
raise ValueError(f"Too many colors for band: {token}")
|
||||
if maxval == 1023:
|
||||
self.mode = "I"
|
||||
rawmode = "I;10B"
|
||||
elif maxval < 2**16:
|
||||
self.mode = "I"
|
||||
rawmode = "I;16B"
|
||||
for bit in range(9, 16):
|
||||
if maxval == 2**bit - 1:
|
||||
break
|
||||
else:
|
||||
self.mode = "I"
|
||||
rawmode = "I;32B"
|
||||
bit = 16 if maxval < 2**16 else 32
|
||||
rawmode = "I;" + str(bit) + "B"
|
||||
|
||||
self._size = xsize, ysize
|
||||
self.tile = [("raw", (0, 0, xsize, ysize), self.fp.tell(), (rawmode, 0, 1))]
|
||||
|
|
|
@ -1182,22 +1182,39 @@ unpackI12_I16(UINT8 *out, const UINT8 *in, int pixels) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackI10B(UINT8 *out, const UINT8 *in, int pixels) {
|
||||
int i, pixel;
|
||||
for (i = 0; i < pixels; i++) {
|
||||
pixel = ((in[0] << 8) + in[1]) << 6;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
out[2] = pixel >> 8;
|
||||
out[3] = pixel;
|
||||
#define UNPACK_IXB(NAME, DEPTH) \
|
||||
static void NAME(UINT8 *out, const UINT8 *in, int pixels) { \
|
||||
int i, pixel; \
|
||||
for (i = 0; i < pixels; i++) { \
|
||||
pixel = ((in[0] << 8) + in[1]) << (16 - DEPTH); \
|
||||
out[2] = pixel >> 8; \
|
||||
out[3] = pixel; \
|
||||
in += 2; \
|
||||
out += 4; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
out[0] = pixel;
|
||||
out[1] = pixel >> 8;
|
||||
#define UNPACK_IXB(NAME, DEPTH) \
|
||||
static void NAME(UINT8 *out, const UINT8 *in, int pixels) { \
|
||||
int i, pixel; \
|
||||
for (i = 0; i < pixels; i++) { \
|
||||
pixel = ((in[0] << 8) + in[1]) << (16 - DEPTH); \
|
||||
out[0] = pixel; \
|
||||
out[1] = pixel >> 8; \
|
||||
in += 2; \
|
||||
out += 4; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
in += 2;
|
||||
out += 4;
|
||||
}
|
||||
}
|
||||
|
||||
UNPACK_IXB(unpackI9B, 9)
|
||||
UNPACK_IXB(unpackI10B, 10)
|
||||
UNPACK_IXB(unpackI11B, 11)
|
||||
UNPACK_IXB(unpackI12B, 12)
|
||||
UNPACK_IXB(unpackI13B, 13)
|
||||
UNPACK_IXB(unpackI14B, 14)
|
||||
UNPACK_IXB(unpackI15B, 15)
|
||||
|
||||
static void
|
||||
copy1(UINT8 *out, const UINT8 *in, int pixels) {
|
||||
|
@ -1701,7 +1718,13 @@ static struct {
|
|||
{"I", "I", 32, copy4},
|
||||
{"I", "I;8", 8, unpackI8},
|
||||
{"I", "I;8S", 8, unpackI8S},
|
||||
{"I", "I;9B", 16, unpackI9B},
|
||||
{"I", "I;10B", 16, unpackI10B},
|
||||
{"I", "I;11B", 16, unpackI11B},
|
||||
{"I", "I;12B", 16, unpackI12B},
|
||||
{"I", "I;13B", 16, unpackI13B},
|
||||
{"I", "I;14B", 16, unpackI14B},
|
||||
{"I", "I;15B", 16, unpackI15B},
|
||||
{"I", "I;16", 16, unpackI16},
|
||||
{"I", "I;16S", 16, unpackI16S},
|
||||
{"I", "I;16B", 16, unpackI16B},
|
||||
|
|