Skip to content

Commit 0a2e93c

Browse files
committed
Merge branch 'master' into Riddlerat/pgm-work
2 parents d4e33c2 + 6fb1375 commit 0a2e93c

6 files changed

Lines changed: 181 additions & 18 deletions

File tree

adafruit_imageload/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,3 @@ def load(filename, *, bitmap=None, palette=None):
5555
return pnm.load(f, header, bitmap=bitmap, palette=palette)
5656
else:
5757
raise RuntimeError("Unsupported image format")
58-

adafruit_imageload/pnm/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,9 @@ def load(f, header, *, bitmap=None, palette=None):
4141
while True:
4242
# We have all we need at length 3
4343
if len(pnm_header) == 3:
44-
f.read(1)
4544
break
4645
if magic_number.startswith(b"P1") or magic_number.startswith(b"P4"):
4746
if len(pnm_header) == 2:
48-
f.read(1)
4947
from . import pbm
5048

5149
return pbm.load(
@@ -70,7 +68,7 @@ def load(f, header, *, bitmap=None, palette=None):
7068
if not next_byte:
7169
raise RuntimeError("Unsupported image format")
7270

73-
pnm_header.append(int(value))
71+
pnm_header.append(int("".join(["%c" % char for char in value])))
7472
continue
7573

7674
if not next_byte:
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import logging
2+
3+
4+
5+
def load(f, magic_number, header, bitmap = None , palette = None):
6+
# type: (stream, str, list, c_obj, c_obj) -> bitmap, palette
7+
height = header[0]
8+
width = header[1]
9+
logging.info(f'height: {height}')
10+
if palette:
11+
palette = palette(1)
12+
if bitmap:
13+
bitmap = bitmap(header[0], header[1], 1)
14+
for line in range(height-1,-1,-1):
15+
16+
chunk = f.read(width)
17+
#logging.info(chunk)
18+
return bitmap, palette
19+
20+
#while not has 3 signnif
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
"""
23+
`adafruit_imageload.pnm.ppm`
24+
====================================================
25+
26+
Load pixel values (indices or colors) into a bitmap and for a binary ppm,
27+
return None for pallet.
28+
29+
* Author(s): Matt Land, Brooke Storm, Sam McGahan
30+
31+
"""
32+
33+
__version__ = "0.0.0-auto.0"
34+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git"
35+
36+
import math
37+
38+
39+
def load(file, magic_number, header, bitmap=None, palette=None):
40+
"""Load pixel values (indices or colors) into a bitmap and for a binary
41+
ppm, return None for pallet."""
42+
width = header[0]
43+
height = header[1]
44+
max_colors = (header[2] + 1) ** 3
45+
# TODO: This needs to be different most likely?
46+
colors = math.log(header[2], 2)
47+
bitmap = bitmap(width, height, int(colors))
48+
palette = None
49+
50+
if bitmap:
51+
if magic_number == b"P3":
52+
# This is ascii
53+
from . import ppm_ascii
54+
55+
return ppm_ascii.load(
56+
file, width, height, max_colors, bitmap=bitmap, palette=None
57+
)
58+
59+
minimum_color_depth = 1
60+
while max_colors > 2 ** minimum_color_depth:
61+
minimum_color_depth *= 2
62+
63+
# This seems maybe right?
64+
line_size = width * 3
65+
66+
chunk = bytearray(line_size)
67+
68+
for y in range(height):
69+
file.readinto(chunk)
70+
# Division by zero!
71+
pixels_per_byte = 8 // max_colors
72+
offset = y * width
73+
74+
for x in range(width):
75+
# This math is clearly wrong and was just copied in from the PR
76+
i = x // pixels_per_byte
77+
pixel = (
78+
chunk[i] >> (8 - max_colors * (x % pixels_per_byte + 1))
79+
) & ((1 << minimum_color_depth) - 1)
80+
bitmap[offset + x] = pixel
81+
82+
return bitmap, palette
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
"""
23+
`adafruit_imageload.pnm.ppm.ppm_ascii`
24+
====================================================
25+
26+
Load pixel values (indices or colors) into a bitmap and for an ascii ppm,
27+
return None for pallet.
28+
29+
* Author(s): Matt Land, Brooke Storm, Sam McGahan
30+
31+
"""
32+
33+
__version__ = "0.0.0-auto.0"
34+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git"
35+
36+
import struct
37+
38+
39+
def load(file, width, height, max_colors, bitmap=None, palette=None):
40+
"""Load an ascii ppm into the Bitmap object"""
41+
if bitmap:
42+
for y in range(height):
43+
offset = y * width
44+
for x in range(width):
45+
triplet = []
46+
color = bytearray()
47+
while True:
48+
if len(triplet) == 3:
49+
break
50+
this_byte = file.read(1)
51+
if this_byte.isdigit():
52+
color += this_byte
53+
else:
54+
triplet.append(color)
55+
color = bytearray()
56+
continue
57+
pixel = bytearray(3)
58+
# This just became 8-bit only...
59+
struct.pack_into(
60+
"BBB",
61+
pixel,
62+
0,
63+
int("".join(["%c" % char for char in triplet[0]])),
64+
int("".join(["%c" % char for char in triplet[1]])),
65+
int("".join(["%c" % char for char in triplet[2]])),
66+
)
67+
bitmap[offset + x] = int.from_bytes(pixel, "little")
68+
69+
return bitmap, palette

adafruit_imageload/tests/test_pnm_load.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,38 @@ def __init__(self, width, height, colors):
1212

1313
logging.getLogger().setLevel(logging.INFO)
1414

15-
class TestPbmP1(TestCase):
15+
class TestPnmLoad(TestCase):
1616

1717
def test_load_fails_with_no_header_data(self):
1818
f = BytesIO(b"some initial binary data: \x00\x01")
1919
try:
20-
pnm.load(f, b'P1')
20+
pnm.load(f, b'P1', bitmap=Bitmap)
2121
self.fail('should have failed')
2222
except Exception as e:
2323
if "Unsupported image format" not in str(e):
2424
raise
2525

26-
def _test_load_works_p1_ascii(self):
26+
def test_load_works_p1_ascii(self):
2727
test_file = os.path.join(os.path.dirname(__file__), '..', '..', 'examples', 'images', 'netpbm_p1_mono.pbm')
28-
with open(test_file) as f:
29-
f.seek(2)
30-
bitmap, palette = pnm.load(f, b'P1')
31-
self.assertTrue(isinstance(bitmap, Bitmap))
32-
self.fail(bitmap)
28+
with open(test_file, 'rb') as f:
29+
bitmap, palette = pnm.load(f, b'P1', bitmap=Bitmap)
30+
self.assertTrue(isinstance(bitmap, Bitmap), bitmap)
3331
self.assertEqual(1, bitmap.colors)
34-
self.assertEqual(20, bitmap.width)
32+
self.assertEqual(13, bitmap.width)
33+
self.assertEqual(21, bitmap.height)
3534

3635
def test_load_works_p4_binary(self):
3736
test_file = os.path.join(os.path.dirname(__file__), '..', '..', 'examples', 'images', 'netpbm_p4_mono.pbm')
38-
3937
with open(test_file, 'rb') as f:
40-
f.seek(2)
4138
bitmap, palette = pnm.load(f, b'P4', bitmap=Bitmap)
4239
self.assertTrue(isinstance(bitmap, Bitmap))
4340
self.assertEqual(1, bitmap.colors)
4441
self.assertEqual(8, bitmap.width)
4542
self.assertEqual(8, bitmap.height)
4643

47-
def test_load_works_p4_binary_big(self):
44+
def test_load_works_p4_binary_high_res(self):
4845
test_file = os.path.join(os.path.dirname(__file__), '..', '..', 'examples', 'images', 'MARBLES.PBM')
49-
5046
with open(test_file, 'rb') as f:
51-
f.seek(2)
5247
bitmap, palette = pnm.load(f, b'P4', bitmap=Bitmap)
5348
self.assertTrue(isinstance(bitmap, Bitmap))
5449
self.assertEqual(1, bitmap.colors)

0 commit comments

Comments
 (0)