-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathResDecompress.py
More file actions
76 lines (59 loc) · 2.13 KB
/
ResDecompress.py
File metadata and controls
76 lines (59 loc) · 2.13 KB
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
'''
Handling of compressed MacOS resources.
Author: Max Poliakovski 2018
'''
import struct
from DonnBits import DonnDecompress
from GreggBits import GreggDecompress, GreggCompress
from InstaCompOne import InstaCompDecompress
def GetEncoding(dat):
sig, hdrlen, vers, attrs, biglen = struct.unpack_from(">IHBBI", dat)
if sig != 0xA89F6572:
print("Invalid extended resource header sig: 0x%X" % sig)
return 'UnknownCompression'
if vers not in (8, 9):
print("Unknown ext res header format: %d" % vers)
return 'UnknownCompression'
if attrs & 1 == 0:
print("extAttributes,bit0 isn't set. Treat this res as uncompressed.")
return 'UnknownCompression'
print("Uncompressed length: %d" % biglen)
if vers == 8:
return 'DonnBits'
elif vers == 9:
if dat[12:14] == b'\x00\x02':
return 'GreggyBits'
elif dat[12:14] == b'\x00\x03':
return 'InstaCompOne'
else:
return 'UnknownCompression'
else:
return 'UnknownCompression'
def DecompressResource(dat):
encoding = GetEncoding(dat)
sig, hdrlen, vers, attrs, biglen = struct.unpack_from(">IHBBI", dat)
if encoding == 'DonnBits':
dst = bytearray()
DonnDecompress(dat, dst, unpackSize=biglen, pos=12)
return bytes(dst)
elif encoding == 'GreggyBits':
dst = bytearray()
GreggDecompress(dat, dst, unpackSize=biglen, pos=12)
return bytes(dst)
elif encoding == 'InstaCompOne':
dst = bytearray()
InstaCompDecompress(dat, dst, unpackSize=biglen, pos=14)
return bytes(dst)
elif encoding == 'UnknownCompression':
return dat # passthru
def CompressResource(dat, encoding):
if encoding == 'UnknownCompression':
return dat
elif encoding == 'GreggyBits':
dst = bytearray()
# re-create extended resource header
dst.extend([0xA8, 0x9F, 0x65, 0x72, 0x00, 0x12, 0x09, 0x01])
dst.extend(len(dat).to_bytes(4, 'big'))
# leave Gregg-specific header to the compressor
GreggCompress(dat, dst)
return bytes(dst)