Module refinery.units.compression.pkw

Expand source code Browse git
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import annotations

from refinery.units import Unit, RefineryPartialResult
from refinery.lib.structures import StructReader, MemoryFile


class pkw(Unit):
    """
    This unit implements PKWare decompression.
    """
    def process(self, data):

        def read_from_table(table: dict[tuple[int, int], int], start: int, stop: int):
            value = length = 0
            while length < start:
                value <<= 1
                value |= getint(1)
                length += 1
            while length < stop:
                try:
                    return table[length, value]
                except KeyError:
                    value <<= 1
                    value |= getint(1)
                    length += 1
            raise ValueError(
                'Failed to decode a symbol in the compressed data stream.')

        reader = StructReader(data)
        codelit = reader.u8()  # First byte is 0 if literals are uncoded, otherwise 1
        maxdict = reader.u8()  # Second byte is 4, 5, or 6 (max size of dictionary)

        if not 0 <= codelit <= 1:
            raise ValueError(F'Invalid literal encoding value {codelit}.')

        if not 4 <= maxdict <= 6:
            raise ValueError(F'Invalid dictionary size {maxdict}.')

        output = MemoryFile()
        getint = reader.read_integer

        while not reader.eof:
            try:
                if not getint(1):
                    if codelit:
                        code = read_from_table(_LITERALS, 4, 14)
                    else:
                        code = getint(8)
                    output.write_byte(code)
                else:
                    length = read_from_table(_COPY_LENGTHS, 2, 0x10)
                    if length == 519:
                        break
                    offset = read_from_table(_COPY_OFFSETS, 2, 0x09)
                    more = (2 if length == 2 else maxdict)
                    offset <<= more
                    offset += getint(more)
                    offset += 1
                    output.replay(offset, length)
            except Exception as E:
                if not (out := output.getvalue()):
                    raise
                raise RefineryPartialResult(str(E), out) from E

        return output.getvalue()

    @classmethod
    def handles(self, data: bytearray) -> bool:
        return (len(data) > 2) and (0 <= data[0] <= 1) and (4 <= data[1] <= 6)


