Skip to content

Commit f993d5f

Browse files
committed
Support also 8-bit PNG images in Stage
As long as only 16 colors are used
1 parent 9c88283 commit f993d5f

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

stage.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def read_palette(self, palette=None):
177177
return palette
178178

179179
def read_data(self, buffer=None):
180-
line_size = self.width >> 1
180+
line_size = (self.width + 1 ) >> 1
181181
if buffer is None:
182182
buffer = bytearray(line_size * self.height)
183183

@@ -207,17 +207,23 @@ def read_header(self):
207207
) = struct.unpack(">I4sIIBBBBB4s", f.read(25))
208208
assert size == 13 # header length
209209
assert chunk == b'IHDR'
210-
if self.depth != 4 or self.mode != 3 or self.interlaced != 0:
210+
if self.depth not in {4, 8} or self.mode != 3 or self.interlaced != 0:
211211
raise ValueError("16-color non-interaced PNG expected")
212212

213213
def read_palette(self, palette=None):
214214
if palette is None:
215215
palette = array.array('H', (0 for i in range(16)))
216216
with open(self.filename, 'rb') as f:
217217
f.seek(8 + 25)
218-
size, chunk = struct.unpack(">I4s", f.read(8))
219-
assert chunk == b'PLTE'
220-
for color in range(size // 3):
218+
while True:
219+
size, chunk = struct.unpack(">I4s", f.read(8))
220+
if chunk == b'PLTE':
221+
break
222+
f.seek(size + 4, 1)
223+
colors = size // 3
224+
if colors > 16:
225+
raise ValueError("16-color PNG expected")
226+
for color in range(colors):
221227
c = color565(*struct.unpack("BBB", f.read(3)))
222228
palette[color] = ((c << 8) | (c >> 8)) & 0xffff
223229
return palette
@@ -236,14 +242,30 @@ def read_data(self, buffer=None):
236242
data.extend(f.read(size))
237243
f.seek(4, 1) # skip CRC
238244
data = zlib.decompress(data)
239-
line_size = self.width >> 1
245+
line_size = (self.width + 1) >> 1
240246
if buffer is None:
241247
buffer = bytearray(line_size * self.height)
242-
for line in range(self.height):
243-
a = line * line_size
244-
b = line * (line_size + 1)
245-
assert data[b] == 0 # no filter
246-
buffer[a:a + line_size] = data[b + 1:b + 1 + line_size]
248+
if self.depth == 4:
249+
for line in range(self.height):
250+
a = line * line_size
251+
b = line * (line_size + 1)
252+
assert data[b] == 0 # no filter
253+
buffer[a:a + line_size] = data[b + 1:b + 1 + line_size]
254+
elif self.depth == 8:
255+
for line in range(self.height):
256+
a = line * line_size
257+
b = line * (self.width + 1)
258+
assert data[b] == 0 # no filter
259+
b += 1
260+
for col in range(line_size):
261+
buffer[a] = (data[b] & 0x0f) << 4
262+
b += 1
263+
try:
264+
buffer[a] |= data[b] & 0x0f
265+
except IndexError:
266+
pass
267+
b += 1
268+
a += 1
247269
return buffer
248270

249271

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy