Skip to content

Commit f667e4f

Browse files
authored
Merge pull request #98 from Neradoc/add-filters-indexed-png
Implement filters for indexed PNG
2 parents c5e3b7e + 790497e commit f667e4f

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

adafruit_imageload/png.py

100644100755
Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import struct
2929
import zlib
3030

31-
__version__ = "0.0.0-auto.0"
31+
__version__ = "0.0.0+auto.0"
3232
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git"
3333

3434

@@ -106,20 +106,56 @@ def load( # noqa: PLR0912, PLR0915, Too many branches, Too many statements
106106
if mode == 3: # indexed
107107
bmp = bitmap(width, height, 1 << depth)
108108
pixels_per_byte = 8 // depth
109-
src = 1
110-
src_b = 1
109+
src = 0
111110
pixmask = (1 << depth) - 1
111+
line = bytearray(scanline)
112+
prev = bytearray(scanline)
112113
for y in range(height):
114+
filter_ = data_bytes[src]
115+
src_b = src + 1
113116
for x in range(0, width, pixels_per_byte):
117+
# relative position on the line
118+
pos = x // pixels_per_byte
114119
byte = data_bytes[src_b]
120+
if filter_ == 0:
121+
pass
122+
elif filter_ == 1: # sub
123+
prev_b = line[pos - unit] if pos >= unit else 0
124+
byte = (byte + prev_b) & 0xFF
125+
elif filter_ == 2: # up
126+
byte = (byte + prev[pos]) & 0xFF
127+
elif filter_ == 3: # average
128+
prev_b = line[pos - unit] if pos >= unit else 0
129+
byte = (byte + (prev_b + prev[pos]) // 2) & 0xFF
130+
elif filter_ == 4: # paeth
131+
a = line[pos - unit] if pos >= unit else 0
132+
if y > 0:
133+
b = prev[pos]
134+
c = prev[pos - unit] if pos >= unit else 0
135+
else:
136+
b = c = 0
137+
p = a + b - c
138+
pa = abs(p - a)
139+
pb = abs(p - b)
140+
pc = abs(p - c)
141+
if pa <= pb and pa <= pc:
142+
p = a
143+
elif pb <= pc:
144+
p = b
145+
else:
146+
p = c
147+
byte = (byte + p) & 0xFF
148+
else:
149+
raise ValueError("Wrong filter.")
150+
line[pos] = byte
115151
for pixel in range(pixels_per_byte):
116152
if x + pixel < width:
117153
bmp[x + pixel, y] = (
118154
byte >> ((pixels_per_byte - pixel - 1) * depth)
119155
) & pixmask
120156
src_b += 1
121157
src += scanline + 1
122-
src_b = src
158+
prev, line = line, prev
123159
return bmp, pal
124160
# RGB, RGBA or Grayscale
125161
import displayio

0 commit comments

Comments
 (0)