_LITERALS = {
    (0x4, 0b0001111): 0x20,
    (0x5, 0b0011101): 0x45,
    (0x5, 0b0011100): 0x61,
    (0x5, 0b0011011): 0x65,
    (0x5, 0b0011010): 0x69,
    (0x5, 0b0011001): 0x6c,
    (0x5, 0b0011000): 0x6e,
    (0x5, 0b0010111): 0x6f,
    (0x5, 0b0010110): 0x72,
    (0x5, 0b0010101): 0x73,
    (0x5, 0b0010100): 0x74,
    (0x5, 0b0010011): 0x75,
    (0x6, 0b0100101): 0x2d,
    (0x6, 0b0100100): 0x31,
    (0x6, 0b0100011): 0x41,
    (0x6, 0b0100010): 0x43,
    (0x6, 0b0100001): 0x44,
    (0x6, 0b0100000): 0x49,
    (0x6, 0b0011111): 0x4c,
    (0x6, 0b0011110): 0x4e,
    (0x6, 0b0011101): 0x4f,
    (0x6, 0b0011100): 0x52,
    (0x6, 0b0011011): 0x53,
    (0x6, 0b0011010): 0x54,
    (0x6, 0b0011001): 0x62,
    (0x6, 0b0011000): 0x63,
    (0x6, 0b0010111): 0x64,
    (0x6, 0b0010110): 0x66,
    (0x6, 0b0010101): 0x67,
    (0x6, 0b0010100): 0x68,
    (0x6, 0b0010011): 0x6d,
    (0x6, 0b0010010): 0x70,
    (0x7, 0b0100011): 0x0a,
    (0x7, 0b0100010): 0x0d,
    (0x7, 0b0100001): 0x28,
    (0x7, 0b0100000): 0x29,
    (0x7, 0b0011111): 0x2c,
    (0x7, 0b0011110): 0x2e,
    (0x7, 0b0011101): 0x30,
    (0x7, 0b0011100): 0x32,
    (0x7, 0b0011011): 0x33,
    (0x7, 0b0011010): 0x34,
    (0x7, 0b0011001): 0x35,
    (0x7, 0b0011000): 0x37,
    (0x7, 0b0010111): 0x38,
    (0x7, 0b0010110): 0x3d,
    (0x7, 0b0010101): 0x42,
    (0x7, 0b0010100): 0x46,
    (0x7, 0b0010011): 0x4d,
    (0x7, 0b0010010): 0x50,
    (0x7, 0b0010001): 0x55,
    (0x7, 0b0010000): 0x6b,
    (0x7, 0b0001111): 0x77,
    (0x8, 0b0011101): 0x09,
    (0x8, 0b0011100): 0x22,
    (0x8, 0b0011011): 0x27,
    (0x8, 0b0011010): 0x2a,
    (0x8, 0b0011001): 0x2f,
    (0x8, 0b0011000): 0x36,
    (0x8, 0b0010111): 0x39,
    (0x8, 0b0010110): 0x3a,
    (0x8, 0b0010101): 0x47,
    (0x8, 0b0010100): 0x48,
    (0x8, 0b0010011): 0x57,
    (0x8, 0b0010010): 0x5b,
    (0x8, 0b0010001): 0x5f,
    (0x8, 0b0010000): 0x76,
    (0x8, 0b0001111): 0x78,
    (0x8, 0b0001110): 0x79,
    (0x9, 0b0011011): 0x2b,
    (0x9, 0b0011010): 0x3e,
    (0x9, 0b0011001): 0x4b,
    (0x9, 0b0011000): 0x56,
    (0x9, 0b0010111): 0x58,
    (0x9, 0b0010110): 0x59,
    (0x9, 0b0010101): 0x5d,
    (0xA, 0b0101001): 0x21,
    (0xA, 0b0101000): 0x24,
    (0xA, 0b0100111): 0x26,
    (0xA, 0b0100110): 0x71,
    (0xA, 0b0100101): 0x7a,
    (0xB, 0b1001001): 0x00,
    (0xB, 0b1001000): 0x3c,
    (0xB, 0b1000111): 0x3f,
    (0xB, 0b1000110): 0x4a,
    (0xB, 0b1000101): 0x51,
    (0xB, 0b1000100): 0x5a,
    (0xB, 0b1000011): 0x5c,
    (0xB, 0b1000010): 0x6a,
    (0xB, 0b1000001): 0x7b,
    (0xB, 0b1000000): 0x7c,
    (0xC, 0b1111111): 0x01,
    (0xC, 0b1111110): 0x02,
    (0xC, 0b1111101): 0x03,
    (0xC, 0b1111100): 0x04,
    (0xC, 0b1111011): 0x05,
    (0xC, 0b1111010): 0x06,
    (0xC, 0b1111001): 0x07,
    (0xC, 0b1111000): 0x08,
    (0xC, 0b1110111): 0x0b,
    (0xC, 0b1110110): 0x0c,
    (0xC, 0b1110101): 0x0e,
    (0xC, 0b1110100): 0x0f,
    (0xC, 0b1110011): 0x10,
    (0xC, 0b1110010): 0x11,
    (0xC, 0b1110001): 0x12,
    (0xC, 0b1110000): 0x13,
    (0xC, 0b1101111): 0x14,
    (0xC, 0b1101110): 0x15,
    (0xC, 0b1101101): 0x16,
    (0xC, 0b1101100): 0x17,
    (0xC, 0b1101011): 0x18,
    (0xC, 0b1101010): 0x19,
    (0xC, 0b1101001): 0x1b,
    (0xC, 0b1101000): 0x1c,
    (0xC, 0b1100111): 0x1d,
    (0xC, 0b1100110): 0x1e,
    (0xC, 0b1100101): 0x1f,
    (0xC, 0b1100100): 0x23,
    (0xC, 0b1100011): 0x25,
    (0xC, 0b1100010): 0x3b,
    (0xC, 0b1100001): 0x40,
    (0xC, 0b1100000): 0x5e,
    (0xC, 0b1011111): 0x60,
    (0xC, 0b1011110): 0x7d,
    (0xC, 0b1011101): 0x7e,
    (0xC, 0b1011100): 0x7f,
    (0xC, 0b1011011): 0xb0,
    (0xC, 0b1011010): 0xb1,
    (0xC, 0b1011001): 0xb2,
    (0xC, 0b1011000): 0xb3,
    (0xC, 0b1010111): 0xb4,
    (0xC, 0b1010110): 0xb5,
    (0xC, 0b1010101): 0xb6,
    (0xC, 0b1010100): 0xb7,
    (0xC, 0b1010011): 0xb8,
    (0xC, 0b1010010): 0xb9,
    (0xC, 0b1010001): 0xba,
    (0xC, 0b1010000): 0xbb,
    (0xC, 0b1001111): 0xbc,
    (0xC, 0b1001110): 0xbd,
    (0xC, 0b1001101): 0xbe,
    (0xC, 0b1001100): 0xbf,
    (0xC, 0b1001011): 0xc0,
    (0xC, 0b1001010): 0xc1,
    (0xC, 0b1001001): 0xc2,
    (0xC, 0b1001000): 0xc3,
    (0xC, 0b1000111): 0xc4,
    (0xC, 0b1000110): 0xc5,
    (0xC, 0b1000101): 0xc6,
    (0xC, 0b1000100): 0xc7,
    (0xC, 0b1000011): 0xc8,
    (0xC, 0b1000010): 0xc9,
    (0xC, 0b1000001): 0xca,
    (0xC, 0b1000000): 0xcb,
    (0xC, 0b0111111): 0xcc,
    (0xC, 0b0111110): 0xcd,
    (0xC, 0b0111101): 0xce,
    (0xC, 0b0111100): 0xcf,
    (0xC, 0b0111011): 0xd0,
    (0xC, 0b0111010): 0xd1,
    (0xC, 0b0111001): 0xd2,
    (0xC, 0b0111000): 0xd3,
    (0xC, 0b0110111): 0xd4,
    (0xC, 0b0110110): 0xd5,
    (0xC, 0b0110101): 0xd6,
    (0xC, 0b0110100): 0xd7,
    (0xC, 0b0110011): 0xd8,
    (0xC, 0b0110010): 0xd9,
    (0xC, 0b0110001): 0xda,
    (0xC, 0b0110000): 0xdb,
    (0xC, 0b0101111): 0xdc,
    (0xC, 0b0101110): 0xdd,
    (0xC, 0b0101101): 0xde,
    (0xC, 0b0101100): 0xdf,
    (0xC, 0b0101011): 0xe1,
    (0xC, 0b0101010): 0xe5,
    (0xC, 0b0101001): 0xe9,
    (0xC, 0b0101000): 0xee,
    (0xC, 0b0100111): 0xf2,
    (0xC, 0b0100110): 0xf3,
    (0xC, 0b0100101): 0xf4,
    (0xD, 0b1001001): 0x1a,
    (0xD, 0b1001000): 0x80,
    (0xD, 0b1000111): 0x81,
    (0xD, 0b1000110): 0x82,
    (0xD, 0b1000101): 0x83,
    (0xD, 0b1000100): 0x84,
    (0xD, 0b1000011): 0x85,
    (0xD, 0b1000010): 0x86,
    (0xD, 0b1000001): 0x87,
    (0xD, 0b1000000): 0x88,
    (0xD, 0b0111111): 0x89,
    (0xD, 0b0111110): 0x8a,
    (0xD, 0b0111101): 0x8b,
    (0xD, 0b0111100): 0x8c,
    (0xD, 0b0111011): 0x8d,
    (0xD, 0b0111010): 0x8e,
    (0xD, 0b0111001): 0x8f,
    (0xD, 0b0111000): 0x90,
    (0xD, 0b0110111): 0x91,
    (0xD, 0b0110110): 0x92,
    (0xD, 0b0110101): 0x93,
    (0xD, 0b0110100): 0x94,
    (0xD, 0b0110011): 0x95,
    (0xD, 0b0110010): 0x96,
    (0xD, 0b0110001): 0x97,
    (0xD, 0b0110000): 0x98,
    (0xD, 0b0101111): 0x99,
    (0xD, 0b0101110): 0x9a,
    (0xD, 0b0101101): 0x9b,
    (0xD, 0b0101100): 0x9c,
    (0xD, 0b0101011): 0x9d,
    (0xD, 0b0101010): 0x9e,
    (0xD, 0b0101001): 0x9f,
    (0xD, 0b0101000): 0xa0,
    (0xD, 0b0100111): 0xa1,
    (0xD, 0b0100110): 0xa2,
    (0xD, 0b0100101): 0xa3,
    (0xD, 0b0100100): 0xa4,
    (0xD, 0b0100011): 0xa5,
    (0xD, 0b0100010): 0xa6,
    (0xD, 0b0100001): 0xa7,
    (0xD, 0b0100000): 0xa8,
    (0xD, 0b0011111): 0xa9,
    (0xD, 0b0011110): 0xaa,
    (0xD, 0b0011101): 0xab,
    (0xD, 0b0011100): 0xac,
    (0xD, 0b0011011): 0xad,
    (0xD, 0b0011010): 0xae,
    (0xD, 0b0011001): 0xaf,
    (0xD, 0b0011000): 0xe0,
    (0xD, 0b0010111): 0xe2,
    (0xD, 0b0010110): 0xe3,
    (0xD, 0b0010101): 0xe4,
    (0xD, 0b0010100): 0xe6,
    (0xD, 0b0010011): 0xe7,
    (0xD, 0b0010010): 0xe8,
    (0xD, 0b0010001): 0xea,
    (0xD, 0b0010000): 0xeb,
    (0xD, 0b0001111): 0xec,
    (0xD, 0b0001110): 0xed,
    (0xD, 0b0001101): 0xef,
    (0xD, 0b0001100): 0xf0,
    (0xD, 0b0001011): 0xf1,
    (0xD, 0b0001010): 0xf5,
    (0xD, 0b0001001): 0xf6,
    (0xD, 0b0001000): 0xf7,
    (0xD, 0b0000111): 0xf8,
    (0xD, 0b0000110): 0xf9,
    (0xD, 0b0000101): 0xfa,
    (0xD, 0b0000100): 0xfb,
    (0xD, 0b0000011): 0xfc,
    (0xD, 0b0000010): 0xfd,
    (0xD, 0b0000001): 0xfe,
    (0xD, 0b0000000): 0xff,
}

