summaryrefslogtreecommitdiff
path: root/util/png.py
diff options
context:
space:
mode:
Diffstat (limited to 'util/png.py')
-rw-r--r--util/png.py33
1 files changed, 33 insertions, 0 deletions
diff --git a/util/png.py b/util/png.py
new file mode 100644
index 0000000..0936cf0
--- /dev/null
+++ b/util/png.py
@@ -0,0 +1,33 @@
+import struct
+import zlib
+
+def encode(buf, width, height):
+ """ buf: must be bytes or a bytearray in py3, a regular string in py2. formatted RGBRGB... """
+ assert (width * height * 3 == len(buf))
+ bpp = 3
+
+ def raw_data():
+ # reverse the vertical line order and add null bytes at the start
+ row_bytes = width * bpp
+ for row_start in range((height - 1) * width * bpp, -1, -row_bytes):
+ yield b'\x00'
+ yield buf[row_start:row_start + row_bytes]
+
+ def chunk(tag, data):
+ return [
+ struct.pack("!I", len(data)),
+ tag,
+ data,
+ struct.pack("!I", 0xFFFFFFFF & zlib.crc32(data, zlib.crc32(tag)))
+ ]
+
+ SIGNATURE = b'\x89PNG\r\n\x1a\n'
+ COLOR_TYPE_RGB = 2
+ COLOR_TYPE_RGBA = 6
+ bit_depth = 8
+ return b''.join(
+ [ SIGNATURE ] +
+ chunk(b'IHDR', struct.pack("!2I5B", width, height, bit_depth, COLOR_TYPE_RGB, 0, 0, 0)) +
+ chunk(b'IDAT', zlib.compress(b''.join(raw_data()), 9)) +
+ chunk(b'IEND', b'')
+ )