Skip to content

Commit

Permalink
Fixed reading 10-bit PGM
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Mar 4, 2022
1 parent d1124cd commit 0712535
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
Binary file added Tests/images/10_bit_binary.pgm
Binary file not shown.
Binary file added Tests/images/10_bit_binary_pgm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions Tests/test_file_ppm.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +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:
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")


def test_16bit_pgm():
with Image.open("Tests/images/16_bit_binary.pgm") as im:
im.load()
Expand Down
7 changes: 5 additions & 2 deletions src/PIL/PpmImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,12 @@ def _open(self):
elif ix == 2: # token is maxval
maxval = token
if maxval > 255:
if not mode == "L":
if mode != "L":
raise ValueError(f"Too many colors for band: {token}")
if maxval < 2 ** 16:
if maxval == 1023:
self.mode = "I"
rawmode = "I;10B"
elif maxval < 2 ** 16:
self.mode = "I"
rawmode = "I;16B"
else:
Expand Down
18 changes: 18 additions & 0 deletions src/libImaging/Unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,23 @@ 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;
#else
out[0] = pixel;
out[1] = pixel >> 8;
#endif
in += 2;
out += 4;
}
}

static void
copy1(UINT8 *out, const UINT8 *in, int pixels) {
/* L, P */
Expand Down Expand Up @@ -1684,6 +1701,7 @@ static struct {
{"I", "I", 32, copy4},
{"I", "I;8", 8, unpackI8},
{"I", "I;8S", 8, unpackI8S},
{"I", "I;10B", 16, unpackI10B},
{"I", "I;16", 16, unpackI16},
{"I", "I;16S", 16, unpackI16S},
{"I", "I;16B", 16, unpackI16B},
Expand Down

0 comments on commit 0712535

Please sign in to comment.