_COPY_OFFSETS = {
    (2, 0b00000011): 0x00,
    (4, 0b00001011): 0x01,
    (4, 0b00001010): 0x02,
    (5, 0b00010011): 0x03,
    (5, 0b00010010): 0x04,
    (5, 0b00010001): 0x05,
    (5, 0b00010000): 0x06,
    (6, 0b00011111): 0x07,
    (6, 0b00011110): 0x08,
    (6, 0b00011101): 0x09,
    (6, 0b00011100): 0x0a,
    (6, 0b00011011): 0x0b,
    (6, 0b00011010): 0x0c,
    (6, 0b00011001): 0x0d,
    (6, 0b00011000): 0x0e,
    (6, 0b00010111): 0x0f,
    (6, 0b00010110): 0x10,
    (6, 0b00010101): 0x11,
    (6, 0b00010100): 0x12,
    (6, 0b00010011): 0x13,
    (6, 0b00010010): 0x14,
    (6, 0b00010001): 0x15,
    (7, 0b00100001): 0x16,
    (7, 0b00100000): 0x17,
    (7, 0b00011111): 0x18,
    (7, 0b00011110): 0x19,
    (7, 0b00011101): 0x1a,
    (7, 0b00011100): 0x1b,
    (7, 0b00011011): 0x1c,
    (7, 0b00011010): 0x1d,
    (7, 0b00011001): 0x1e,
    (7, 0b00011000): 0x1f,
    (7, 0b00010111): 0x20,
    (7, 0b00010110): 0x21,
    (7, 0b00010101): 0x22,
    (7, 0b00010100): 0x23,
    (7, 0b00010011): 0x24,
    (7, 0b00010010): 0x25,
    (7, 0b00010001): 0x26,
    (7, 0b00010000): 0x27,
    (7, 0b00001111): 0x28,
    (7, 0b00001110): 0x29,
    (7, 0b00001101): 0x2a,
    (7, 0b00001100): 0x2b,
    (7, 0b00001011): 0x2c,
    (7, 0b00001010): 0x2d,
    (7, 0b00001001): 0x2e,
    (7, 0b00001000): 0x2f,
    (8, 0b00001111): 0x30,
    (8, 0b00001110): 0x31,
    (8, 0b00001101): 0x32,
    (8, 0b00001100): 0x33,
    (8, 0b00001011): 0x34,
    (8, 0b00001010): 0x35,
    (8, 0b00001001): 0x36,
    (8, 0b00001000): 0x37,
    (8, 0b00000111): 0x38,
    (8, 0b00000110): 0x39,
    (8, 0b00000101): 0x3a,
    (8, 0b00000100): 0x3b,
    (8, 0b00000011): 0x3c,
    (8, 0b00000010): 0x3d,
    (8, 0b00000001): 0x3e,
    (8, 0b00000000): 0x3f
}

