qwad/WiiPy/compression.py
2012-08-21 19:28:14 +02:00

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