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 72b7387 commit 45988ab
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
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
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
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
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
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
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
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
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
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 45988ab

Please sign in to comment.