_COPY_LENGTHS = {
    (0x2, 0b00000011): 3,
    (0x3, 0b00000101): 2,
    (0x3, 0b00000100): 4,
    (0x3, 0b00000011): 5,
    (0x4, 0b00000101): 6,
    (0x4, 0b00000100): 7,
    (0x4, 0b00000011): 8,
    (0x5, 0b00000101): 9,
    (0x6, 0b00001001): 11,
    (0x6, 0b00001000): 10,
    (0x7, 0b00001111): 15,
    (0x7, 0b00001110): 13,
    (0x7, 0b00001101): 14,
    (0x7, 0b00001100): 12,
    (0x8, 0b00010111): 23,
    (0x8, 0b00010110): 19,
    (0x8, 0b00010101): 21,
    (0x8, 0b00010100): 17,
    (0x8, 0b00010011): 22,
    (0x8, 0b00010010): 18,
    (0x8, 0b00010001): 20,
    (0x8, 0b00010000): 16,
    (0xA, 0b00111111): 39,
    (0xA, 0b00111110): 31,
    (0xA, 0b00111101): 35,
    (0xA, 0b00111100): 27,
    (0xA, 0b00111011): 37,
    (0xA, 0b00111010): 29,
    (0xA, 0b00111001): 33,
    (0xA, 0b00111000): 25,
    (0xA, 0b00110111): 38,
    (0xA, 0b00110110): 30,
    (0xA, 0b00110101): 34,
    (0xA, 0b00110100): 26,
    (0xA, 0b00110011): 36,
    (0xA, 0b00110010): 28,
    (0xA, 0b00110001): 32,
    (0xA, 0b00110000): 24,
    (0xB, 0b01011111): 71,
    (0xB, 0b01011110): 55,
    (0xB, 0b01011101): 63,
    (0xB, 0b01011100): 47,
    (0xB, 0b01011011): 67,
    (0xB, 0b01011010): 51,
    (0xB, 0b01011001): 59,
    (0xB, 0b01011000): 43,
    (0xB, 0b01010111): 69,
    (0xB, 0b01010110): 53,
    (0xB, 0b01010101): 61,
    (0xB, 0b01010100): 45,
    (0xB, 0b01010011): 65,
    (0xB, 0b01010010): 49,
    (0xB, 0b01010001): 57,
    (0xB, 0b01010000): 41,
    (0xB, 0b01001111): 70,
    (0xB, 0b01001110): 54,
    (0xB, 0b01001101): 62,
    (0xB, 0b01001100): 46,
    (0xB, 0b01001011): 66,
    (0xB, 0b01001010): 50,
    (0xB, 0b01001001): 58,
    (0xB, 0b01001000): 42,
    (0xB, 0b01000111): 68,
    (0xB, 0b01000110): 52,
    (0xB, 0b01000101): 60,
    (0xB, 0b01000100): 44,
    (0xB, 0b01000011): 64,
    (0xB, 0b01000010): 48,
    (0xB, 0b01000001): 56,
    (0xB, 0b01000000): 40,
    (0xC, 0b01111111): 135,
    (0xC, 0b01111110): 103,
    (0xC, 0b01111101): 119,
    (0xC, 0b01111100): 87,
    (0xC, 0b01111011): 127,
    (0xC, 0b01111010): 95,
    (0xC, 0b01111001): 111,
    (0xC, 0b01111000): 79,
    (0xC, 0b01110111): 131,
    (0xC, 0b01110110): 99,
    (0xC, 0b01110101): 115,
    (0xC, 0b01110100): 83,
    (0xC, 0b01110011): 123,
    (0xC, 0b01110010): 91,
    (0xC, 0b01110001): 107,
    (0xC, 0b01110000): 75,
    (0xC, 0b01101111): 133,
    (0xC, 0b01101110): 101,
    (0xC, 0b01101101): 117,
    (0xC, 0b01101100): 85,
    (0xC, 0b01101011): 125,
    (0xC, 0b01101010): 93,
    (0xC, 0b01101001): 109,
    (0xC, 0b01101000): 77,
    (0xC, 0b01100111): 129,
    (0xC, 0b01100110): 97,
    (0xC, 0b01100101): 113,
    (0xC, 0b01100100): 81,
    (0xC, 0b01100011): 121,
    (0xC, 0b01100010): 89,
    (0xC, 0b01100001): 105,
    (0xC, 0b01100000): 73,
    (0xC, 0b01011111): 134,
    (0xC, 0b01011110): 102,
    (0xC, 0b01011101): 118,
    (0xC, 0b01011100): 86,
    (0xC, 0b01011011): 126,
    (0xC, 0b01011010): 94,
    (0xC, 0b01011001): 110,
    (0xC, 0b01011000): 78,
    (0xC, 0b01010111): 130,
    (0xC, 0b01010110): 98,
    (0xC, 0b01010101): 114,
    (0xC, 0b01010100): 82,
    (0xC, 0b01010011): 122,
    (0xC, 0b01010010): 90,
    (0xC, 0b01010001): 106,
    (0xC, 0b01010000): 74,
    (0xC, 0b01001111): 132,
    (0xC, 0b01001110): 100,
    (0xC, 0b01001101): 116,
    (0xC, 0b01001100): 84,
    (0xC, 0b01001011): 124,
    (0xC, 0b01001010): 92,
    (0xC, 0b01001001): 108,
    (0xC, 0b01001000): 76,
    (0xC, 0b01000111): 128,
    (0xC, 0b01000110): 96,
    (0xC, 0b01000101): 112,
    (0xC, 0b01000100): 80,
    (0xC, 0b01000011): 120,
    (0xC, 0b01000010): 88,
    (0xC, 0b01000001): 104,
    (0xC, 0b01000000): 72,
    (0xE, 0b11111111): 263,
    (0xE, 0b11111110): 199,
    (0xE, 0b11111101): 231,
    (0xE, 0b11111100): 167,
    (0xE, 0b11111011): 247,
    (0xE, 0b11111010): 183,
    (0xE, 0b11111001): 215,
    (0xE, 0b11111000): 151,
    (0xE, 0b11110111): 255,
    (0xE, 0b11110110): 191,
    (0xE, 0b11110101): 223,
    (0xE, 0b11110100): 159,
    (0xE, 0b11110011): 239,
    (0xE, 0b11110010): 175,
    (0xE, 0b11110001): 207,
    (0xE, 0b11110000): 143,
    (0xE, 0b11101111): 259,
    (0xE, 0b11101110): 195,
    (0xE, 0b11101101): 227,
    (0xE, 0b11101100): 163,
    (0xE, 0b11101011): 243,
    (0xE, 0b11101010): 179,
    (0xE, 0b11101001): 211,
    (0xE, 0b11101000): 147,
    (0xE, 0b11100111): 251,
    (0xE, 0b11100110): 187,
    (0xE, 0b11100101): 219,
    (0xE, 0b11100100): 155,
    (0xE, 0b11100011): 235,
    (0xE, 0b11100010): 171,
    (0xE, 0b11100001): 203,
    (0xE, 0b11100000): 139,
    (0xE, 0b11011111): 261,
    (0xE, 0b11011110): 197,
    (0xE, 0b11011101): 229,
    (0xE, 0b11011100): 165,
    (0xE, 0b11011011): 245,
    (0xE, 0b11011010): 181,
    (0xE, 0b11011001): 213,
    (0xE, 0b11011000): 149,
    (0xE, 0b11010111): 253,
    (0xE, 0b11010110): 189,
    (0xE, 0b11010101): 221,
    (0xE, 0b11010100): 157,
    (0xE, 0b11010011): 237,
    (0xE, 0b11010010): 173,
    (0xE, 0b11010001): 205,
    (0xE, 0b11010000): 141,
    (0xE, 0b11001111): 257,
    (0xE, 0b11001110): 193,
    (0xE, 0b11001101): 225,
    (0xE, 0b11001100): 161,
    (0xE, 0b11001011): 241,
    (0xE, 0b11001010): 177,
    (0xE, 0b11001001): 209,
    (0xE, 0b11001000): 145,
    (0xE, 0b11000111): 249,
    (0xE, 0b11000110): 185,
    (0xE, 0b11000101): 217,
    (0xE, 0b11000100): 153,
    (0xE, 0b11000011): 233,
    (0xE, 0b11000010): 169,
    (0xE, 0b11000001): 201,
    (0xE, 0b11000000): 137,
    (0xE, 0b10111111): 262,
    (0xE, 0b10111110): 198,
    (0xE, 0b10111101): 230,
    (0xE, 0b10111100): 166,
    (0xE, 0b10111011): 246,
    (0xE, 0b10111010): 182,
    (0xE, 0b10111001): 214,
    (0xE, 0b10111000): 150,
    (0xE, 0b10110111): 254,
    (0xE, 0b10110110): 190,
    (0xE, 0b10110101): 222,
    (0xE, 0b10110100): 158,
    (0xE, 0b10110011): 238,
    (0xE, 0b10110010): 174,
    (0xE, 0b10110001): 206,
    (0xE, 0b10110000): 142,
    (0xE, 0b10101111): 258,
    (0xE, 0b10101110): 194,
    (0xE, 0b10101101): 226,
    (0xE, 0b10101100): 162,
    (0xE, 0b10101011): 242,
    (0xE, 0b10101010): 178,
    (0xE, 0b10101001): 210,
    (0xE, 0b10101000): 146,
    (0xE, 0b10100111): 250,
    (0xE, 0b10100110): 186,
    (0xE, 0b10100101): 218,
    (0xE, 0b10100100): 154,
    (0xE, 0b10100011): 234,
    (0xE, 0b10100010): 170,
    (0xE, 0b10100001): 202,
    (0xE, 0b10100000): 138,
    (0xE, 0b10011111): 260,
    (0xE, 0b10011110): 196,
    (0xE, 0b10011101): 228,
    (0xE, 0b10011100): 164,
    (0xE, 0b10011011): 244,
    (0xE, 0b10011010): 180,
    (0xE, 0b10011001): 212,
    (0xE, 0b10011000): 148,
    (0xE, 0b10010111): 252,
    (0xE, 0b10010110): 188,
    (0xE, 0b10010101): 220,
    (0xE, 0b10010100): 156,
    (0xE, 0b10010011): 236,
    (0xE, 0b10010010): 172,
    (0xE, 0b10010001): 204,
    (0xE, 0b10010000): 140,
    (0xE, 0b10001111): 256,
    (0xE, 0b10001110): 192,
    (0xE, 0b10001101): 224,
    (0xE, 0b10001100): 160,
    (0xE, 0b10001011): 240,
    (0xE, 0b10001010): 176,
    (0xE, 0b10001001): 208,
    (0xE, 0b10001000): 144,
    (0xE, 0b10000111): 248,
    (0xE, 0b10000110): 184,
    (0xE, 0b10000101): 216,
    (0xE, 0b10000100): 152,
    (0xE, 0b10000011): 232,
    (0xE, 0b10000010): 168,
    (0xE, 0b10000001): 200,
    (0xE, 0b10000000): 136,
    (0xF, 0b11111111): 519,
    (0xF, 0b11111110): 391,
    (0xF, 0b11111101): 455,
    (0xF, 0b11111100): 327,
    (0xF, 0b11111011): 487,
    (0xF, 0b11111010): 359,
    (0xF, 0b11111001): 423,
    (0xF, 0b11111000): 295,
    (0xF, 0b11110111): 503,
    (0xF, 0b11110110): 375,
    (0xF, 0b11110101): 439,
    (0xF, 0b11110100): 311,
    (0xF, 0b11110011): 471,
    (0xF, 0b11110010): 343,
    (0xF, 0b11110001): 407,
    (0xF, 0b11110000): 279,
    (0xF, 0b11101111): 511,
    (0xF, 0b11101110): 383,
    (0xF, 0b11101101): 447,
    (0xF, 0b11101100): 319,
    (0xF, 0b11101011): 479,
    (0xF, 0b11101010): 351,
    (0xF, 0b11101001): 415,
    (0xF, 0b11101000): 287,
    (0xF, 0b11100111): 495,
    (0xF, 0b11100110): 367,
    (0xF, 0b11100101): 431,
    (0xF, 0b11100100): 303,
    (0xF, 0b11100011): 463,
    (0xF, 0b11100010): 335,
    (0xF, 0b11100001): 399,
    (0xF, 0b11100000): 271,
    (0xF, 0b11011111): 515,
    (0xF, 0b11011110): 387,
    (0xF, 0b11011101): 451,
    (0xF, 0b11011100): 323,
    (0xF, 0b11011011): 483,
    (0xF, 0b11011010): 355,
    (0xF, 0b11011001): 419,
    (0xF, 0b11011000): 291,
    (0xF, 0b11010111): 499,
    (0xF, 0b11010110): 371,
    (0xF, 0b11010101): 435,
    (0xF, 0b11010100): 307,
    (0xF, 0b11010011): 467,
    (0xF, 0b11010010): 339,
    (0xF, 0b11010001): 403,
    (0xF, 0b11010000): 275,
    (0xF, 0b11001111): 507,
    (0xF, 0b11001110): 379,
    (0xF, 0b11001101): 443,
    (0xF, 0b11001100): 315,
    (0xF, 0b11001011): 475,
    (0xF, 0b11001010): 347,
    (0xF, 0b11001001): 411,
    (0xF, 0b11001000): 283,
    (0xF, 0b11000111): 491,
    (0xF, 0b11000110): 363,
    (0xF, 0b11000101): 427,
    (0xF, 0b11000100): 299,
    (0xF, 0b11000011): 459,
    (0xF, 0b11000010): 331,
    (0xF, 0b11000001): 395,
    (0xF, 0b11000000): 267,
    (0xF, 0b10111111): 517,
    (0xF, 0b10111110): 389,
    (0xF, 0b10111101): 453,
    (0xF, 0b10111100): 325,
    (0xF, 0b10111011): 485,
    (0xF, 0b10111010): 357,
    (0xF, 0b10111001): 421,
    (0xF, 0b10111000): 293,
    (0xF, 0b10110111): 501,
    (0xF, 0b10110110): 373,
    (0xF, 0b10110101): 437,
    (0xF, 0b10110100): 309,
    (0xF, 0b10110011): 469,
    (0xF, 0b10110010): 341,
    (0xF, 0b10110001): 405,
    (0xF, 0b10110000): 277,
    (0xF, 0b10101111): 509,
    (0xF, 0b10101110): 381,
    (0xF, 0b10101101): 445,
    (0xF, 0b10101100): 317,
    (0xF, 0b10101011): 477,
    (0xF, 0b10101010): 349,
    (0xF, 0b10101001): 413,
    (0xF, 0b10101000): 285,
    (0xF, 0b10100111): 493,
    (0xF, 0b10100110): 365,
    (0xF, 0b10100101): 429,
    (0xF, 0b10100100): 301,
    (0xF, 0b10100011): 461,
    (0xF, 0b10100010): 333,
    (0xF, 0b10100001): 397,
    (0xF, 0b10100000): 269,
    (0xF, 0b10011111): 513,
    (0xF, 0b10011110): 385,
    (0xF, 0b10011101): 449,
    (0xF, 0b10011100): 321,
    (0xF, 0b10011011): 481,
    (0xF, 0b10011010): 353,
    (0xF, 0b10011001): 417,
    (0xF, 0b10011000): 289,
    (0xF, 0b10010111): 497,
    (0xF, 0b10010110): 369,
    (0xF, 0b10010101): 433,
    (0xF, 0b10010100): 305,
    (0xF, 0b10010011): 465,
    (0xF, 0b10010010): 337,
    (0xF, 0b10010001): 401,
    (0xF, 0b10010000): 273,
    (0xF, 0b10001111): 505,
    (0xF, 0b10001110): 377,
    (0xF, 0b10001101): 441,
    (0xF, 0b10001100): 313,
    (0xF, 0b10001011): 473,
    (0xF, 0b10001010): 345,
    (0xF, 0b10001001): 409,
    (0xF, 0b10001000): 281,
    (0xF, 0b10000111): 489,
    (0xF, 0b10000110): 361,
    (0xF, 0b10000101): 425,
    (0xF, 0b10000100): 297,
    (0xF, 0b10000011): 457,
    (0xF, 0b10000010): 329,
    (0xF, 0b10000001): 393,
    (0xF, 0b10000000): 265,
    (0xF, 0b01111111): 518,
    (0xF, 0b01111110): 390,
    (0xF, 0b01111101): 454,
    (0xF, 0b01111100): 326,
    (0xF, 0b01111011): 486,
    (0xF, 0b01111010): 358,
    (0xF, 0b01111001): 422,
    (0xF, 0b01111000): 294,
    (0xF, 0b01110111): 502,
    (0xF, 0b01110110): 374,
    (0xF, 0b01110101): 438,
    (0xF, 0b01110100): 310,
    (0xF, 0b01110011): 470,
    (0xF, 0b01110010): 342,
    (0xF, 0b01110001): 406,
    (0xF, 0b01110000): 278,
    (0xF, 0b01101111): 510,
    (0xF, 0b01101110): 382,
    (0xF, 0b01101101): 446,
    (0xF, 0b01101100): 318,
    (0xF, 0b01101011): 478,
    (0xF, 0b01101010): 350,
    (0xF, 0b01101001): 414,
    (0xF, 0b01101000): 286,
    (0xF, 0b01100111): 494,
    (0xF, 0b01100110): 366,
    (0xF, 0b01100101): 430,
    (0xF, 0b01100100): 302,
    (0xF, 0b01100011): 462,
    (0xF, 0b01100010): 334,
    (0xF, 0b01100001): 398,
    (0xF, 0b01100000): 270,
    (0xF, 0b01011111): 514,
    (0xF, 0b01011110): 386,
    (0xF, 0b01011101): 450,
    (0xF, 0b01011100): 322,
    (0xF, 0b01011011): 482,
    (0xF, 0b01011010): 354,
    (0xF, 0b01011001): 418,
    (0xF, 0b01011000): 290,
    (0xF, 0b01010111): 498,
    (0xF, 0b01010110): 370,
    (0xF, 0b01010101): 434,
    (0xF, 0b01010100): 306,
    (0xF, 0b01010011): 466,
    (0xF, 0b01010010): 338,
    (0xF, 0b01010001): 402,
    (0xF, 0b01010000): 274,
    (0xF, 0b01001111): 506,
    (0xF, 0b01001110): 378,
    (0xF, 0b01001101): 442,
    (0xF, 0b01001100): 314,
    (0xF, 0b01001011): 474,
    (0xF, 0b01001010): 346,
    (0xF, 0b01001001): 410,
    (0xF, 0b01001000): 282,
    (0xF, 0b01000111): 490,
    (0xF, 0b01000110): 362,
    (0xF, 0b01000101): 426,
    (0xF, 0b01000100): 298,
    (0xF, 0b01000011): 458,
    (0xF, 0b01000010): 330,
    (0xF, 0b01000001): 394,
    (0xF, 0b01000000): 266,
    (0xF, 0b00111111): 516,
    (0xF, 0b00111110): 388,
    (0xF, 0b00111101): 452,
    (0xF, 0b00111100): 324,
    (0xF, 0b00111011): 484,
    (0xF, 0b00111010): 356,
    (0xF, 0b00111001): 420,
    (0xF, 0b00111000): 292,
    (0xF, 0b00110111): 500,
    (0xF, 0b00110110): 372,
    (0xF, 0b00110101): 436,
    (0xF, 0b00110100): 308,
    (0xF, 0b00110011): 468,
    (0xF, 0b00110010): 340,
    (0xF, 0b00110001): 404,
    (0xF, 0b00110000): 276,
    (0xF, 0b00101111): 508,
    (0xF, 0b00101110): 380,
    (0xF, 0b00101101): 444,
    (0xF, 0b00101100): 316,
    (0xF, 0b00101011): 476,
    (0xF, 0b00101010): 348,
    (0xF, 0b00101001): 412,
    (0xF, 0b00101000): 284,
    (0xF, 0b00100111): 492,
    (0xF, 0b00100110): 364,
    (0xF, 0b00100101): 428,
    (0xF, 0b00100100): 300,
    (0xF, 0b00100011): 460,
    (0xF, 0b00100010): 332,
    (0xF, 0b00100001): 396,
    (0xF, 0b00100000): 268,
    (0xF, 0b00011111): 512,
    (0xF, 0b00011110): 384,
    (0xF, 0b00011101): 448,
    (0xF, 0b00011100): 320,
    (0xF, 0b00011011): 480,
    (0xF, 0b00011010): 352,
    (0xF, 0b00011001): 416,
    (0xF, 0b00011000): 288,
    (0xF, 0b00010111): 496,
    (0xF, 0b00010110): 368,
    (0xF, 0b00010101): 432,
    (0xF, 0b00010100): 304,
    (0xF, 0b00010011): 464,
    (0xF, 0b00010010): 336,
    (0xF, 0b00010001): 400,
    (0xF, 0b00010000): 272,
    (0xF, 0b00001111): 504,
    (0xF, 0b00001110): 376,
    (0xF, 0b00001101): 440,
    (0xF, 0b00001100): 312,
    (0xF, 0b00001011): 472,
    (0xF, 0b00001010): 344,
    (0xF, 0b00001001): 408,
    (0xF, 0b00001000): 280,
    (0xF, 0b00000111): 488,
    (0xF, 0b00000110): 360,
    (0xF, 0b00000101): 424,
    (0xF, 0b00000100): 296,
    (0xF, 0b00000011): 456,
    (0xF, 0b00000010): 328,
    (0xF, 0b00000001): 392,
    (0xF, 0b00000000): 264,
}

