-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcdl2png.py
64 lines (51 loc) · 1.86 KB
/
cdl2png.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import itertools, os, sys
from PIL import Image # Pillow, https://python-pillow.org
# 2 LSBs of CDL byte -> RGB color;
# see http://fceux.com/web/help/CodeDataLogger.html
OUTPUT_PALETTE = (
(0x00, 0x00, 0x00), # 0b00: unaccessed
(0xff, 0x80, 0x00), # 0b01: code (PRG) / rendered (CHR)
(0x00, 0x80, 0xff), # 0b10: data (PRG) / read programmatically (CHR)
(0xff, 0xff, 0xff), # 0b11: both
)
def parse_arguments():
# return (name of input file, name of output file)
if len(sys.argv) != 3:
sys.exit(
"Convert an FCEUX Code/Data Logger file (.cdl) into a PNG image "
"file. Arguments: inputFile outputFile. See README.md for details."
)
(inFile, outFile) = sys.argv[1:]
if not os.path.isfile(inFile):
sys.exit("Input file not found.")
try:
fileSize = os.path.getsize(inFile)
except OSError:
sys.exit("Error getting input file size.")
if fileSize == 0 or fileSize % 256 > 0:
sys.exit("Input file size must be a multiple of 256 bytes.")
if os.path.exists(outFile):
sys.exit("Output file already exists.")
return (inFile, outFile)
def create_image(handle):
# read CDL data from file, return indexed image
dataLen = handle.seek(0, 2)
image = Image.new("P", (256, dataLen // 256))
image.putpalette(itertools.chain.from_iterable(OUTPUT_PALETTE))
handle.seek(0)
image.putdata(tuple(b & 0b11 for b in handle.read()))
return image
def main():
(inFile, outFile) = parse_arguments()
try:
with open(inFile, "rb") as handle:
image = create_image(handle)
except OSError:
sys.exit("Error reading input file.")
try:
with open(outFile, "wb") as handle:
handle.seek(0)
image.save(handle, "png")
except OSError:
sys.exit("Error writing output file.")
main()