aboutsummaryrefslogtreecommitdiff
path: root/experiments/conv
diff options
context:
space:
mode:
Diffstat (limited to 'experiments/conv')
-rw-r--r--experiments/conv/consts.py38
-rw-r--r--experiments/conv/makefile2
-rwxr-xr-xexperiments/conv/pc2png26
-rwxr-xr-xexperiments/conv/png2pc56
-rw-r--r--experiments/conv/shared.py19
5 files changed, 102 insertions, 39 deletions
diff --git a/experiments/conv/consts.py b/experiments/conv/consts.py
index 898bd3d..e50c51a 100644
--- a/experiments/conv/consts.py
+++ b/experiments/conv/consts.py
@@ -1,18 +1,24 @@
+DS_TILE_SIZE = 8
+TILE_BYTES = 32 # tiles are stored in 32 bytes chunks
+
+TILES_HORIZONTAL = 32
+
PICTOCHAT_PALETTE = (
- (0xff, 0xff, 0xff),
- (0x00, 0x00, 0x00),
- (0xd3, 0xcb, 0xc3),
- (0xeb, 0x00, 0xeb),
- (0xfb, 0x00, 0x8a),
- (0xfb, 0x00, 0x28),
- (0xfb, 0x49, 0x00),
- (0xfb, 0xa2, 0x00),
- (0xe3, 0xf3, 0x00),
- (0x82, 0xfb, 0x00),
- (0x10, 0xfb, 0x20),
- (0x00, 0xfb, 0xba),
- (0x00, 0xc3, 0xfb),
- (0x00, 0x79, 0xfb),
- (0x00, 0x30, 0xfb),
- (0x28, 0x00, 0xfb),
+ (0xff, 0xff, 0xff),
+ (0x00, 0x00, 0x00),
+ (0xd3, 0xcb, 0xc3),
+ (0xeb, 0x00, 0xeb),
+ (0xfb, 0x00, 0x8a),
+ (0xfb, 0x00, 0x28),
+ (0xfb, 0x49, 0x00),
+ (0xfb, 0xa2, 0x00),
+ (0xe3, 0xf3, 0x00),
+ (0x82, 0xfb, 0x00),
+ (0x10, 0xfb, 0x20),
+ (0x00, 0xfb, 0xba),
+ (0x00, 0xc3, 0xfb),
+ (0x00, 0x79, 0xfb),
+ (0x00, 0x30, 0xfb),
+ (0x28, 0x00, 0xfb),
)
+
diff --git a/experiments/conv/makefile b/experiments/conv/makefile
new file mode 100644
index 0000000..f4f3cd5
--- /dev/null
+++ b/experiments/conv/makefile
@@ -0,0 +1,2 @@
+%.png: %.bin
+ ./pc2png $<
diff --git a/experiments/conv/pc2png b/experiments/conv/pc2png
index 4fa7a1a..c7f131a 100755
--- a/experiments/conv/pc2png
+++ b/experiments/conv/pc2png
@@ -1,18 +1,10 @@
#!/bin/python3
-
-import sys
-import re
import math
import io
-
from PIL import Image
-from consts import PICTOCHAT_PALETTE
-
-DS_TILE_SIZE = 8
-TILE_BYTES = 32 # tiles are stored in 32 bytes chunks
-
-TILES_HORIZONTAL = 32
+from consts import *
+from shared import main
# convert a single DS tile (8x8) from packed palette index format to RGB colors
def convert_chunk(img, chunk, offset):
@@ -53,18 +45,6 @@ def pc2png(data):
img.save(output, format='PNG')
return output.getvalue()
-def convert_file(input_filename, output_filename):
- with open(input_filename, 'rb') as input_file:
- content = input_file.read()
- output = pc2png(content)
- with open(output_filename, 'wb+') as output_file:
- output_file.write(output)
-
if __name__ == "__main__":
- del sys.argv[0]
- for input_filename in sys.argv:
- output_filename = re.sub('.bin$', '.png', input_filename)
- if not output_filename.endswith('.png'):
- output_filename += '.png'
- convert_file(input_filename, output_filename)
+ main("bin", "png", pc2png)
diff --git a/experiments/conv/png2pc b/experiments/conv/png2pc
new file mode 100755
index 0000000..d1eaab8
--- /dev/null
+++ b/experiments/conv/png2pc
@@ -0,0 +1,56 @@
+#!/bin/python3
+import itertools
+import io
+from PIL import Image
+
+from consts import *
+from shared import main
+
+palette_img = Image.new('P', (1, 1))
+palette_img.putpalette(list(itertools.chain.from_iterable([
+ *PICTOCHAT_PALETTE,
+ *[PICTOCHAT_PALETTE[0] for x in range(256 - len(PICTOCHAT_PALETTE))],
+])))
+
+def convert_chunk(img, offset):
+ palette_indices = []
+ for y in range(DS_TILE_SIZE):
+ for x in range(DS_TILE_SIZE):
+ palette_indices.append(img.getpixel((x + offset[0], y + offset[1])))
+
+ bytes = bytearray()
+ for i in range(0, len(palette_indices), 2):
+ bytes.append((palette_indices[i+0] << 0) | (palette_indices[i+1] << 4))
+
+ return bytes
+
+def png2pc(data):
+ img = Image.open(io.BytesIO(data))
+ if img.width != TILES_HORIZONTAL * DS_TILE_SIZE:
+ print(f"error: input image is not {TILES_HORIZONTAL * DS_TILE_SIZE} pixels wide")
+ exit(1)
+ if img.height % DS_TILE_SIZE != 0:
+ print(f"error: input image height not a muliple of {DS_TILE_SIZE}")
+ exit(1)
+ tile_count = (img.width * img.height) // (DS_TILE_SIZE ** 2)
+
+ img = img.convert('RGB')
+ img = img.quantize(palette=palette_img)
+
+ output = b""
+ for tile_idx in range(tile_count):
+ tile = (
+ tile_idx % TILES_HORIZONTAL,
+ tile_idx // TILES_HORIZONTAL,
+ )
+ offset = (
+ tile[0] * DS_TILE_SIZE,
+ tile[1] * DS_TILE_SIZE,
+ )
+ output += convert_chunk(img, offset)
+
+ return output
+
+if __name__ == "__main__":
+ main("png", "bin", png2pc)
+
diff --git a/experiments/conv/shared.py b/experiments/conv/shared.py
new file mode 100644
index 0000000..be883be
--- /dev/null
+++ b/experiments/conv/shared.py
@@ -0,0 +1,19 @@
+import sys
+
+def convert_file(input_filename, output_filename, converter):
+ with open(input_filename, 'rb') as input_file:
+ content = input_file.read()
+ output = converter(content)
+ with open(output_filename, 'wb+') as output_file:
+ output_file.write(output)
+
+def main(from_ext, to_ext, converter):
+ del sys.argv[0]
+ if len(sys.argv) == 0:
+ print("error: no input files!", file=sys.stderr)
+ exit(1)
+
+ for input_filename in sys.argv:
+ output_filename = input_filename.removesuffix(f".{from_ext}") + f".{to_ext}"
+ convert_file(input_filename, output_filename, converter)
+