from common import * # Copyright (c) 2008 Hector Martin # 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(">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("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