FanFicFare/included_dependencies/brotlipython.py

2744 lines
81 KiB
Python

#!/usr/bin/env python3
# Copyright (C) 2016 Kai Lüke kailueke@riseup.net
# This program comes with ABSOLUTELY NO WARRANTY and is free software, you are welcome to redistribute it
# under certain conditions, see https://www.gnu.org/licenses/gpl-3.0.en.html
# super slow pure python brotli decoder, please ignore
#
# ported from brotli-rs to a minimal python subset and now back to standard python (but unpolished) as a side project
#
# usage:
#
# from brotlipython import brotlidec
# in = open('test.br', 'rb').read()
# outbuf = []
# dec = brotlidec(in, outbuf) # also returns bytes(outbuf) again
#
# or see `./brotlipython.py --help`
# @TODO:
# look into brotlidump.py
# whole file is unpythonic (no for loops, mostly integers, global variables, no classes, no good exception model)
# is needlessly complicated comes becfrom a malloc/free world (transformations)
import sys, array, argparse, os
from requests.utils import extract_zipped_paths
BROTLI_DICTIONARY = ''
# alloc_pM = lambda length: array.array('B', [0 for x in range(0, length)])
# alloc_pH = lambda length: array.array('L', [0 for x in range(0, length)])
alloc_L = lambda length: [0 for x in range(0, length)]
alloc_pM = alloc_pH = alloc_L
input_buf_pos = 0
input_buf = []
NONE = None
gcmpbuf = []
cmpbuf_pos = 0
output_buf = []
def out(a):
global cmpbuf_pos, output_buf
if gcmpbuf is not None:
expected = gcmpbuf[cmpbuf_pos]
cmpbuf_pos += 1
if a != expected:
import ipdb; ipdb.set_trace()
output_buf.append(a)
def read_b():
global input_buf, input_buf_pos
if input_buf_pos == len(input_buf):
return NONE
a = input_buf[input_buf_pos]
input_buf_pos += 1
return a
def error():
raise Exception("error() invoked")
# /bitreader/mod.rs
bit_pos = 0
current_byte = NONE
global_bit_pos = 0
read_exact_result = 0
def read_exact(): # read only one as it's anyway not used for more
global read_exact_result
read_exact_result = read_b()
if read_exact_result is None:
return 1 # eos error()
return 0
def read_u8(): # return NONE for eof
global bit_pos, current_byte, global_bit_pos
res = read_exact()
buf = read_exact_result
if bit_pos == 0 and current_byte is not None and res == 1: # i.e. res == EOS
tmp_ = current_byte
current_byte = NONE
global_bit_pos += 8
return tmp_
elif current_byte is None and res == 0: # i.e. res == Ok()
global_bit_pos += 8
return buf
elif current_byte is not None and res == 0:
tmp_ = current_byte
current_byte = buf
global_bit_pos += 8
return (tmp_ >> bit_pos) | (buf << (8 - bit_pos))
else:
return NONE
read_u8_from_nibble_result = 0
def read_u8_from_nibble(): # returns 0 for OK, 1 for Error
global bit_pos, current_byte, global_bit_pos, read_u8_from_nibble_result
if bit_pos == 0 and current_byte is None:
res = read_exact()
buf = read_exact_result
if res == 0: # i.e. Ok()
global_bit_pos += 4
bit_pos = 4
current_byte = buf
read_u8_from_nibble_result = buf & 0x0f
return 0
else:
return res
elif (bit_pos == 1 or bit_pos == 2 or bit_pos == 3) and current_byte is not None:
global_bit_pos += 4
bit_pos += 4
read_u8_from_nibble_result = (current_byte >> (bit_pos - 4)) & 0x0f
return 0
elif bit_pos == 4 and current_byte is not None:
global_bit_pos += 4
bit_pos = 0
tmp_ = current_byte
current_byte = NONE
read_u8_from_nibble_result = (tmp_ >> 4) & 0x0f
return 0
elif (bit_pos == 5 or bit_pos == 6 or bit_pos == 7) and current_byte is not None:
res = read_exact()
buf = read_exact_result
if res == 0:
global_bit_pos += 4
bit_pos_prev = bit_pos
bit_pos = bit_pos - 4
tmp_ = current_byte
current_byte = buf
read_u8_from_nibble_result = ((tmp_ >> (bit_pos_prev)) | (buf << (8 - bit_pos_prev))) & 0x0f
return 0
else:
return res
else:
return 1 # unreachable
read_bit_result = 0
def read_bit(): # returns 0 for OK, 1 for Error
global bit_pos, current_byte, global_bit_pos, read_bit_result
if current_byte is not None:
tmp_ = bit_pos
tmp_2 = current_byte
bit_pos = (tmp_ + 1) % 8
global_bit_pos = global_bit_pos + 1
if bit_pos == 0:
current_byte = NONE
read_bit_result = tmp_2 >> tmp_ & 1
return 0
else:
if read_exact():
return 1
else:
current_byte = read_exact_result
bit_pos = 1
global_bit_pos = 1
read_bit_result = read_exact_result & 1
return 0
read_u32_from_n_bits_result = 0
# returns 0 for OK, 1 for Error
def read_u32_from_n_bits(n): # does also serve as read_u8_from_n_bits, read_u16_from_n_bits
global bit_pos, current_byte, global_bit_pos, read_u32_from_n_bits_result
read_u32_from_n_bits_result = 0
i = 0
while i < n:
if read_bit():
return 1 # error
elif read_bit_result == 1:
read_u32_from_n_bits_result = read_u32_from_n_bits_result | (1 << i)
i += 1
return 0
def read_u8_from_byte_tail(): # return NONE for eof
if bit_pos == 0:
return 0
else:
if read_u32_from_n_bits(8 - bit_pos):
return NONE
return read_u32_from_n_bits_result
read_u32_from_n_nibbles_result = 0
# returns 0 for OK, 1 for Error
def read_u32_from_n_nibbles(n):
global bit_pos, current_byte, global_bit_pos, read_u32_from_n_nibbles_result
read_u32_from_n_nibbles_result = 0
i = 0
while i < n:
if read_u8_from_nibble() == 0:
read_u32_from_n_nibbles_result = read_u32_from_n_nibbles_result | (read_u8_from_nibble_result << (4 * i))
else:
return 1
i += 1
return 0
def read_fixed_length_string(length):
my_string = alloc_pM(length)
i = 0
while i < length:
t = read_u8()
if t == NONE:
return NONE
my_string[i] = t
i += 1
return my_string
# /huffman/tree/mod.rs
# tree as [buf, len, last_symbol]
# buf: tree[0]
# len: tree[1]
# last_symbol: tree[2]
def tree_from_raw_data(buf, len_, last_symbol):
return [buf, len_, last_symbol]
def tree_with_max_depth(max_depth):
len_ = (1 << (max_depth + 1)) - 1
# u16 entries
arr = alloc_L(len_)
i = 0 # init all values with NONE
while i < len_:
arr[i] = NONE
i += 1
return tree_from_raw_data(arr, 0, NONE)
def insert(tree, code, symbol): # code[0,1,0,1,0,1]
# code is 32 bit array
tree[1] = tree[1] + 1
tree[2] = symbol
insert_at_index = 0
i = 0
while i < len(code):
insert_at_index = (insert_at_index << 1) + code[i]
i += 1
insert_at_index = (1 << len(code)) - 1 + insert_at_index
if insert_at_index > len(tree[0]) - 1:
error() # panic!()
tr = tree[0]
tr[insert_at_index] = symbol
def lookup(tree):
pseudo_code = 1
len_ = len(tree[0])
while True:
if read_bit():
return NONE
pseudo_code = (pseudo_code << 1) + read_bit_result
lookup_index = pseudo_code - 1
if lookup_index > len_ - 1:
return NONE # None but anyway None is always leading to DecompressorError
tr = tree[0]
tmp_ = tr[lookup_index] # buf[lookup_index]
if tmp_ != NONE:
return tmp_
def lookup_symbol(tree):
if tree[1] == 0: # len == 0
return NONE # None empty table
if tree[1] == 1: # len == 1
return tree[2] # last_symbol
return lookup(tree)
# /huffman/mod.rs
def bit_string_from_code_and_length(code, len_): # nr, nr
bits = alloc_pM(len_)
i = 0
while i < len_: # all bits get set, no initialisation with zero needed
if (code >> i) & 1 == 1:
bits[len_ - i - 1] = 1
else:
bits[len_ - i - 1] = 0
i += 1
return bits
def codes_from_lengths_and_symbols(lengths, symbols): # [], [] -> tree
# treat lengths as u8 in pM, symbols as u32 in pH
max_length = 0
i = 0
while i < len(lengths):
j = lengths[i]
if j > max_length:
max_length = j
i += 1
bl_count = alloc_pH(max_length + 1)
i = 0
while i < max_length + 1:
bl_count[i] = 0 # init
i += 1
i = 0
while i < len(lengths):
j = lengths[i]
bl_count[j] = bl_count[j] + 1
i += 1
code = 0
next_code = alloc_pH(max_length + 1)
next_code[0] = 0 # init, rest is in loop
bits = 1
while bits < max_length + 1:
code = (code + bl_count[bits - 1]) << 1
next_code[bits] = code
bits += 1
codes = tree_with_max_depth(max_length)
i = 0
while i < len(lengths):
len_ = lengths[i]
if len_ > 0 or max_length == 0:
insert(codes, bit_string_from_code_and_length(next_code[len_], len_), symbols[i])
next_code[len_] = next_code[len_] + 1
i += 1
return codes
def codes_from_lengths(lengths): # [] -> Tree
# lengths is in pM
symbols = alloc_pH(len(lengths))
i = 0
while i < len(lengths):
symbols[i] = i
i += 1
ret = codes_from_lengths_and_symbols(lengths, symbols)
return ret
# /transformation/mod.rs
def uppercase_all(base_word):
l = len(base_word)
v = alloc_pM(l)
i = 0
while i < l:
b = base_word[i]
if (b >= 0 and b <= 96) or (b >= 123 and b <= 191):
v[i] = b
i += 1
elif b >= 97 and b <= 122:
v[i] = b ^ 32
i += 1
elif b >= 192 and b <= 223:
v[i] = b
i += 1
if i < l:
v[i] = base_word[i] ^ 32
i += 1
elif b >= 224 and b <= 255:
v[i] = b
i += 1
if i < l:
v[i] = base_word[i]
i += 1
if i < l:
v[i] = base_word[i] ^ 5
i += 1
else:
error() # unreachable
return v
def uppercase_first(base_word):
l = len(base_word)
if l == 0:
return alloc_pM(0)
v = alloc_pM(l)
i = 0
b = base_word[0]
if (b >= 1 and b <= 96) or (b >= 123 and b <= 191):
v[0] = b
i = 1
elif b >= 97 and b <= 122:
v[0] = b ^ 32
i = 1
elif b >= 192 and b <= 223:
v[0] = b
if 1 < l:
v[1] = base_word[1] ^ 32
i = 2
elif b >= 224 and b <= 255:
v[0] = b
if 1 < l:
v[1] = base_word[1]
if 2 < l:
v[2] = base_word[2] ^ 5
i = 3
else:
error() # unreachable
while i < l:
v[i] = base_word[i]
i += 1
return v
def transformation(id_, base_word):
#print("t:", id_, str(bytearray(base_word)))
# rewrite like: t1 = [0x22] t2= omit_first(2) t3=[0x22,0x21] tc=3
l = len(base_word)
i = 0
if id_ == 0:
return base_word
elif id_ == 1 or id_ == 19 or id_ == 20 or id_ == 22 or id_ == 24 or id_ == 36 or id_ == 51 or id_ == 57 or id_ == 76: # 1 hinten an
v = alloc_pM(l+1)
while i < l:
v[i] = base_word[i]
i += 1
if id_ == 1:
v[i] = 0x20
elif id_ == 19:
v[i] = 0x22
elif id_ == 20:
v[i] = 0x2e
elif id_ == 22:
v[i] = 0x0a
elif id_ == 24:
v[i] = 0x5d
elif id_ == 36:
v[i] = 0x27
elif id_ == 51:
v[i] = 0x3a
elif id_ == 57:
v[i] = 0x28
elif id_ == 76:
v[i] = 0x2c
elif id_ == 2 or id_ == 67 or id_ == 71 or id_ == 77 or id_ == 89 or id_ == 103: # 1 vorne 1 hinten an
v = alloc_pM(l+2)
if id_ == 2 or id_ == 71 or id_ == 89 or id_ == 103:
v[i] = 0x20
elif id_ == 67 or id_ == 77:
v[i] = 0x2e
i += 1
while i <= l:
v[i] = base_word[i-1]
i += 1
if id_ == 2 or id_ == 77:
v[i] = 0x20
elif id_ == 67 or id_ == 89:
v[i] = 0x28
elif id_ == 71:
v[i] = 0x2e
elif id_ == 103:
v[i] = 0x2c
elif id_ == 3 or id_ == 11 or id_ == 26 or id_ == 34 or id_ == 39 or id_ == 40 or id_ == 54 or id_ == 55:
if id_ == 3:
j = 1
elif id_ == 11:
j = 2
elif id_ == 26:
j = 3
elif id_ == 34:
j = 4
elif id_ == 39:
j = 5
elif id_ == 40:
j = 6
elif id_ == 54:
j = 9
elif id_ == 55:
j = 7
if l-1 < j:
j = l-1
v = alloc_pM(l-j)
while i < l-j:
v[i] = base_word[i+j]
i += 1
elif id_ == 4 or id_ == 66 or id_ == 74 or id_ == 78 or id_ == 79 or id_ == 99: # upper first 1 hinten an
u = uppercase_first(base_word)
j = len(u)
v = alloc_pM(j+1)
while i < j:
v[i] = u[i]
i += 1
if id_ == 4:
v[i] = 0x20
elif id_ == 66:
v[i] = 0x22
elif id_ == 74:
v[i] = 0x27
elif id_ == 78:
v[i] = 0x28
elif id_ == 79:
v[i] = 0x2e
elif id_ == 99:
v[i] = 0x2c
elif id_ == 5 or id_ == 10 or id_ == 25 or id_ == 80 or id_ == 93: # 5 hinten an
v = alloc_pM(l+5)
while i < l:
v[i] = base_word[i]
i += 1
if id_ == 93:
v[i] = 0x6c
else:
v[i] = 0x20
i += 1
if id_ == 5:
v[i] = 0x74
elif id_ == 10:
v[i] = 0x61
elif id_ == 25:
v[i] = 0x66
elif id_ == 80:
v[i] = 0x6e
elif id_ == 93:
v[i] = 0x65
i += 1
if id_ == 5:
v[i] = 0x68
elif id_ == 10:
v[i] = 0x6e
elif id_ == 25 or id_ == 80:
v[i] = 0x6f
elif id_ == 93:
v[i] = 0x73
i += 1
if id_ == 5:
v[i] = 0x65
elif id_ == 10:
v[i] = 0x64
elif id_ == 25:
v[i] = 0x72
elif id_ == 80:
v[i] = 0x74
elif id_ == 93:
v[i] = 0x73
i += 1
v[i] = 0x20
elif id_ == 6 or id_ == 32: # 1 vorne an
v = alloc_pM(l+1)
if id_ == 6:
v[i] = 0x20
elif id_ == 32:
v[i] = 0x2e
i += 1
while i <= l:
v[i] = base_word[i-1]
i += 1
elif id_ == 7 or id_ == 13 or id_ == 18: # 2 vorne an 1 hinten an
v = alloc_pM(l+3)
if id_ == 7:
v[i] = 0x73
elif id_ == 13:
v[i] = 0x2c
elif id_ == 18:
v[i] = 0x65
i += 1
v[i] = 0x20
i += 1
l += 1
while i <= l:
v[i] = base_word[i-2]
i += 1
v[i] = 0x20
elif id_ == 8 or id_ == 16 or id_ == 17 or id_ == 38 or id_ == 45 or id_ == 46 or id_ == 47 or id_ == 60 or id_ == 90 or id_ == 92 or id_ == 95 or id_ == 100 or id_ == 106: # 4 hinten an
v = alloc_pM(l+4)
while i < l:
v[i] = base_word[i]
i += 1
if id_ == 90:
v[i] = 0x66
elif id_ == 92 or id_ == 100:
v[i] = 0x69
elif id_ == 95:
v[i] = 0x65
elif id_ == 106:
v[i] = 0x6f
else:
v[i] = 0x20
i += 1
if id_ == 8:
v[i] = 0x6f
elif id_ == 16:
v[i] = 0x69
elif id_ == 17:
v[i] = 0x74
elif id_ == 38:
v[i] = 0x62
elif id_ == 45:
v[i] = 0x6f
elif id_ == 46 or id_ == 60:
v[i] = 0x61
elif id_ == 47:
v[i] = 0x69
elif id_ == 90 or id_ == 106:
v[i] = 0x75
elif id_ == 92:
v[i] = 0x76
elif id_ == 95:
v[i] = 0x73
elif id_ == 100:
v[i] = 0x7a
i += 1
if id_ == 8:
v[i] = 0x66
elif id_ == 16:
v[i] = 0x6e
elif id_ == 17:
v[i] = 0x6f
elif id_ == 38:
v[i] = 0x79
elif id_ == 45:
v[i] = 0x6e
elif id_ == 46 or id_ == 47 or id_ == 106:
v[i] = 0x73
elif id_ == 60 or id_ == 95:
v[i] = 0x74
elif id_ == 90:
v[i] = 0x6c
elif id_ == 92 or id_ == 100:
v[i] = 0x65
i += 1
v[i] = 0x20
elif id_ == 9:
v = uppercase_first(base_word)
elif id_ == 12 or id_ == 23 or id_ == 27 or id_ == 42 or id_ == 48 or id_ == 56 or id_ == 59 or id_ == 63 or id_ == 64:
if id_ == 12:
j = 1
elif id_ == 23:
j = 3
elif id_ == 27:
j = 2
elif id_ == 42:
j = 4
elif id_ == 48:
j = 7
elif id_ == 56:
j = 6
elif id_ == 59:
j = 8
elif id_ == 63:
j = 5
elif id_ == 64:
j = 9
if l > j:
j = l
if id_ == 12:
j -= 1
elif id_ == 23:
j -= 3
elif id_ == 27:
j -= 2
elif id_ == 42:
j -= 4
elif id_ == 48:
j -= 7
elif id_ == 56:
j -= 6
elif id_ == 59:
j -= 8
elif id_ == 63:
j -= 5
elif id_ == 64:
j -= 9
v = alloc_pM(j)
while i < j:
v[i] = base_word[i]
i += 1
elif id_ == 14 or id_ == 21 or id_ == 31 or id_ == 50 or id_ == 70 or id_ == 86: # 2 hinten an
v = alloc_pM(l+2)
while i < l:
v[i] = base_word[i]
i += 1
if id_ == 14:
v[i] = 0x2c
elif id_ == 21:
v[i] = 0x22
elif id_ == 31:
v[i] = 0x2e
elif id_ == 50:
v[i] = 0x0a
elif id_ == 70 or id_ == 86:
v[i] = 0x3d
i += 1
if id_ == 14 or id_ == 31:
v[i] = 0x20
elif id_ == 21:
v[i] = 0x3e
elif id_ == 50:
v[i] = 0x09
elif id_ == 70:
v[i] = 0x22
elif id_ == 86:
v[i] = 0x27
elif id_ == 15 or id_ == 96 or id_ == 109: # upper first 1 vorne an 1 hinten an
u = uppercase_first(base_word)
j = len(u)
v = alloc_pM(j+2)
v[0] = 0x20
while i < j:
v[i+1] = u[i]
i += 1
i += 1
if id_ == 96:
v[i] = 0x2e
elif id_ == 109:
v[i] = 0x2c
else:
v[i] = 0x20
elif id_ == 28 or id_ == 53 or id_ == 61 or id_ == 82 or id_ == 84: # 3 hinten an
v = alloc_pM(l+3)
while i < l:
v[i] = base_word[i]
i += 1
if id_ == 28:
v[i] = 0x20
elif id_ == 53 or id_ == 82:
v[i] = 0x65
elif id_ == 61:
v[i] = 0x6c
elif id_ == 84:
v[i] = 0x61
i += 1
if id_ == 28:
v[i] = 0x61
elif id_ == 53:
v[i] = 0x64
elif id_ == 61:
v[i] = 0x79
elif id_ == 82:
v[i] = 0x72
elif id_ == 84:
v[i] = 0x6c
i += 1
v[i] = 0x20
elif id_ == 29 or id_ == 35 or id_ == 37 or id_ == 43: # 6 hinten an
v = alloc_pM(l+6)
while i < l:
v[i] = base_word[i]
i += 1
if id_ == 43:
v[i] = 0x2e
else:
v[i] = 0x20
i += 1
if id_ == 29:
v[i] = 0x74
elif id_ == 35:
v[i] = 0x77
elif id_ == 37:
v[i] = 0x66
elif id_ == 43:
v[i] = 0x20
i += 1
if id_ == 29:
v[i] = 0x68
elif id_ == 35:
v[i] = 0x69
elif id_ == 37:
v[i] = 0x72
elif id_ == 43:
v[i] = 0x54
i += 1
if id_ == 29:
v[i] = 0x61
elif id_ == 35:
v[i] = 0x74
elif id_ == 37:
v[i] = 0x6f
elif id_ == 43:
v[i] = 0x68
i += 1
if id_ == 29:
v[i] = 0x74
elif id_ == 35:
v[i] = 0x68
elif id_ == 37:
v[i] = 0x6d
elif id_ == 43:
v[i] = 0x65
i += 1
v[i] = 0x20
elif id_ == 30: # upper first 1 vorne an
u = uppercase_first(base_word)
j = len(u)
v = alloc_pM(j+1)
v[0] = 0x20
while i < j:
v[i+1] = u[i]
i += 1
elif id_ == 33 or id_ == 52 or id_ == 81 or id_ == 98: # 1 vorne 2 hinten an
v = alloc_pM(l+3)
v[i] = 0x20
i += 1
while i <= l:
v[i] = base_word[i-1]
i += 1
if id_ == 33:
v[i] = 0x2c
elif id_ == 52:
v[i] = 0x2e
elif id_ == 81 or id_ == 98:
v[i] = 0x3d
i += 1
if id_ == 81:
v[i] = 0x22
elif id_ == 98:
v[i] = 0x27
else:
v[i] = 0x20
elif id_ == 41 or id_ == 72: # 5 vorne an
v = alloc_pM(l+5)
if id_ == 41:
v[i] = 0x20
elif id_ == 72:
v[i] = 0x2e
i += 1
if id_ == 41:
v[i] = 0x74
elif id_ == 72:
v[i] = 0x63
i += 1
if id_ == 41:
v[i] = 0x68
elif id_ == 72:
v[i] = 0x6f
i += 1
if id_ == 41:
v[i] = 0x65
elif id_ == 72:
v[i] = 0x6d
i += 1
if id_ == 41:
v[i] = 0x20
elif id_ == 72:
v[i] = 0x2f
i += 1
while i-5 < l:
v[i] = base_word[i-5]
i += 1
elif id_ == 44:
v = uppercase_all(base_word)
elif id_ == 49:
j = 1
if l > j:
j = l
j -= 1
v = alloc_pM(j+4)
while i < j:
v[i] = base_word[i]
i += 1
v[i] = 0x69
i += 1
v[i] = 0x6e
i += 1
v[i] = 0x67
i += 1
v[i] = 0x20
elif id_ == 58 or id_ == 69 or id_ == 88 or id_ == 104 or id_ == 108: # upper first 2 hinten an
u = uppercase_first(base_word)
j = len(u)
v = alloc_pM(j+2)
while i < j:
v[i] = u[i]
i += 1
if id_ == 58:
v[i] = 0x2c
elif id_ == 69:
v[i] = 0x22
elif id_ == 88:
v[i] = 0x2e
elif id_ == 104 or id_ == 108:
v[i] = 0x3d
i += 1
if id_ == 58 or id_ == 88:
v[i] = 0x20
elif id_ == 69:
v[i] = 0x3e
elif id_ == 104:
v[i] = 0x22
elif id_ == 108:
v[i] = 0x27
elif id_ == 62: # 5 vorne 4 hinten an
v = alloc_pM(l+9)
v[i] = 0x20
i += 1
v[i] = 0x74
i += 1
v[i] = 0x68
i += 1
v[i] = 0x65
i += 1
v[i] = 0x20
i += 1
while i-5 < l:
v[i] = base_word[i-5]
i += 1
v[i] = 0x20
i += 1
v[i] = 0x6f
i += 1
v[i] = 0x66
i += 1
v[i] = 0x20
elif id_ == 65 or id_ == 91 or id_ == 118 or id_ == 120: # upper first 1 vorne 2 hinten an
u = uppercase_first(base_word)
j = len(u)
v = alloc_pM(j+3)
v[0] = 0x20
while i < j:
v[i+1] = u[i]
i += 1
i += 1
if id_ == 65:
v[i] = 0x2c
elif id_ == 91:
v[i] = 0x2e
else:
v[i] = 0x3d
i += 1
if id_ == 118:
v[i] = 0x22
elif id_ == 120:
v[i] = 0x27
else:
v[i] = 0x20
elif id_ == 68 or id_ == 87 or id_ == 94 or id_ == 101 or id_ == 112 or id_ == 113: # upper all 1 hinten
u = uppercase_all(base_word)
j = len(u)
v = alloc_pM(j+1)
while i < j:
v[i] = u[i]
i += 1
if id_ == 87:
v[i] = 0x22
elif id_ == 94:
v[i] = 0x27
elif id_ == 101:
v[i] = 0x2e
elif id_ == 112:
v[i] = 0x2c
elif id_ == 113:
v[i] = 0x28
else:
v[i] = 0x20
elif id_ == 73: # 5 vorne 8 hinten an
v = alloc_pM(l+13)
v[i] = 0x20
i += 1
v[i] = 0x74
i += 1
v[i] = 0x68
i += 1
v[i] = 0x65
i += 1
v[i] = 0x20
i += 1
while i-5 < l:
v[i] = base_word[i-5]
i += 1
v[i] = 0x20
i += 1
v[i] = 0x6f
i += 1
v[i] = 0x66
i += 1
v[i] = 0x20
i += 1
v[i] = 0x74
i += 1
v[i] = 0x68
i += 1
v[i] = 0x65
i += 1
v[i] = 0x20
elif id_ == 75: # 7 hinten an
v = alloc_pM(l+7)
while i < l:
v[i] = base_word[i]
i += 1
v[i] = 0x2e
i += 1
v[i] = 0x20
i += 1
v[i] = 0x54
i += 1
v[i] = 0x68
i += 1
v[i] = 0x69
i += 1
v[i] = 0x73
i += 1
v[i] = 0x20
elif id_ == 83 or id_ == 115: # upper all 1 vorne 1 hinten
u = uppercase_all(base_word)
j = len(u)
v = alloc_pM(j+2)
v[0] = 0x20
while i < j:
v[i+1] = u[i]
i += 1
i += 1
if id_ == 83:
v[i] = 0x20
elif id_ == 115:
v[i] = 0x2e
elif id_ == 85: # upper all 1 vorne
u = uppercase_all(base_word)
j = len(u)
v = alloc_pM(j+1)
v[0] = 0x20
while i < j:
v[i+1] = u[i]
i += 1
elif id_ == 97 or id_ == 105 or id_ == 107 or id_ == 114 or id_ == 116: # upper all 2 hinten
u = uppercase_all(base_word)
j = len(u)
v = alloc_pM(j+2)
while i < j:
v[i] = u[i]
i += 1
if id_ == 97:
v[i] = 0x22
elif id_ == 105 or id_ == 116:
v[i] = 0x3d
elif id_ == 107:
v[i] = 0x2c
elif id_ == 114:
v[i] = 0x2e
i += 1
if id_ == 97:
v[i] = 0x3e
elif id_ == 105:
v[i] = 0x22
elif id_ == 116:
v[i] = 0x27
elif id_ == 107 or id_ == 114:
v[i] = 0x20
elif id_ == 102: # 2 vorne
v = alloc_pM(l+2)
v[i] = 0xc2
i += 1
v[i] = 0xa0
i += 1
l += 1
while i <= l:
v[i] = base_word[i-2]
i += 1
elif id_ == 110 or id_ == 111 or id_ == 117 or id_ == 119: # upper all 1 vorne 2 hinten
u = uppercase_all(base_word)
j = len(u)
v = alloc_pM(j+3)
v[0] = 0x20
while i < j:
v[i+1] = u[i]
i += 1
i += 1
if id_ == 110 or id_ == 119:
v[i] = 0x3d
elif id_ == 111:
v[i] = 0x2c
elif id_ == 117:
v[i] = 0x2e
i += 1
if id_ == 110:
v[i] = 0x22
elif id_ == 110:
v[i] = 0x27
else:
v[i] = 0x20
else:
return NONE # unreachable
return v
# /dictionary/mod.rs
BROTLI_DICTIONARY_OFFSETS_BY_LENGTH = [0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, 53248, 63488 , 74752, 87040, 93696, 100864, 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280, 122016]
BROTLI_DICTIONARY_SIZE_BITS_BY_LENGTH = [0, 0, 0, 0, 10, 10, 11, 11, 10, 10, 10, 10, 10, 9, 9, 8, 7, 7, 8, 7, 7, 6, 6, 5, 5]
# /lookuptable/mod.rs
LUT_0 = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,
44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12,
12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48,
52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,
12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,
60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3
]
LUT_1 = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
]
LUT_2 = [
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7
]
table = alloc_pH(704*4)
insert_and_copy_length = 0
while insert_and_copy_length < 704:
if insert_and_copy_length >= 0 and insert_and_copy_length <= 63:
insert_length_code = 0
copy_length_code = 0
elif insert_and_copy_length >= 64 and insert_and_copy_length <= 127:
insert_length_code = 0
copy_length_code = 8
elif insert_and_copy_length >= 128 and insert_and_copy_length <= 191:
insert_length_code = 0
copy_length_code = 0
elif insert_and_copy_length >= 192 and insert_and_copy_length <= 255:
insert_length_code = 0
copy_length_code = 8
elif insert_and_copy_length >= 256 and insert_and_copy_length <= 319:
insert_length_code = 8
copy_length_code = 0
elif insert_and_copy_length >= 320 and insert_and_copy_length <= 383:
insert_length_code = 8
copy_length_code = 8
elif insert_and_copy_length >= 384 and insert_and_copy_length <= 447:
insert_length_code = 0
copy_length_code = 16
elif insert_and_copy_length >= 448 and insert_and_copy_length <= 511:
insert_length_code = 16
copy_length_code = 0
elif insert_and_copy_length >= 512 and insert_and_copy_length <= 575:
insert_length_code = 8
copy_length_code = 16
elif insert_and_copy_length >= 576 and insert_and_copy_length <= 639:
insert_length_code = 16
copy_length_code = 8
elif insert_and_copy_length >= 640 and insert_and_copy_length <= 703:
insert_length_code = 16
copy_length_code = 16
else:
error() # print('unreachable')
insert_length_code += 0x07 & (insert_and_copy_length >> 3)
copy_length_code += 0x07 & insert_and_copy_length
if insert_length_code >= 0 and insert_length_code <= 5:
insert_length = insert_length_code
extra_bits_insert = 0
elif insert_length_code == 6 or insert_length_code == 7:
insert_length = 6 + 2 * (insert_length_code - 6)
extra_bits_insert = 1
elif insert_length_code == 8 or insert_length_code == 9:
insert_length = 10 + 4 * (insert_length_code - 8)
extra_bits_insert = 2
elif insert_length_code == 10 or insert_length_code == 11:
insert_length = 18 + 8 * (insert_length_code - 10)
extra_bits_insert = 3
elif insert_length_code == 12 or insert_length_code == 13:
insert_length = 34 + 16 * (insert_length_code - 12)
extra_bits_insert = 4
elif insert_length_code == 14 or insert_length_code == 15:
insert_length = 66 + 32 * (insert_length_code - 14)
extra_bits_insert = 5
elif insert_length_code == 16:
insert_length = 130
extra_bits_insert = 6
elif insert_length_code == 17:
insert_length = 194
extra_bits_insert = 7
elif insert_length_code == 18:
insert_length = 322
extra_bits_insert = 8
elif insert_length_code == 19:
insert_length = 578
extra_bits_insert = 9
elif insert_length_code == 20:
insert_length = 1090
extra_bits_insert = 10
elif insert_length_code == 21:
insert_length = 2114
extra_bits_insert = 12
elif insert_length_code == 22:
insert_length = 6210
extra_bits_insert = 14
elif insert_length_code == 23:
insert_length = 22594
extra_bits_insert = 24
else:
error() # print('unreachable')
if copy_length_code >= 0 and copy_length_code <= 7:
copy_length = copy_length_code + 2
extra_bits_copy = 0
elif copy_length_code == 8 or copy_length_code == 9:
copy_length = 10 + 2 * (copy_length_code - 8)
extra_bits_copy = 1
elif copy_length_code == 10 or copy_length_code == 11:
copy_length = 14 + 4 * (copy_length_code - 10)
extra_bits_copy = 2
elif copy_length_code == 12 or copy_length_code == 13:
copy_length = 22 + 8 * (copy_length_code - 12)
extra_bits_copy = 3
elif copy_length_code == 14 or copy_length_code == 15:
copy_length = 38 + 16 * (copy_length_code - 14)
extra_bits_copy = 4
elif copy_length_code == 16 or copy_length_code == 17:
copy_length = 70 + 32 * (copy_length_code - 16)
extra_bits_copy = 5
elif copy_length_code == 18:
copy_length = 134
extra_bits_copy = 6
elif copy_length_code == 19:
copy_length = 198
extra_bits_copy = 7
elif copy_length_code == 20:
copy_length = 326
extra_bits_copy = 8
elif copy_length_code == 21:
copy_length = 582
extra_bits_copy = 9
elif copy_length_code == 22:
copy_length = 1094
extra_bits_copy = 10
elif copy_length_code == 23:
copy_length = 2118
extra_bits_copy = 24
else:
error() # print('unreachable')
table[insert_and_copy_length*4] = insert_length
table[insert_and_copy_length*4 + 1] = extra_bits_insert
table[insert_and_copy_length*4 + 2] = copy_length
table[insert_and_copy_length*4 + 3] = extra_bits_copy
insert_and_copy_length += 1
INSERT_LENGTHS_AND_COPY_LENGTHS = table
# /lib.rs
PrefixCodeKind_Simple = 1
PrefixCodeKind_Complex = 2
PrefixCodeKind_Complex_data = NONE
StreamBegin = 1
HeaderBegin = 2
WBits = 3
WBits_data = 0
HeaderEnd = 4
HeaderMetaBlockBegin = 5
IsLast = 6
IsLast_data = 0
IsLastEmpty = 7
IsLastEmpty_data = 0
MNibbles = 8
MNibbles_data = 0
MSkipBytes = 9
MSkipBytes_data = 0
MSkipLen = 10
MSkipLen_data = 0
MLen = 11
MLen_data = 0
IsUncompressed = 12
IsUncompressed_data = 0
MLenLiterals = 13
MLenLiterals_data = 0 # []
NBltypesL = 14
NBltypesL_data = 0
PrefixCodeBlockTypesLiterals = 15
PrefixCodeBlockTypesLiterals_data = 0 # (HuffmanCodes)
PrefixCodeBlockCountsLiterals = 16
PrefixCodeBlockCountsLiterals_data = 0 # (HuffmanCodes)
FirstBlockCountLiterals = 17
FirstBlockCountLiterals_data = 0 # (BLen)
NBltypesI = 18
NBltypesI_data = 0
PrefixCodeBlockTypesInsertAndCopyLengths = 19
PrefixCodeBlockTypesInsertAndCopyLengths_data = 0 # (HuffmanCodes)
PrefixCodeBlockCountsInsertAndCopyLengths = 20
PrefixCodeBlockCountsInsertAndCopyLengths_data = 0 # (HuffmanCodes)
FirstBlockCountInsertAndCopyLengths = 21
FirstBlockCountInsertAndCopyLengths_data = 0
NBltypesD = 22
NBltypesD_data = 0 # (NBltypes)
PrefixCodeBlockTypesDistances = 23
PrefixCodeBlockTypesDistances_data = 0 # (HuffmanCodes)
PrefixCodeBlockCountsDistances = 24
PrefixCodeBlockCountsDistances_data = 0 # (HuffmanCodes)
FirstBlockCountDistances = 25
FirstBlockCountDistances_data = 0 #(BLen)
NPostfix = 26
NPostfix_data = 0
NDirect = 27
NDirect_data = 0
ContextModesLiterals = 28
ContextModesLiterals_data = 0 # (ContextModes)
NTreesL = 29
NTreesL_data = 0 # (NTrees)
NTreesD = 30
NTreesD_data = 0 #(NTrees)
ContextMapDistances = 31
ContextMapDistances_data = 0 # (ContextMap)
ContextMapLiterals = 32
ContextMapLiterals_data = 0 # (ContextMap)
PrefixCodesLiterals = 33
PrefixCodesLiterals_data = 0 # (Vec<HuffmanCodes>)
PrefixCodesInsertAndCopyLengths = 34
PrefixCodesInsertAndCopyLengths_data = 0 # (Vec<HuffmanCodes>)
PrefixCodesDistances = 35
PrefixCodesDistances_data = 0 # (Vec<HuffmanCodes>)
DataMetaBlockBegin = 36
InsertAndCopyLength = 37
InsertAndCopyLength_data = 0
InsertLengthAndCopyLength = 38
InsertLengthAndCopyLength_data_co_len = NONE
InsertLengthAndCopyLength_data_in_len = NONE
InsertLiterals = 39
InsertLiterals_data = 0 #(Literals)
DistanceCode = 40
DistanceCode_data = 0 #(DistanceCode)
Distance = 41
Distance_data = 0 # (Distance)
CopyLiterals = 42
CopyLiterals_data = 0 # (Literals)
DataMetaBlockEnd = 43
MetaBlockEnd = 44
StreamEnd = 45
t_array = alloc_pH(255)
i = 0
while i < 255:
t_array[i] = NONE
i += 1
t_array[1] = 16
t_array[24] = 21
t_array[25] = 19
t_array[26] = 23
t_array[27] = 18
t_array[28] = 22
t_array[29] = 20
t_array[30] = 24
t_array[191] = 17
t_array[192] = 12
t_array[193] = 10
t_array[194] = 14
t_array[196] = 13
t_array[197] = 11
t_array[198] = 15
header_wbits_codes = tree_from_raw_data(t_array, 15, 24)
t_array = alloc_pH(31)
i = 0
while i < 31:
t_array[i] = NONE
i += 1
t_array[3] = 0
t_array[4] = 3
t_array[5] = 4
t_array[13] = 2
t_array[29] = 1
t_array[30] = 5
header_bit_lengths_code = tree_from_raw_data(t_array, 6, 5)
t_array = alloc_pH(31)
i = 0
while i < 31:
t_array[i] = NONE
i += 1
t_array[1] = 1
t_array[23] = 2
t_array[24] = 17
t_array[25] = 5
t_array[26] = 65
t_array[27] = 3
t_array[28] = 33
t_array[29] = 9
t_array[30] = 129
header_bltype_codes = tree_from_raw_data(t_array, 9, 129)
header_wbits = NONE
header_window_size = NONE
output_window = NONE # RingBuffer []
output_window_pointer = 0
count_output = 0 # Decompressor.count_output
distance_buf = alloc_pH(4)
distance_buf[0] = 16 # reversed!
distance_buf[1] = 15
distance_buf[2] = 11
distance_buf[3] = 4
distance_buf_pointer = 3
literal_buf = alloc_pM(2)
literal_buf[0] = 0
literal_buf[1] = 0
literal_buf_pointer = 0
meta_block_header_is_last = NONE
meta_block_header_is_last_empty = NONE
meta_block_header_m_nibbles = NONE
meta_block_header_m_skip_bytes = NONE
meta_block_header_m_skip_len = NONE
meta_block_header_m_len = NONE
meta_block_header_is_uncompressed = NONE
meta_block_header_n_bltypes_l = NONE
meta_block_header_n_bltypes_i = NONE
meta_block_header_n_bltypes_d = NONE
meta_block_header_n_postfix = NONE
meta_block_header_n_direct = NONE
meta_block_header_n_trees_l = NONE
meta_block_header_n_trees_d = NONE
meta_block_header_c_map_l = NONE
meta_block_header_c_map_d = NONE
meta_block_prefix_tree_block_types_literals = NONE
meta_block_prefix_tree_block_counts_literals = NONE
meta_block_prefix_trees_literals = NONE
meta_block_count_output = 0
meta_block_btype_l = 0
meta_block_btype_l_prev = 1
meta_block_blen_l = NONE
meta_block_blen_i = NONE
meta_block_blen_d = NONE
meta_block_btype_i = 0
meta_block_btype_i_prev = 1
meta_block_btype_d = 0
meta_block_btype_d_prev = 1
meta_block_prefix_tree_block_types_insert_and_copy_lengths = NONE
meta_block_prefix_tree_block_counts_insert_and_copy_lengths = NONE
meta_block_prefix_tree_block_types_distances = NONE
meta_block_prefix_tree_block_counts_distances = NONE
meta_block_prefix_trees_insert_and_copy_lengths = NONE
meta_block_prefix_trees_distances = NONE
meta_block_context_modes_literals = NONE
meta_block_insert_and_copy_length = NONE
meta_block_copy_length = NONE
meta_block_insert_length = NONE
meta_block_distance = NONE
meta_block_distance_code = NONE
state = StreamBegin
def parse_wbits():
return lookup_symbol(header_wbits_codes)
def parse_is_last():
global IsLast_data
if read_bit():
error() # eof
else:
IsLast_data = read_bit_result
return IsLast
def parse_is_last_empty():
global IsLastEmpty_data
if read_bit():
error() # eof
else:
IsLastEmpty_data = read_bit_result
return IsLastEmpty
def parse_m_nibbles():
global MNibbles_data
if read_u32_from_n_bits(2):
error() # eof
if read_u32_from_n_bits_result == 3:
MNibbles_data = 0
return MNibbles
else:
MNibbles_data = read_u32_from_n_bits_result + 4
return MNibbles
def parse_m_skip_bytes():
global MSkipBytes_data
if read_u32_from_n_bits(2):
error() # eof
MSkipBytes_data = read_u32_from_n_bits_result
return MSkipBytes
def parse_m_skip_len():
global MSkipLen_data
bytes_ = read_fixed_length_string(meta_block_header_m_skip_bytes)
if bytes_ == NONE:
error() # eof
if meta_block_header_m_skip_bytes > 1 and bytes_[meta_block_header_m_skip_bytes - 1] == 0:
error()
MSkipLen_data = 0
i = 0
while i < meta_block_header_m_skip_bytes:
MSkipLen_data = MSkipLen_data | (bytes_[i] << i) # u32!
i += 1
return MSkipLen
def parse_m_len():
global MLen_data
if read_u32_from_n_nibbles(meta_block_header_m_nibbles):
error()
if meta_block_header_m_nibbles > 4 and (read_u32_from_n_nibbles_result >> ((meta_block_header_m_nibbles - 1)*4) == 0):
error() # NonZeroTrailerNibble
MLen_data = read_u32_from_n_nibbles_result + 1
return MLen
def parse_is_uncompressed():
global IsUncompressed_data
if read_bit():
error()
IsUncompressed_data = read_bit_result
return IsUncompressed
def parse_mlen_literals():
global MLenLiterals_data
MLenLiterals_data = read_fixed_length_string(meta_block_header_m_len)
if MLenLiterals_data == NONE:
error()
return MLenLiterals
def parse_n_bltypes():
value = lookup_symbol(header_bltype_codes)
if value == 1 or value == 2:
extra_bits = 0
elif value == 3:
extra_bits = 1
elif value == 5:
extra_bits = 2
elif value == 9:
extra_bits = 3
elif value == 17:
extra_bits = 4
elif value == 33:
extra_bits = 5
elif value == 65:
extra_bits = 6
elif value == 129:
extra_bits = 7
if extra_bits > 0:
if read_u32_from_n_bits(extra_bits):
error()
return value + read_u32_from_n_bits_result
else:
return value
def parse_n_bltypes_l():
global NBltypesL_data
NBltypesL_data = parse_n_bltypes()
if NBltypesL_data == NONE:
error()
return NBltypesL
def parse_n_bltypes_i():
global NBltypesI_data
NBltypesI_data = parse_n_bltypes()
if NBltypesI_data == NONE:
error()
return NBltypesI
def parse_n_bltypes_d():
global NBltypesD_data
NBltypesD_data = parse_n_bltypes()
if NBltypesD_data == NONE:
error()
return NBltypesD
def parse_n_postfix():
global NPostfix_data
if read_u32_from_n_bits(2):
error()
NPostfix_data = read_u32_from_n_bits_result
return NPostfix
def parse_n_direct():
global NDirect_data
if read_u32_from_n_bits(4):
error()
NDirect_data = read_u32_from_n_bits_result << meta_block_header_n_postfix
return NDirect
def parse_context_modes_literals():
global ContextModesLiterals_data
ContextModesLiterals_data = alloc_pM(meta_block_header_n_bltypes_l)
i = 0
while i < meta_block_header_n_bltypes_l:
if read_u32_from_n_bits(2):
error()
ContextModesLiterals_data[i] = read_u32_from_n_bits_result
i += 1
return ContextModesLiterals
def parse_n_trees_l():
global NTreesL_data
NTreesL_data = parse_n_bltypes()
if NTreesL_data == NONE:
error()
return NTreesL
def parse_n_trees_d():
global NTreesD_data
NTreesD_data = parse_n_bltypes()
if NTreesD_data == NONE:
error()
return NTreesD
def parse_prefix_code_kind():
global PrefixCodeKind_Complex_data
if read_u32_from_n_bits(2):
error()
if read_u32_from_n_bits_result == 1:
return PrefixCodeKind_Simple
PrefixCodeKind_Complex_data = read_u32_from_n_bits_result
return PrefixCodeKind_Complex
def parse_simple_prefix_code(alphabet_size):
#import ipdb; ipdb.set_trace()
bit_width = alphabet_size - 1
n = 0
# count leading zeros
if bit_width == 0:
n = 16
else:
while True:
if bit_width >= 32768: # 2**15
break
n += 1
bit_width <<= 1
bit_width = 16 - n
if read_u32_from_n_bits(2):
error()
n_sym = read_u32_from_n_bits_result + 1
symbols = alloc_pH(n_sym)
i = 0
while i < n_sym:
if read_u32_from_n_bits(bit_width):
error()
if read_u32_from_n_bits_result < alphabet_size:
symbols[i] = read_u32_from_n_bits_result
else:
error() # InvalidSymbol
i += 1
i = 0
while i < n_sym - 1:
j = i+1
while j < n_sym:
if symbols[i] == symbols[j]:
error() # InvalidSymbol
j += 1
i += 1
if n_sym == 4:
if read_bit():
error() # eof
tree_select = read_bit_result
else:
tree_select = NONE
if n_sym == 1 and tree_select == NONE:
code_lengths = alloc_pM(1)
code_lengths[0] = 0
elif n_sym == 2 and tree_select == NONE:
tmp_ = symbols[0]
if tmp_ > symbols[1]:
symbols[0] = symbols[1]
symbols[1] = tmp_
code_lengths = alloc_pM(2)
code_lengths[0] = 1
code_lengths[1] = 1
elif n_sym == 3 and tree_select == NONE:
# [1..3]rust sort ind 1...2
tmp_ = symbols[1]
if tmp_ > symbols[2]:
symbols[1] = symbols[2]
symbols[2] = tmp_
code_lengths = alloc_pM(3)
code_lengths[0] = 1
code_lengths[1] = 2
code_lengths[2] = 2
elif n_sym == 4 and tree_select == 0:
# sort all in-place with insertion sort
i = 1
while i < n_sym:
x = symbols[i]
j = i - 1
while j >= 0 and symbols[j] > x:
symbols[j+1] = symbols[j]
j = j - 1
symbols[j+1] = x
i += 1
code_lengths = alloc_pM(4)
code_lengths[0] = 2
code_lengths[1] = 2
code_lengths[2] = 2
code_lengths[3] = 2
elif n_sym == 4 and tree_select == 1:
# [2..4]rust sort ind 2...3
tmp_ = symbols[2]
if tmp_ > symbols[3]:
symbols[2] = symbols[3]
symbols[3] = tmp_
code_lengths = alloc_pM(4)
code_lengths[0] = 1
code_lengths[1] = 2
code_lengths[2] = 3
code_lengths[3] = 3
else:
error() # unreachable as len(symbols)<=4
ret = codes_from_lengths_and_symbols(code_lengths, symbols)
return ret
def parse_complex_prefix_code(h_skip, alphabet_size):
#import ipdb; ipdb.set_trace()
# symbols = [1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15]
bit_lengths_code = header_bit_lengths_code
code_lengths = alloc_pM(18)
i = 0
while i < 18:
code_lengths[i] = 0
i += 1
sum_ = 0
len_non_zero_codelengths = 0
i = h_skip
while i < 18:
code_length = lookup_symbol(bit_lengths_code)
if code_length == NONE:
error()
code_lengths[i] = code_length
if code_length > 0:
sum_ = sum_ + (32 >> code_length)
len_non_zero_codelengths += 1
#
# print("code length = ", code_lengths[i])
# print("32 >> code length = ", 32 >> code_lengths[i])
# print("sum = ", sum_)
#
if sum_ == 32:
break
if sum_ > 32:
error() # CodeLengthsChecksum
i += 1
if len_non_zero_codelengths == 0:
error() # NoCodeLength
if len_non_zero_codelengths >= 2 and sum_ < 32:
error() # CodeLengthsChecksum
new_code_lengths = alloc_pM(18)
new_code_lengths[0] = code_lengths[4]
new_code_lengths[1] = code_lengths[0]
new_code_lengths[2] = code_lengths[1]
new_code_lengths[3] = code_lengths[2]
new_code_lengths[4] = code_lengths[3]
new_code_lengths[5] = code_lengths[5]
new_code_lengths[6] = code_lengths[7]
new_code_lengths[7] = code_lengths[9]
new_code_lengths[8] = code_lengths[10]
new_code_lengths[9] = code_lengths[11]
new_code_lengths[10] = code_lengths[12]
new_code_lengths[11] = code_lengths[13]
new_code_lengths[12] = code_lengths[14]
new_code_lengths[13] = code_lengths[15]
new_code_lengths[14] = code_lengths[16]
new_code_lengths[15] = code_lengths[17]
new_code_lengths[16] = code_lengths[8]
new_code_lengths[17] = code_lengths[6]
code_lengths = new_code_lengths
symbols = alloc_pH(18)
i = 0
while i < 18:
symbols[i] = i
i += 1
prefix_code_code_lengths = codes_from_lengths_and_symbols(code_lengths, symbols)
actual_code_lengths = alloc_pM(alphabet_size)
i = 0
while i < alphabet_size:
actual_code_lengths[i] = 0
i += 1
sum_ = 0
last_symbol = NONE
last_repeat = NONE
last_non_zero_codelength = 8
i = 0
while i < alphabet_size:
code_length_code = lookup_symbol(prefix_code_code_lengths)
if code_length_code == NONE:
error()
if code_length_code >= 0 and code_length_code <= 15:
actual_code_lengths[i] = code_length_code
i += 1
last_symbol = code_length_code
last_repeat = NONE
if code_length_code > 0:
last_non_zero_codelength = code_length_code
sum_ += 32768 >> code_length_code
if sum_ == 32768:
break
elif sum_ > 32768:
error() # CodeLengthsChecksum
elif code_length_code == 16:
if read_u32_from_n_bits(2):
error() # UnexpectedEOF
extra_bits = read_u32_from_n_bits_result
if last_symbol == 16 and last_repeat != NONE:
new_repeat = 4 * (last_repeat - 2) + extra_bits + 3
if i + new_repeat - last_repeat > alphabet_size:
error() # ParseErrorComplexPrefixCodeLengths
j = 0
while j < new_repeat - last_repeat:
actual_code_lengths[i] = last_non_zero_codelength
i += 1
sum_ += 32768 >> last_non_zero_codelength
j += 1
if sum_ == 32768:
break
elif sum_ > 32768:
error() # CodeLengthsChecksum
last_repeat = new_repeat
else:
repeat = 3 + extra_bits
if i + repeat > alphabet_size:
error() # ParseErrorComplexPrefixCodeLengths
j = 0
while j < repeat:
actual_code_lengths[i] = last_non_zero_codelength
i += 1
sum_ += 32768 >> last_non_zero_codelength
j += 1
if sum_ == 32768:
break
elif sum_ > 32768:
error() # CodeLengthsChecksum
last_repeat = repeat
last_symbol = 16
elif code_length_code == 17:
if read_u32_from_n_bits(3):
error() # UnexpectedEOF
extra_bits = read_u32_from_n_bits_result
if last_symbol == 17 and last_repeat != NONE:
new_repeat = (8 * (last_repeat - 2)) + extra_bits + 3
i += new_repeat - last_repeat
last_repeat = new_repeat
else:
repeat = 3 + extra_bits
i += repeat
last_repeat = repeat
if i > alphabet_size:
error() # ParseErrorComplexPrefixCodeLengths
last_symbol = 17
else:
error() # unreachable OR ParseErrorComplexPrefixCodeLengths
tmp_ = 0
i = 0
while i < alphabet_size:
if actual_code_lengths[i] > 0:
tmp_ += 1
i += 1
if tmp_ < 2:
error() # LessThanTwoNonZeroCodeLengths
ret = codes_from_lengths(actual_code_lengths)
return ret
def parse_prefix_code(alphabet_size):
prefix_code_kind = parse_prefix_code_kind()
if prefix_code_kind == NONE:
error()
if prefix_code_kind == PrefixCodeKind_Complex:
return parse_complex_prefix_code(PrefixCodeKind_Complex_data, alphabet_size)
elif prefix_code_kind == PrefixCodeKind_Simple:
return parse_simple_prefix_code(alphabet_size)
else:
return NONE # unreachable
def parse_prefix_code_block_types_literals():
global PrefixCodeBlockTypesLiterals_data
alphabet_size = meta_block_header_n_bltypes_l + 2
tmp_ = parse_prefix_code(alphabet_size)
if tmp_ == NONE:
error()
PrefixCodeBlockTypesLiterals_data = tmp_
return PrefixCodeBlockTypesLiterals
def parse_prefix_code_block_counts_literals():
global PrefixCodeBlockCountsLiterals_data
tmp_ = parse_prefix_code(26)
if tmp_ == NONE:
error()
PrefixCodeBlockCountsLiterals_data = tmp_
return PrefixCodeBlockCountsLiterals
def parse_prefix_code_block_types_insert_and_copy_lengths():
global PrefixCodeBlockTypesInsertAndCopyLengths_data
alphabet_size = meta_block_header_n_bltypes_i + 2
tmp_ = parse_prefix_code(alphabet_size)
if tmp_ == NONE:
error()
PrefixCodeBlockTypesInsertAndCopyLengths_data = tmp_
return PrefixCodeBlockTypesInsertAndCopyLengths
def parse_prefix_code_block_counts_insert_and_copy_lengths():
global PrefixCodeBlockCountsInsertAndCopyLengths_data
tmp_ = parse_prefix_code(26)
if tmp_ == NONE:
error()
PrefixCodeBlockCountsInsertAndCopyLengths_data = tmp_
return PrefixCodeBlockCountsInsertAndCopyLengths
def parse_prefix_code_block_types_distances():
global PrefixCodeBlockTypesDistances_data
alphabet_size = meta_block_header_n_bltypes_d + 2
tmp_ = parse_prefix_code(alphabet_size)
if tmp_ == NONE:
error()
PrefixCodeBlockTypesDistances_data = tmp_
return PrefixCodeBlockTypesDistances
def parse_prefix_code_block_counts_distances():
global PrefixCodeBlockCountsDistances_data
tmp_ = parse_prefix_code(26)
if tmp_ == NONE:
error()
PrefixCodeBlockCountsDistances_data = tmp_
return PrefixCodeBlockCountsDistances
def parse_block_count(prefix_code): # HuffmanCodes
symbol = lookup_symbol(prefix_code)
if symbol >= 0 and symbol <= 3:
base_length = 1 + (symbol << 2)
extra_bits = 2
elif symbol >= 4 and symbol <= 7:
base_length = 17 + ((symbol - 4) << 3)
extra_bits = 3
elif symbol >= 8 and symbol <= 11:
base_length = 49 + ((symbol - 8) << 4)
extra_bits = 4
elif symbol >= 12 and symbol <= 15:
base_length = 113 + ((symbol - 12) << 5)
extra_bits = 5
elif symbol >= 16 and symbol <= 17:
base_length = 241 + ((symbol - 16) << 6)
extra_bits = 6
elif symbol == 18:
base_length = 369
extra_bits = 7
elif symbol == 19:
base_length = 497
extra_bits = 8
elif symbol == 20:
base_length = 753
extra_bits = 9
elif symbol == 21:
base_length = 1265
extra_bits = 10
elif symbol == 22:
base_length = 2289
extra_bits = 11
elif symbol == 23:
base_length = 4337
extra_bits = 12
elif symbol == 24:
base_length = 8433
extra_bits = 13
elif symbol == 25:
base_length = 16625
extra_bits = 24
else:
error() # err EOF OR InvalidBlockCountCode
if read_u32_from_n_bits(extra_bits):
error() # err EOF
return base_length + read_u32_from_n_bits_result
def parse_first_block_count_literals():
global FirstBlockCountLiterals_data
prefix_code = meta_block_prefix_tree_block_counts_literals
FirstBlockCountLiterals_data = parse_block_count(prefix_code)
if FirstBlockCountLiterals_data == NONE:
error()
return FirstBlockCountLiterals
def parse_first_block_count_insert_and_copy_lengths():
global FirstBlockCountInsertAndCopyLengths_data
prefix_code = meta_block_prefix_tree_block_counts_insert_and_copy_lengths
FirstBlockCountInsertAndCopyLengths_data = parse_block_count(prefix_code)
if FirstBlockCountInsertAndCopyLengths_data == NONE:
error()
return FirstBlockCountInsertAndCopyLengths
def parse_first_block_count_distances():
global FirstBlockCountDistances_data
prefix_code = meta_block_prefix_tree_block_counts_distances
FirstBlockCountDistances_data = parse_block_count(prefix_code)
if FirstBlockCountDistances_data == NONE:
error()
return FirstBlockCountDistances
def parse_prefix_codes_literals():
global PrefixCodesLiterals_data
n_trees_l = meta_block_header_n_trees_l
prefix_codes = alloc_L(n_trees_l)
alphabet_size = 256
j = 0
while j < n_trees_l:
prefix_codes[j] = parse_prefix_code(alphabet_size)
if prefix_codes[j] == NONE:
error()
j += 1
PrefixCodesLiterals_data = prefix_codes
return PrefixCodesLiterals
def parse_prefix_codes_insert_and_copy_lengths():
global PrefixCodesInsertAndCopyLengths_data
n_bltypes_i = meta_block_header_n_bltypes_i
prefix_codes = alloc_L(n_bltypes_i)
alphabet_size = 704
j = 0
while j < n_bltypes_i:
prefix_codes[j] = parse_prefix_code(alphabet_size)
if prefix_codes[j] == NONE:
error()
j += 1
PrefixCodesInsertAndCopyLengths_data = prefix_codes
return PrefixCodesInsertAndCopyLengths
def parse_prefix_codes_distances():
global PrefixCodesDistances_data
n_trees_d = meta_block_header_n_trees_d
prefix_codes = alloc_L(n_trees_d)
alphabet_size = 16 + meta_block_header_n_direct + (48 << meta_block_header_n_postfix)
j = 0
while j < n_trees_d:
prefix_codes[j] = parse_prefix_code(alphabet_size)
if prefix_codes[j] == NONE:
error()
j += 1
PrefixCodesDistances_data = prefix_codes
return PrefixCodesDistances
def parse_context_map(n_trees, len_):
if read_bit():
error() # err eof
rlemax = read_bit_result
if rlemax:
if read_u32_from_n_bits(4):
error() # err eof
rlemax = read_u32_from_n_bits_result + 1
alphabet_size = rlemax + n_trees
prefix_tree = parse_prefix_code(alphabet_size)
if prefix_tree == NONE:
error() # err
c_map = alloc_pM(len_)
c_pushed = 0
while c_pushed < len_:
run_length_code = lookup_symbol(prefix_tree)
if run_length_code == NONE:
error() # err eof OR ParseErrorContextMap
if run_length_code > 0 and run_length_code <= rlemax:
if read_u32_from_n_bits(run_length_code):
error() # err eof
repeat = (1 << run_length_code) + read_u32_from_n_bits_result
j = 0
while j < repeat:
c_map[c_pushed] = 0
c_pushed += 1
if c_pushed > len_:
error() # RunLengthExceededSizeOfContextMap
j += 1
else:
if run_length_code == 0:
c_map[c_pushed] = 0
else:
c_map[c_pushed] = run_length_code - rlemax
c_pushed += 1
if read_bit():
error() # err eof
imtf_bit = read_bit_result
if imtf_bit:
inverse_move_to_front_transform(c_map) # mut c_map
return c_map
def parse_context_map_literals():
global ContextMapLiterals_data
n_trees = meta_block_header_n_trees_l
len_ = meta_block_header_n_bltypes_l * 64
ContextMapLiterals_data = parse_context_map(n_trees, len_)
if ContextMapLiterals_data == NONE:
error() # err
return ContextMapLiterals
def parse_context_map_distances():
global ContextMapDistances_data
n_trees = meta_block_header_n_trees_d
len_ = meta_block_header_n_bltypes_d * 4
ContextMapDistances_data = parse_context_map(n_trees, len_)
if ContextMapDistances_data == NONE:
error() # err
return ContextMapDistances
def inverse_move_to_front_transform(v): # modifies v
mtf = alloc_pM(256)
i = 0
while i < 256:
mtf[i] = i
i += 1
i = 0
while i < len(v):
index = v[i]
value = mtf[index]
v[i] = value
j = index
while j > 0:
mtf[j] = mtf[j - 1]
j -= 1
mtf[0] = value
i += 1
def decode_insert_and_copy_length():
global InsertLengthAndCopyLength_data_co_len, InsertLengthAndCopyLength_data_in_len
insert_length = INSERT_LENGTHS_AND_COPY_LENGTHS[0 + meta_block_insert_and_copy_length*4]
extra_bits_insert = INSERT_LENGTHS_AND_COPY_LENGTHS[1 + meta_block_insert_and_copy_length*4]
copy_length = INSERT_LENGTHS_AND_COPY_LENGTHS[2 + meta_block_insert_and_copy_length*4]
extra_bits_copy = INSERT_LENGTHS_AND_COPY_LENGTHS[3 + meta_block_insert_and_copy_length*4]
if read_u32_from_n_bits(extra_bits_insert):
error() # err eof
insert_length += read_u32_from_n_bits_result
if read_u32_from_n_bits(extra_bits_copy):
error() # err eof
copy_length += read_u32_from_n_bits_result
InsertLengthAndCopyLength_data_co_len = copy_length
InsertLengthAndCopyLength_data_in_len = insert_length
return InsertLengthAndCopyLength
parse_block_switch_command_block_type = NONE
parse_block_switch_command_block_count = NONE
def parse_block_switch_command(prefix_tree_types, btype, btype_prev, n_bltypes, prefix_tree_counts): # 1:HuffmanCodes,2-4:nr,5:HuffmanCodes
global parse_block_switch_command_block_type, parse_block_switch_command_block_count
block_type_code = lookup_symbol(prefix_tree_types)
if block_type_code == NONE:
error() # decompr err
if block_type_code == 0:
block_type = btype_prev
elif block_type_code == 1:
block_type = (btype + 1) % n_bltypes
elif block_type_code >= 2 and block_type_code <= 258:
block_type = block_type_code - 2
else:
return NONE # unreachable
block_count = parse_block_count(prefix_tree_counts)
if block_count == NONE:
error() # err
parse_block_switch_command_block_type = block_type
parse_block_switch_command_block_count = block_count
return 0
parse_block_switch_command_literals_block_type = NONE
parse_block_switch_command_literals_block_count = NONE
def parse_block_switch_command_literals():
global parse_block_switch_command_literals_block_type, parse_block_switch_command_literals_block_count
prefix_tree_types = meta_block_prefix_tree_block_types_literals
btype = meta_block_btype_l
btype_prev = meta_block_btype_l_prev
n_bltypes = meta_block_header_n_bltypes_l
prefix_tree_counts = meta_block_prefix_tree_block_counts_literals
if parse_block_switch_command(prefix_tree_types, btype, btype_prev, n_bltypes, prefix_tree_counts):
error() # err
parse_block_switch_command_literals_block_type = parse_block_switch_command_block_type
parse_block_switch_command_literals_block_count = parse_block_switch_command_block_count
return 0
parse_block_switch_command_insert_and_copy_lengths_block_type = NONE
parse_block_switch_command_insert_and_copy_lengths_block_count = NONE
def parse_block_switch_command_insert_and_copy_lengths():
global parse_block_switch_command_insert_and_copy_lengths_block_type, parse_block_switch_command_insert_and_copy_lengths_block_count
prefix_tree_types = meta_block_prefix_tree_block_types_insert_and_copy_lengths
btype = meta_block_btype_i
btype_prev = meta_block_btype_i_prev
n_bltypes = meta_block_header_n_bltypes_i
prefix_tree_counts = meta_block_prefix_tree_block_counts_insert_and_copy_lengths
if parse_block_switch_command(prefix_tree_types, btype, btype_prev, n_bltypes, prefix_tree_counts):
error() # err
parse_block_switch_command_insert_and_copy_lengths_block_type = parse_block_switch_command_block_type
parse_block_switch_command_insert_and_copy_lengths_block_count = parse_block_switch_command_block_count
return 0
def parse_insert_and_copy_length():
global meta_block_btype_i_prev, meta_block_blen_i, meta_block_btype_i, InsertAndCopyLength_data
if meta_block_blen_i == NONE:
pass
elif meta_block_blen_i == 0:
if parse_block_switch_command_insert_and_copy_lengths():
error() # err
meta_block_btype_i_prev = meta_block_btype_i
meta_block_btype_i = parse_block_switch_command_insert_and_copy_lengths_block_type
meta_block_blen_i = parse_block_switch_command_insert_and_copy_lengths_block_count - 1
else:
meta_block_blen_i -= 1
btype = meta_block_btype_i
InsertAndCopyLength_data = lookup_symbol(meta_block_prefix_trees_insert_and_copy_lengths[btype])
if InsertAndCopyLength_data == NONE:
error() # err eof OR ParseErrorInsertAndCopyLength
return InsertAndCopyLength
parse_block_switch_command_distances_block_type = NONE
parse_block_switch_command_distances_block_count = NONE
def parse_block_switch_command_distances():
global parse_block_switch_command_distances_block_type, parse_block_switch_command_distances_block_count
prefix_tree_types = meta_block_prefix_tree_block_types_distances
btype = meta_block_btype_d
btype_prev = meta_block_btype_d_prev
n_bltypes = meta_block_header_n_bltypes_d
prefix_tree_counts = meta_block_prefix_tree_block_counts_distances
if parse_block_switch_command(prefix_tree_types, btype, btype_prev, n_bltypes, prefix_tree_counts):
error() # err
parse_block_switch_command_distances_block_type = parse_block_switch_command_block_type
parse_block_switch_command_distances_block_count = parse_block_switch_command_block_count
return 0
def parse_insert_literals():
global literal_buf_pointer, meta_block_btype_l_prev, meta_block_btype_l, meta_block_blen_l, InsertLiterals_data
insert_length = meta_block_insert_length
literals = alloc_pM(insert_length)
j = 0
while j < insert_length:
if meta_block_blen_l == NONE:
pass
elif meta_block_blen_l == 0:
if parse_block_switch_command_literals():
error()
meta_block_btype_l_prev = meta_block_btype_l
meta_block_btype_l = parse_block_switch_command_literals_block_type
meta_block_blen_l = parse_block_switch_command_literals_block_count - 1
else:
meta_block_blen_l -= 1
btype = meta_block_btype_l
context_mode = meta_block_context_modes_literals[btype]
p1 = literal_buf[literal_buf_pointer]
p2 = literal_buf[(literal_buf_pointer+1) % 2]
if context_mode == 0:
cid = p1 & 63
elif context_mode == 1:
cid = p1 >> 2
elif context_mode == 2:
cid = LUT_0[p1] | LUT_1[p2]
elif context_mode == 3:
cid = (LUT_2[p1] << 3) | LUT_2[p2]
else:
return NONE # unreachable
index = meta_block_header_c_map_l[btype * 64 + cid]
tmp_ = lookup_symbol(meta_block_prefix_trees_literals[index])
if tmp_ == NONE:
error() # err eof OR ParseErrorInsertLiterals
literals[j] = tmp_
literal_buf_pointer = (literal_buf_pointer+1) % 2
literal_buf[literal_buf_pointer] = tmp_
j += 1
InsertLiterals_data = literals
return InsertLiterals
def parse_distance_code():
global meta_block_btype_d_prev, meta_block_btype_d, meta_block_blen_d, DistanceCode_data
if meta_block_distance == 0:
DistanceCode_data = 0
return DistanceCode
elif meta_block_distance == NONE:
pass
else:
return NONE # unreachable
if meta_block_blen_d == NONE:
pass
elif meta_block_blen_d == 0:
if parse_block_switch_command_distances():
error() # err
meta_block_btype_d_prev = meta_block_btype_d
meta_block_btype_d = parse_block_switch_command_distances_block_type
meta_block_blen_d = parse_block_switch_command_distances_block_count - 1
else:
meta_block_blen_d -= 1
if meta_block_copy_length == 0 or meta_block_copy_length == 1:
error() # unreachable
elif meta_block_copy_length == 2 or meta_block_copy_length == 3 or meta_block_copy_length == 4:
cid = meta_block_copy_length - 2
else:
cid = 3
index = meta_block_header_c_map_d[meta_block_btype_d * 4 + cid]
DistanceCode_data = lookup_symbol(meta_block_prefix_trees_distances[index])
if DistanceCode_data == NONE:
error() # err decompr ParseErrorDistanceCode OR eof
return DistanceCode
def decode_distance():
global Distance_data, distance_buf_pointer
if meta_block_distance_code == NONE:
error() # unreachable
elif meta_block_distance_code >= 0 and meta_block_distance_code <= 3:
distance = distance_buf[(4 + distance_buf_pointer - meta_block_distance_code) % 4]
#if distance == NONE:
# error() # RingBufferError
elif meta_block_distance_code >= 4 and meta_block_distance_code <= 9:
distance = distance_buf[distance_buf_pointer]
sign = meta_block_distance_code % 2
d = (meta_block_distance_code - 2) >> 1
if sign: # case +
distance = distance + d
else: # case -
if distance <= d:
error() # InvalidNonPositiveDistance
distance = distance - d
elif meta_block_distance_code >= 10 and meta_block_distance_code <= 15:
distance = distance_buf[(3 + distance_buf_pointer) % 4]
sign = meta_block_distance_code % 2
d = (meta_block_distance_code - 8) >> 1
if sign: # case +
distance = distance + d
else: # case -
if distance <= d:
error() # InvalidNonPositiveDistance
distance = distance - d
elif meta_block_distance_code <= (15 + meta_block_header_n_direct):
distance = meta_block_distance_code - 15
else:
n_direct = meta_block_header_n_direct
n_postfix = meta_block_header_n_postfix
ndistbits = 1 + ((meta_block_distance_code - n_direct - 16) >> (n_postfix + 1))
if read_u32_from_n_bits(ndistbits):
error() # eof err
dextra = read_u32_from_n_bits_result
hcode = (meta_block_distance_code - n_direct - 16) >> n_postfix
postfix_mask = (1 << n_postfix) - 1
lcode = (meta_block_distance_code - n_direct - 16) & postfix_mask
offset = ((2 + (hcode & 1)) << ndistbits) - 4
distance = ((offset + dextra) << n_postfix) + lcode + n_direct + 1
if meta_block_distance_code > 0 and distance <= header_window_size and distance <= count_output:
distance_buf_pointer = (distance_buf_pointer + 1) % 4
distance_buf[distance_buf_pointer] = distance
Distance_data = distance
return Distance
def copy_literals():
global CopyLiterals_data
window_size = header_window_size
copy_length = meta_block_copy_length
distance = meta_block_distance
max_allowed_distance = count_output
if window_size < max_allowed_distance:
max_allowed_distance = window_size
if distance <= max_allowed_distance:
window = alloc_pM(copy_length)
l = distance
if copy_length < l:
l = copy_length
# output_window.slice_tail(distance - 1, &mut window)
n = distance - 1
i = 0
while i < copy_length:
t = (output_window_pointer + len(output_window) - n + i) % len(output_window)
window[i] = output_window[t]
i += 1
i = 0
while i < copy_length:
window[i] = window[i % l]
i += 1
CopyLiterals_data = window
return CopyLiterals
else:
if copy_length < 4 or copy_length > 24:
error() # InvalidLengthInStaticDictionary
word_id = distance - max_allowed_distance - 1
if copy_length < 4:
n_words_length = 0
else:
n_words_length = 1 << BROTLI_DICTIONARY_SIZE_BITS_BY_LENGTH[copy_length]
index = word_id % n_words_length
offset_from = BROTLI_DICTIONARY_OFFSETS_BY_LENGTH[copy_length] + index * copy_length
offset_to = BROTLI_DICTIONARY_OFFSETS_BY_LENGTH[copy_length] + (index + 1) * copy_length
base_word = alloc_pM(offset_to-offset_from)
i = 0
while i < offset_to-offset_from:
base_word[i] = BROTLI_DICTIONARY[i + offset_from]
i += 1
transform_id = word_id >> BROTLI_DICTIONARY_SIZE_BITS_BY_LENGTH[copy_length]
if transform_id > 120:
error() # InvalidTransformId
# print(bytes(eval('array.'+str(base_word)))) # remove
CopyLiterals_data = transformation(transform_id, base_word)
# print(transform_id, bytes(eval('array.'+str(CopyLiterals_data)))) # remove
return CopyLiterals
def brotlidec(pinput, outb, cmpbuf=None):
"""pinput: input buffer, needs to support len() and []
outb: output buffer, needs to support .append()
returns bytes(outb)"""
global count_output, header_wbits, header_window_size, literal_buf_pointer, meta_block_blen_d
global meta_block_blen_i, meta_block_blen_l, meta_block_context_modes_literals, meta_block_copy_length
global meta_block_count_output, meta_block_distance, meta_block_distance_code, meta_block_header_c_map_d
global meta_block_btype_l_prev, meta_block_btype_l, meta_block_btype_i, meta_block_btype_i_prev
global meta_block_btype_d, meta_block_btype_d_prev
global meta_block_header_c_map_l, meta_block_header_is_last, meta_block_header_is_last_empty
global meta_block_header_is_uncompressed, meta_block_header_m_len, meta_block_header_m_nibbles
global meta_block_header_m_skip_bytes, meta_block_header_m_skip_len, meta_block_header_n_bltypes_d
global meta_block_header_n_bltypes_i, meta_block_header_n_bltypes_l, meta_block_header_n_direct
global meta_block_header_n_postfix, meta_block_header_n_trees_d, meta_block_header_n_trees_l
global meta_block_insert_and_copy_length, meta_block_insert_length, meta_block_prefix_tree_block_counts_distances
global meta_block_prefix_tree_block_counts_insert_and_copy_lengths, meta_block_prefix_tree_block_counts_literals
global meta_block_prefix_tree_block_types_distances, meta_block_prefix_tree_block_types_insert_and_copy_lengths
global meta_block_prefix_tree_block_types_literals, meta_block_prefix_trees_distances
global meta_block_prefix_trees_insert_and_copy_lengths, meta_block_prefix_trees_literals
global output_window, output_window_pointer, state, WBits_data, BROTLI_DICTIONARY
global distance_buf, distance_buf_pointer, literal_buf
global bit_pos, current_byte, global_bit_pos
global input_buf, input_buf_pos, output_buf, gcmpbuf, cmpbuf_pos
dir_path = os.path.dirname(os.path.abspath(__file__))
fo = open(extract_zipped_paths(os.path.join(dir_path,'brotli-dict')),'rb')
BROTLI_DICTIONARY = fo.read()
fo.close()
input_buf_pos = 0
input_buf = pinput
output_buf = outb
gcmpbuf = cmpbuf
if cmpbuf is not None:
cmpbuf_pos = 0
# import ipdb; ipdb.set_trace() # r
state = StreamBegin
while True:
# print("state",state)
# import ipdb; ipdb.set_trace() # c
if state == StreamBegin:
state = HeaderBegin
distance_buf[0] = 16 # reversed!
distance_buf[1] = 15
distance_buf[2] = 11
distance_buf[3] = 4
distance_buf_pointer = 3
literal_buf[0] = 0
literal_buf[1] = 0
literal_buf_pointer = 0
count_output = 0
bit_pos = 0
current_byte = NONE
global_bit_pos = 0
elif state == NONE: # dec err
error()
return
elif state == HeaderBegin:
state = WBits
WBits_data = parse_wbits()
elif state == WBits:
header_wbits = WBits_data
header_window_size = (1 << WBits_data) - 16
output_window = alloc_pM(header_window_size)
output_window_pointer = 0
state = HeaderEnd
elif state == HeaderEnd:
state = HeaderMetaBlockBegin
elif state == HeaderMetaBlockBegin:
meta_block_header_is_last = NONE
meta_block_header_is_last_empty = NONE
meta_block_header_m_nibbles = NONE
meta_block_header_m_skip_bytes = NONE
meta_block_header_m_skip_len = NONE
meta_block_header_m_len = NONE
meta_block_header_is_uncompressed = NONE
meta_block_header_n_bltypes_l = NONE
meta_block_header_n_bltypes_i = NONE
meta_block_header_n_bltypes_d = NONE
meta_block_header_n_postfix = NONE
meta_block_header_n_direct = NONE
meta_block_header_n_trees_l = NONE
meta_block_header_n_trees_d = NONE
meta_block_header_c_map_l = NONE
meta_block_header_c_map_d = NONE
meta_block_prefix_tree_block_types_literals = NONE
meta_block_prefix_tree_block_counts_literals = NONE
meta_block_prefix_trees_literals = NONE
meta_block_count_output = 0
meta_block_btype_l = 0
meta_block_btype_l_prev = 1
meta_block_blen_l = NONE
meta_block_blen_i = NONE
meta_block_blen_d = NONE
meta_block_btype_i = 0
meta_block_btype_i_prev = 1
meta_block_btype_d = 0
meta_block_btype_d_prev = 1
meta_block_prefix_tree_block_types_insert_and_copy_lengths = NONE
meta_block_prefix_tree_block_counts_insert_and_copy_lengths = NONE
meta_block_prefix_tree_block_types_distances = NONE
meta_block_prefix_tree_block_counts_distances = NONE
meta_block_prefix_trees_insert_and_copy_lengths = NONE
meta_block_prefix_trees_distances = NONE
meta_block_context_modes_literals = NONE
meta_block_insert_and_copy_length = NONE
meta_block_copy_length = NONE
meta_block_insert_length = NONE
meta_block_distance = NONE
meta_block_distance_code = NONE
state = parse_is_last()
elif state == IsLast and IsLast_data == 1:
meta_block_header_is_last = 1
state = parse_is_last_empty()
elif state == IsLast and IsLast_data == 0:
meta_block_header_is_last = 0
state = parse_m_nibbles()
elif state == IsLastEmpty and IsLastEmpty_data == 1:
meta_block_header_is_last_empty = 1
state = StreamEnd
elif state == IsLastEmpty and IsLastEmpty_data == 0:
meta_block_header_is_last_empty = 0
state = parse_m_nibbles()
elif state == MNibbles and MNibbles_data == 0:
if read_bit():
error() # eof
if read_bit_result:
error() # NonZeroReservedBit
return
meta_block_header_m_nibbles = 0
state = parse_m_skip_bytes()
elif state == MNibbles:
meta_block_header_m_nibbles = MNibbles_data
state = parse_m_len()
elif state == MSkipBytes and MSkipBytes_data == 0:
meta_block_header_m_skip_bytes = 0
if read_u8_from_byte_tail() != 0:
error() # NonZeroFillBit
return
state = MetaBlockEnd
elif state == MSkipBytes:
meta_block_header_m_skip_bytes = MSkipBytes_data
state = parse_m_skip_len()
elif state == MSkipLen:
meta_block_header_m_skip_len = MSkipLen_data
if read_u8_from_byte_tail() != 0:
error() # NonZeroFillBit
return
state = MetaBlockEnd
elif state == MLen:
meta_block_header_m_len = MLen_data
if meta_block_header_is_last:
state = parse_n_bltypes_l()
else:
state = parse_is_uncompressed()
elif state == IsUncompressed and IsUncompressed_data == 1:
meta_block_header_is_uncompressed = 1
if read_u8_from_byte_tail() != 0:
error() # NonZeroFillBit
state = parse_mlen_literals()
elif state == MLenLiterals:
i = 0
while i < len(MLenLiterals_data):
literal = MLenLiterals_data[i]
out(literal)
output_window_pointer = (output_window_pointer + 1) % len(output_window)
output_window[output_window_pointer] = literal
literal_buf_pointer = (literal_buf_pointer + 1) % 2
literal_buf[literal_buf_pointer] = literal
count_output += 1
i += 1
state = MetaBlockEnd
elif state == IsUncompressed and IsUncompressed_data == 0:
meta_block_header_is_uncompressed = 0
state = parse_n_bltypes_l()
elif state == NBltypesL:
meta_block_header_n_bltypes_l = NBltypesL_data
if NBltypesL_data >= 2:
state = parse_prefix_code_block_types_literals()
else:
state = parse_n_bltypes_i()
elif state == PrefixCodeBlockTypesLiterals:
meta_block_prefix_tree_block_types_literals = PrefixCodeBlockTypesLiterals_data
state = parse_prefix_code_block_counts_literals()
elif state == PrefixCodeBlockCountsLiterals:
meta_block_prefix_tree_block_counts_literals = PrefixCodeBlockCountsLiterals_data
state = parse_first_block_count_literals()
elif state == FirstBlockCountLiterals:
meta_block_blen_l = FirstBlockCountLiterals_data
state = parse_n_bltypes_i()
elif state == NBltypesI:
meta_block_header_n_bltypes_i = NBltypesI_data
if NBltypesI_data >= 2:
state = parse_prefix_code_block_types_insert_and_copy_lengths()
else:
state = parse_n_bltypes_d()
elif state == PrefixCodeBlockTypesInsertAndCopyLengths:
meta_block_prefix_tree_block_types_insert_and_copy_lengths = PrefixCodeBlockTypesInsertAndCopyLengths_data
state = parse_prefix_code_block_counts_insert_and_copy_lengths()
elif state == PrefixCodeBlockCountsInsertAndCopyLengths:
meta_block_prefix_tree_block_counts_insert_and_copy_lengths = PrefixCodeBlockCountsInsertAndCopyLengths_data
state = parse_first_block_count_insert_and_copy_lengths()
elif state == FirstBlockCountInsertAndCopyLengths:
meta_block_blen_i = FirstBlockCountInsertAndCopyLengths_data
state = parse_n_bltypes_d()
elif state == NBltypesD:
meta_block_header_n_bltypes_d = NBltypesD_data
if NBltypesD_data >= 2:
state = parse_prefix_code_block_types_distances()
else:
state = parse_n_postfix()
elif state == PrefixCodeBlockTypesDistances:
meta_block_prefix_tree_block_types_distances = PrefixCodeBlockTypesDistances_data
state = parse_prefix_code_block_counts_distances()
elif state == PrefixCodeBlockCountsDistances:
meta_block_prefix_tree_block_counts_distances = PrefixCodeBlockCountsDistances_data
state = parse_first_block_count_distances()
elif state == FirstBlockCountDistances:
meta_block_blen_d = FirstBlockCountDistances_data
state = parse_n_postfix()
elif state == NPostfix:
meta_block_header_n_postfix = NPostfix_data
state = parse_n_direct()
elif state == NDirect:
meta_block_header_n_direct = NDirect_data
state = parse_context_modes_literals()
elif state == ContextModesLiterals:
meta_block_context_modes_literals = ContextModesLiterals_data
state = parse_n_trees_l()
elif state == NTreesL:
meta_block_header_n_trees_l = NTreesL_data
meta_block_header_c_map_l = alloc_pM(64 * meta_block_header_n_bltypes_l)
if NTreesL_data >= 2:
state = parse_context_map_literals()
else:
state = parse_n_trees_d()
elif state == ContextMapLiterals:
meta_block_header_c_map_l = ContextMapLiterals_data
state = parse_n_trees_d()
elif state == NTreesD:
meta_block_header_n_trees_d = NTreesD_data
meta_block_header_c_map_d = alloc_pM(4 * meta_block_header_n_bltypes_d)
if NTreesD_data >= 2:
state = parse_context_map_distances()
else:
state = parse_prefix_codes_literals()
elif state == ContextMapDistances:
meta_block_header_c_map_d = ContextMapDistances_data
state = parse_prefix_codes_literals()
elif state == PrefixCodesLiterals:
meta_block_prefix_trees_literals = PrefixCodesLiterals_data
state = parse_prefix_codes_insert_and_copy_lengths()
elif state == PrefixCodesInsertAndCopyLengths:
meta_block_prefix_trees_insert_and_copy_lengths = PrefixCodesInsertAndCopyLengths_data
state = parse_prefix_codes_distances()
elif state == PrefixCodesDistances:
meta_block_prefix_trees_distances = PrefixCodesDistances_data
state = DataMetaBlockBegin
elif state == DataMetaBlockBegin:
state = parse_insert_and_copy_length()
elif state == InsertAndCopyLength:
meta_block_insert_and_copy_length = InsertAndCopyLength_data
if InsertAndCopyLength_data >= 0 and InsertAndCopyLength_data <= 127:
meta_block_distance = 0
else:
meta_block_distance = NONE
state = decode_insert_and_copy_length()
elif state == InsertLengthAndCopyLength:
m_len = meta_block_header_m_len
meta_block_insert_length = InsertLengthAndCopyLength_data_in_len
meta_block_copy_length = InsertLengthAndCopyLength_data_co_len
if m_len < meta_block_count_output + meta_block_insert_length: # or (m_len > meta_block_count_output + meta_block_insert_length and m_len < meta_block_count_output + meta_block_insert_length + meta_block_copy_length)
error() # ExceededExpectedBytes
state = parse_insert_literals()
elif state == InsertLiterals:
m_len = meta_block_header_m_len
if m_len < meta_block_count_output + len(InsertLiterals_data):
error() # ExceededExpectedBytes
i = 0
while i < len(InsertLiterals_data):
literal = InsertLiterals_data[i]
out(literal)
output_window_pointer = (output_window_pointer + 1) % len(output_window)
output_window[output_window_pointer] = literal
count_output += 1
meta_block_count_output += 1
i += 1
if meta_block_header_m_len == meta_block_count_output:
state = DataMetaBlockEnd
else:
state = parse_distance_code()
elif state == DistanceCode:
meta_block_distance_code = DistanceCode_data
state = decode_distance()
elif state == Distance:
meta_block_distance = Distance_data
state = copy_literals()
elif state == CopyLiterals:
m_len = meta_block_header_m_len
if m_len < meta_block_count_output + len(CopyLiterals_data):
error() # err ExceededExpectedBytes
i = 0
while i < len(CopyLiterals_data):
literal = CopyLiterals_data[i]
out(literal)
literal_buf_pointer = (literal_buf_pointer + 1) % 2
literal_buf[literal_buf_pointer] = literal
output_window_pointer = (output_window_pointer + 1) % len(output_window)
output_window[output_window_pointer] = literal
count_output += 1
meta_block_count_output += 1
i += 1
if meta_block_header_m_len == meta_block_count_output:
state = DataMetaBlockEnd
else:
state = DataMetaBlockBegin
elif state == DataMetaBlockEnd:
state = MetaBlockEnd
elif state == MetaBlockEnd:
if meta_block_header_is_last:
state = StreamEnd
else:
state = HeaderMetaBlockBegin
elif state == StreamEnd:
if read_u8_from_byte_tail() != 0:
error() # NonZeroTrailerBit
if read_u8() == NONE: # i.e. BitReaderError
state = StreamBegin
tmbuf = output_buf
output_buf = []
input_buf = []
return bytes(tmbuf)
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input', nargs='?', type=argparse.FileType('rb'), default=sys.stdin.buffer, help='input file')
parser.add_argument('--append', type=argparse.FileType('rb'), dest='addseg', default=[], metavar='FILE', action='append', help='additional input files')
parser.add_argument('--compare', type=argparse.FileType('rb'), dest='compare', default=None, metavar='EXPECTEDFILE', help='compare output and run ipdb for mismatch')
parser.add_argument('output', nargs='*', type=argparse.FileType('wb'), default=[sys.stdout.buffer], help='output file')
args = parser.parse_args()
cmpbuf = args.compare.read() if args.compare else None
outb = brotlidec(args.input.read(), [], cmpbuf=cmpbuf)
args.output[0].write(bytes(outb))
for additional_segment in args.addseg:
if len(args.output) > 1:
args.output.pop(0)
outb = brotlidec(additional_segment.read(), [])
args.output[0].write(bytes(outb))
if __name__ == '__main__':
main()