def uncompress(cls, input_stream, file_size, mem_size): output_stream = BytesIO() br = StreamReader(input_stream) end = input_stream.tell() + file_size data = br.bytes(2) data_len = (4 if ((data[0] & 0x80) != 0) else 3) * (2 if ( (data[0] & 0x01) != 0) else 1) data = br.bytes(data_len) real_size = 0 for i in range(data_len): real_size = (real_size << 8) + data[i] assert real_size == mem_size while input_stream.tell() < end: copy_size = 0 copy_offset = 0 packing = br.u8() if packing < 0x80: data = br.bytes(1) data_len = packing & 0x03 copy_size = ((packing >> 2) & 0x07) + 3 copy_offset = (((packing << 3) & 0x300) | data[0]) + 1 elif packing < 0xC0: data = br.bytes(2) data_len = (data[0] >> 6) & 0x03 copy_size = (packing & 0x3F) + 4 copy_offset = (((data[0] << 8) & 0x3F00) | data[1]) + 1 elif packing < 0xE0: data = br.bytes(3) data_len = packing & 0x03 copy_size = (((packing << 6) & 0x300) | data[2]) + 5 copy_offset = (((packing << 12) & 0x10000) | data[0] << 8 | data[1]) + 1 elif packing < 0xFC: data_len = (((packing & 0x1F) + 1) << 2) else: data_len = packing & 0x03 if data_len > 0: output_stream.write(input_stream.read(data_len)) if copy_size < copy_offset > 8: cls.copy_a(output_stream, copy_offset, copy_size) else: cls.copy_b(output_stream, copy_offset, copy_size) output_stream.seek(0, SEEK_SET) return output_stream
def uncompress(cls,input_stream, file_size, mem_size): output_stream = BytesIO() br = StreamReader(input_stream) end = input_stream.tell() + file_size data = br.bytes(2) data_len = (4 if ((data[0] & 0x80) != 0) else 3 ) * ( 2 if ((data[0] & 0x01) != 0) else 1 ) data = br.bytes(data_len) real_size = 0 for i in range(data_len): real_size = (real_size << 8) + data[i] assert real_size == mem_size while input_stream.tell() < end: copy_size = 0 copy_offset = 0 packing = br.u8() if packing < 0x80: data = br.bytes(1) data_len = packing & 0x03 copy_size = ((packing >> 2) & 0x07) + 3 copy_offset = (((packing << 3) & 0x300) | data[0]) + 1 elif packing < 0xC0: data = br.bytes(2) data_len = (data[0] >> 6) & 0x03 copy_size = (packing & 0x3F) + 4 copy_offset = (((data[0] << 8) & 0x3F00) | data[1]) + 1 elif packing < 0xE0: data = br.bytes(3) data_len = packing & 0x03 copy_size = (((packing << 6) & 0x300) | data[2]) + 5 copy_offset = (((packing << 12) & 0x10000) | data[0] << 8 | data[1]) + 1 elif packing < 0xFC: data_len = (((packing & 0x1F) + 1) << 2) else: data_len = packing & 0x03 if data_len > 0: output_stream.write(input_stream.read(data_len)) if copy_size < copy_offset > 8: cls.copy_a(output_stream, copy_offset, copy_size) else: cls.copy_b(output_stream, copy_offset, copy_size) output_stream.seek(0, SEEK_SET) return output_stream