forked from scummvm-director/continuity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dutils.py
123 lines (109 loc) · 2.99 KB
/
dutils.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
111
112
113
114
115
116
117
118
119
120
121
import struct
from StringIO import StringIO
def read32(f, le=False):
x = f.read(4)
if le:
return struct.unpack("<I", x)[0]
else:
return struct.unpack(">I", x)[0]
def read16(f, signed=False):
x = f.read(2)
if signed:
return struct.unpack(">h", x)[0]
else:
return struct.unpack(">H", x)[0]
def read8(f):
x = f.read(1)
return struct.unpack("<B", x)[0]
def readString(f):
s = read8(f)
return f.read(s)
def getString(s):
if len(s) == 0:
return s
l = ord(s[0])
if l == 0:
assert len(s) == 1
return ""
s = s[1:]
if s[-1] == '\x00':
s = s[:-1]
assert l == len(s)
return s
class Rect:
def width(self):
return self.right - self.left
def height(self):
return self.bottom - self.top
def __str__(self):
return "(%d, %d, %d, %d)" % (self.left, self.top, self.right, self.bottom)
def readRect(f):
r = Rect()
r.top = read16(f,True)
r.left = read16(f,True)
r.bottom = read16(f,True)
r.right = read16(f,True)
return r
def getPaletteFor(pos, movie):
palentries = 256
palette = ""
palId = 0
for n in range(pos+1):
if movie.frames[n].palette != 0:
palId = movie.frames[n].palette
if palId != 0 and 'CLUT' in movie.resources:
for p in movie.resources['CLUT']:
if p.rid == palId + 1024:
p.seek(0)
d = p.read()
for i in range(len(d)/6):
l = len(d)/6
n = l - i - 1
if i >= palentries:
break
palette = palette + d[n*6+4] + d[n*6+2] + d[n*6] + '\x00'
while len(palette) < 4*palentries:
palette = palette + '\x00'
else:
pf = open("data/mac.pal")
pf.read(6) # 0:seed,4:flags
assert read16(pf)+1 == 256 # count
pf = pf.read()
n = 0
for e in range(palentries):
ee = 255 - e
# high bytes of uint16s, ignore the first
# palette = palette + pf[e*8+6] + pf[e*8+4] + pf[e*8+2] + '\x00'
palette = palette + pf[ee*8+6] + pf[ee*8+4] + pf[ee*8+2] + '\x00'
return palette
import struct
def imageFromDIB(data, palette):
# fake a stupid BMP (sigh)
assert ord(data[0]) == 40 and ord(data[1]) == 0 # size
depth = ord(data[14])
width, height = struct.unpack("<Ii", data[4:12])
assert depth == 1 or depth == 4 or depth == 8
palentries = ord(data[32]) + (ord(data[33]) << 8)
if palentries == 0:
# palentries = 2**depth
palentries = 256
else:
# FIXME
print "WARNING: palentries %d" % palentries
totalsize = 14 + len(data) + len(palette)
offset = 14 + 40 + len(palette)
rawdata = data[40:]
if depth == 1:
# 1bpp handled differently: always top-down
if height > 0:
data = data[:8] + struct.pack("<i", -height) + data[12:]
# 1bpp handled differently: word padding, so we have to expand to dword padding
oldrawdata = rawdata
rawdata = ""
realwidth = ((width+7)/8)
realwidth = ((realwidth+1)/2)*2
neededwidth = ((realwidth+3)/4)*4
for n in range(height):
rawdata = rawdata + oldrawdata[n*realwidth:n*realwidth+realwidth] + '\x00' * (neededwidth - realwidth)
dibdata = "BM" + struct.pack("<III", totalsize, 0, offset) + data[:40] + palette + rawdata
return dibdata