mirror of
https://github.com/grp/Wii.py.git
synced 2025-06-18 06:45:46 -04:00
83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
from common import *
|
|
|
|
# Copyright (c) 2008 Hector Martin <marcan@marcansoft.com>
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without modification,
|
|
# are permitted provided that the following conditions are met:
|
|
#
|
|
# * Redistributions of source code must retain the above copyright notice, this
|
|
# list of conditions and the following disclaimer.
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
# and/or other materials provided with the distribution.
|
|
# * The name of the author may not be used to endorse or promote products derived
|
|
# from this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
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(self.data)
|
|
file.seek(4)
|
|
unc = self.WiiLZ77(file, file.tell())
|
|
data = unc.uncompress()
|
|
|
|
return data
|
|
def compress(self, fn = ""):
|
|
raise NotImplementedError
|