-
Notifications
You must be signed in to change notification settings - Fork 0
/
dinoparkact.py
110 lines (94 loc) · 3.41 KB
/
dinoparkact.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import struct
import os
import sys
from PIL import Image, ImagePalette
import numpy
from math import ceil
def read_header(file):
return file.read(4).decode('ascii')
def read_u32(file):
return struct.unpack('I', file.read(4))[0]
def read_u16(file):
return struct.unpack('H', file.read(2))[0]
def read_u8(file):
return struct.unpack('B', file.read(1))[0]
def read_s8(file):
return struct.unpack('b', file.read(1))[0]
def read_rgb(file):
return struct.unpack('BBB', file.read(3))
class MaskCommand:
def __init__(self, value):
self.newline = (value & 0b10000000) != 0;
self.colored = (value & 0b01000000) != 0;
self.length = value & 0b00111111;
class ActorImage:
def __init__(self, width, height, mask_commands, colors):
self.width = width
self.height = height
self.create_data(mask_commands, colors)
def create_data(self, mask_commands, colors):
self.data = [(0, 0, 0, 0) for i in range(self.width*self.height)]
pointer = {'x':0, 'y':0}
colors_iter = iter(colors)
for command in mask_commands:
if command.newline:
pointer['x'] = 0
pointer['y'] += 1
if command.colored:
for i in range(command.length):
color = palette[next(colors_iter)]
rgba_color = (color[0], color[1], color[2], 255)
pos = pointer['y']*self.width + pointer['x']
self.data[pos] = rgba_color
pointer['x'] += 1
else:
pointer['x'] += command.length
def save_image(self, index):
im = Image.new(mode='RGBA', size=(self.width, self.height))
im.putdata(self.data)
if not os.path.exists(base_name):
os.mkdir(base_name)
filepath = os.path.join(base_name, 'act' + str(index) + ".png")
im.save(filepath)
base_name = os.path.splitext(sys.argv[1])[0]
palettefile = ''
palette = list()
if len(sys.argv) < 3:
palettefile = base_name + ".PAL"
else:
palettefile = sys.argv[2]
if not os.path.exists(palettefile):
print("Warning: palette " + palettefile + " does not exist. Using grayscale.")
palette = [(i, i, i) for i in range(256)]
else:
with open(palettefile, 'br') as palfile:
for i in range(256):
palette.append(read_rgb(palfile))
images = list()
with open(sys.argv[1], "br") as picfile:
header = read_header(picfile)
if header != "UNC2":
print("This script supports only UNC2 files, this file is of type: " + header)
exit()
image_count = read_u16(picfile)
total_data_size = read_u32(picfile)
read_u32(picfile) # unknown
for pic_index in range(image_count):
image_width = read_u16(picfile)
image_height = read_u8(picfile)
# unknown values
read_u32(picfile)
read_u32(picfile)
read_u8(picfile)
lines_data_size = read_u16(picfile)
colors_data_size = read_u16(picfile)
mask_commands = list()
for i in range(lines_data_size):
mask_value = read_u8(picfile)
mask_commands.append(MaskCommand(mask_value))
#read_u8(picfile) # empty 0x00 separator
colors = list()
for i in range(colors_data_size):
colors.append(read_u8(picfile))
image = ActorImage(image_width, image_height, mask_commands, colors)
image.save_image(pic_index)