mirror of
https://gitlab.com/Nanolx/qwad.git
synced 2024-11-25 12:06:55 +01:00
57 lines
1.4 KiB
Python
57 lines
1.4 KiB
Python
from common import *
|
|
|
|
class LZ77(WiiHeader):
|
|
class WiiLZ77: # class by marcan, used under scope of BSD license
|
|
TYPE_LZ77 = 1
|
|
def __init__(self, file, offset):
|
|
self.file = file
|
|
self.offset = offset
|
|
|
|
self.file.seek(self.offset)
|
|
|
|
hdr = struct.unpack("<I",self.file.read(4))[0]
|
|
self.uncompressed_length = hdr>>8
|
|
self.compression_type = hdr>>4 & 0xF
|
|
|
|
if self.compression_type != self.TYPE_LZ77:
|
|
raise ValueError("Unsupported compression method %d"%self.compression_type)
|
|
|
|
def uncompress(self):
|
|
dout = ""
|
|
|
|
self.file.seek(self.offset + 0x4)
|
|
|
|
while len(dout) < self.uncompressed_length:
|
|
flags = struct.unpack("<B",self.file.read(1))[0]
|
|
|
|
for i in range(8):
|
|
if flags & 0x80:
|
|
info = struct.unpack(">H",self.file.read(2))[0]
|
|
num = 3 + ((info>>12)&0xF)
|
|
disp = info & 0xFFF
|
|
ptr = len(dout) - (info & 0xFFF) - 1
|
|
for i in range(num):
|
|
dout += dout[ptr]
|
|
ptr+=1
|
|
if len(dout) >= self.uncompressed_length:
|
|
break
|
|
else:
|
|
dout += self.file.read(1)
|
|
flags <<= 1
|
|
if len(dout) >= self.uncompressed_length:
|
|
break
|
|
self.data = dout
|
|
return self.data
|
|
def remove(self):
|
|
hdr = self.data[:4]
|
|
if hdr != "LZ77":
|
|
return self.data
|
|
file = StringIO.StringIO(self.data)
|
|
file.seek(4)
|
|
unc = self.WiiLZ77(file, file.tell())
|
|
data = unc.uncompress()
|
|
|
|
return data
|
|
def compress(self, fn = ""):
|
|
raise NotImplementedError
|