Classes

class pkw

This unit implements PKWare decompression.

Expand source code Browse git
class pkw(Unit):
    """
    This unit implements PKWare decompression.
    """
    def process(self, data):

        def read_from_table(table: dict[tuple[int, int], int], start: int, stop: int):
            value = length = 0
            while length < start:
                value <<= 1
                value |= getint(1)
                length += 1
            while length < stop:
                try:
                    return table[length, value]
                except KeyError:
                    value <<= 1
                    value |= getint(1)
                    length += 1
            raise ValueError(
                'Failed to decode a symbol in the compressed data stream.')

        reader = StructReader(data)
        codelit = reader.u8()  # First byte is 0 if literals are uncoded, otherwise 1
        maxdict = reader.u8()  # Second byte is 4, 5, or 6 (max size of dictionary)

        if not 0 <= codelit <= 1:
            raise ValueError(F'Invalid literal encoding value {codelit}.')

        if not 4 <= maxdict <= 6:
            raise ValueError(F'Invalid dictionary size {maxdict}.')

        output = MemoryFile()
        getint = reader.read_integer

        while not reader.eof:
            try:
                if not getint(1):
                    if codelit:
                        code = read_from_table(_LITERALS, 4, 14)
                    else:
                        code = getint(8)
                    output.write_byte(code)
                else:
                    length = read_from_table(_COPY_LENGTHS, 2, 0x10)
                    if length == 519:
                        break
                    offset = read_from_table(_COPY_OFFSETS, 2, 0x09)
                    more = (2 if length == 2 else maxdict)
                    offset <<= more
                    offset += getint(more)
                    offset += 1
                    output.replay(offset, length)
            except Exception as E:
                if not (out := output.getvalue()):
                    raise
                raise RefineryPartialResult(str(E), out) from E

        return output.getvalue()

    @classmethod
    def handles(self, data: bytearray) -> bool:
        return (len(data) > 2) and (0 <= data[0] <= 1) and (4 <= data[1] <= 6)

Ancestors

Class variables

var required_dependencies
var optional_dependencies

Inherited members