Skip to content

Commit

Permalink
Fixed reading 9 and 11-15-bit PGM
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Mar 4, 2022
1 parent 0712535 commit 6cb4f5b
Show file tree
Hide file tree
Showing 17 changed files with 47 additions and 24 deletions.
File renamed without changes.
File renamed without changes
Binary file added Tests/images/ppm/11_bit.pgm
Binary file not shown.
Binary file added Tests/images/ppm/11_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/ppm/12_bit.pgm
Binary file not shown.
Binary file added Tests/images/ppm/12_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/ppm/13_bit.pgm
Binary file not shown.
Binary file added Tests/images/ppm/13_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/ppm/14_bit.pgm
Binary file not shown.
Binary file added Tests/images/ppm/14_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/ppm/15_bit.pgm
Binary file not shown.
Binary file added Tests/images/ppm/15_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/ppm/9_bit.pgm
Binary file not shown.
Binary file added Tests/images/ppm/9_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions Tests/test_file_ppm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
14 changes: 6 additions & 8 deletions src/PIL/PpmImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,13 @@ def _open(self):
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"
self.mode = "I"
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))]
Expand Down
49 changes: 36 additions & 13 deletions src/libImaging/Unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
#endif
in += 2;
out += 4;
#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

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) {
Expand Down Expand Up @@ -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},
Expand Down

0 comments on commit 6cb4f5b

Please sign in to comment.