Skip to content

Instantly share code, notes, and snippets.

@the6p4c
Created November 28, 2019 13:13
Show Gist options
  • Select an option

  • Save the6p4c/47736d332a64331e6358e1f67b3f43d2 to your computer and use it in GitHub Desktop.

Select an option

Save the6p4c/47736d332a64331e6358e1f67b3f43d2 to your computer and use it in GitHub Desktop.

Revisions

  1. the6p4c created this gist Nov 28, 2019.
    60 changes: 60 additions & 0 deletions decompress.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    import sys

    def main():
    input_file = sys.argv[1]
    output_file = sys.argv[2]

    with open(input_file, 'rb') as f_in, open(output_file, 'wb') as f_out:
    decompressed_length = int.from_bytes(f_in.read(4), 'little')
    bytes_written = 0

    output_buffer = [0] * 4096
    output_buffer_pos = 0xFEE

    def get_byte(offset):
    nonlocal output_buffer

    return output_buffer[offset % len(output_buffer)]

    def write_byte(b):
    nonlocal output_buffer, output_buffer_pos, bytes_written, f_out

    output_buffer[output_buffer_pos] = b

    output_buffer_pos += 1
    output_buffer_pos %= len(output_buffer)

    bytes_written += 1

    f_out.write(bytes([b]))

    while True:
    # >= to catch an over-run, if we're unlucky enough for one to
    # happen
    if bytes_written >= decompressed_length:
    return

    control = ord(f_in.read(1))
    control_bits = [(control >> i) & 1 for i in range(8)]

    for control_bit in control_bits:
    # same deal as above
    if bytes_written >= decompressed_length:
    return

    if control_bit == 1:
    # literal
    literal = ord(f_in.read(1))

    write_byte(literal)
    else:
    # reference
    reference = int.from_bytes(f_in.read(2), 'big')
    offset = (((reference >> 4) & 0xF) << 8) | (reference >> 8)
    length = (reference & 0xF) + 3

    for i in range(length):
    write_byte(get_byte(offset + i))

    if __name__ == '__main__':
    main()