func readCodeLengthCodeLengths(s *Reader) int {
	var br *bitReader = &s.br
	var num_codes uint32 = s.repeat
	var space uint32 = s.space
	var i uint32 = s.sub_loop_counter
	for ; i < codeLengthCodes; i++ {
		var code_len_idx byte = kCodeLengthCodeOrder[i]
		var ix uint32
		var v uint32
		if !safeGetBits(br, 4, &ix) {
			var available_bits uint32 = getAvailableBits(br)
			if available_bits != 0 {
				ix = uint32(getBitsUnmasked(br) & 0xF)
			} else {
				ix = 0
			}
			if uint32(kCodeLengthPrefixLength[ix]) > available_bits {
				s.sub_loop_counter = i
				s.repeat = num_codes
				s.space = space
				s.substate_huffman = stateHuffmanComplex
				return decoderNeedsMoreInput
			}
		}
		v = uint32(kCodeLengthPrefixValue[ix])
		dropBits(br, uint32(kCodeLengthPrefixLength[ix]))
		s.code_length_code_lengths[code_len_idx] = byte(v)
		if v != 0 {
			space = space - (32 >> v)
			num_codes++
			s.code_length_histo[v]++
			if space-1 >= 32 {
				break
			}
		}
	}
	if num_codes != 1 && space != 0 {
		return decoderErrorFormatClSpace
	}
	return decoderSuccess
}
/* Reads and decodes 15..18 codes using static prefix code.
Each code is 2..4 bits long. In total 30..72 bits are used.
package brotli
const (
	decoderResultError           = 0
	decoderResultSuccess         = 1
	decoderResultNeedsMoreInput  = 2
	decoderResultNeedsMoreOutput = 3
)
const (
	decoderNoError                          = 0
	decoderSuccess                          = 1
	decoderNeedsMoreInput                   = 2
	decoderNeedsMoreOutput                  = 3
	decoderErrorFormatExuberantNibble       = -1
	decoderErrorFormatReserved              = -2
	decoderErrorFormatExuberantMetaNibble   = -3
	decoderErrorFormatSimpleHuffmanAlphabet = -4
	decoderErrorFormatSimpleHuffmanSame     = -5
	decoderErrorFormatClSpace               = -6
	decoderErrorFormatHuffmanSpace          = -7
	decoderErrorFormatContextMapRepeat      = -8
	decoderErrorFormatBlockLength1          = -9
	decoderErrorFormatBlockLength2          = -10
	decoderErrorFormatTransform             = -11
	decoderErrorFormatDictionary            = -12
	decoderErrorFormatWindowBits            = -13
	decoderErrorFormatPadding1              = -14
	decoderErrorFormatPadding2              = -15
	decoderErrorFormatDistance              = -16
	decoderErrorDictionaryNotSet            = -19
	decoderErrorInvalidArguments            = -20
	decoderErrorAllocContextModes           = -21
	decoderErrorAllocTreeGroups             = -22
	decoderErrorAllocContextMap             = -25
	decoderErrorAllocRingBuffer1            = -26
	decoderErrorAllocRingBuffer2            = -27
	decoderErrorAllocBlockTypeTrees         = -30
	decoderErrorUnreachable                 = -31
)
const lastErrorCode = decoderErrorUnreachable
const (
	decoderParamDisableRingBufferReallocation = 0
	decoderParamLargeWindow                   = 1
)
const huffmanTableBits = 8
const huffmanTableMask = 0xFF
const kRingBufferWriteAheadSlack uint32 = 42
var kCodeLengthCodeOrder = [codeLengthCodes]byte{1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15}
var kCodeLengthPrefixLength = [16]byte{2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4}
var kCodeLengthPrefixValue = [16]byte{0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5}
func decoderSetParameter(state *Reader, p int, value uint32) bool {
	if state.state != stateUninited {
		return false
	}
	switch p {
	case decoderParamDisableRingBufferReallocation:
		if !(value == 0) {
			state.canny_ringbuffer_allocation = 0
		} else {
			state.canny_ringbuffer_allocation = 1
		}
		return true
	case decoderParamLargeWindow:
		state.large_window = (!(value == 0))
		return true
	default:
		return false
	}
}
func saveErrorCode(s *Reader, e int) int {
	s.error_code = int(e)
	switch e {
	case decoderSuccess:
		return decoderResultSuccess
	case decoderNeedsMoreInput:
		return decoderResultNeedsMoreInput
	case decoderNeedsMoreOutput:
		return decoderResultNeedsMoreOutput
	default:
		return decoderResultError
	}
}
func decodeWindowBits(s *Reader, br *bitReader) int {
	var n uint32
	var large_window bool = s.large_window
	s.large_window = false
	takeBits(br, 1, &n)
	if n == 0 {
		s.window_bits = 16
		return decoderSuccess
	}
	takeBits(br, 3, &n)
	if n != 0 {
		s.window_bits = 17 + n
		return decoderSuccess
	}
	takeBits(br, 3, &n)
	if n == 1 {
		if large_window {
			takeBits(br, 1, &n)
			if n == 1 {
				return decoderErrorFormatWindowBits
			}
			s.large_window = true
			return decoderSuccess
		} else {
			return decoderErrorFormatWindowBits
		}
	}
	if n != 0 {
		s.window_bits = 8 + n
		return decoderSuccess
	}
	s.window_bits = 17
	return decoderSuccess
}
func decodeVarLenUint8(s *Reader, br *bitReader, value *uint32) int {
	var bits uint32
	switch s.substate_decode_uint8 {
	case stateDecodeUint8None:
		if !safeReadBits(br, 1, &bits) {
			return decoderNeedsMoreInput
		}
		if bits == 0 {
			*value = 0
			return decoderSuccess
		}
		fallthrough
	case stateDecodeUint8Short:
		if !safeReadBits(br, 3, &bits) {
			s.substate_decode_uint8 = stateDecodeUint8Short
			return decoderNeedsMoreInput
		}
		if bits == 0 {
			*value = 1
			s.substate_decode_uint8 = stateDecodeUint8None
			return decoderSuccess
		}
		*value = bits
		fallthrough
	case stateDecodeUint8Long:
		if !safeReadBits(br, *value, &bits) {
			s.substate_decode_uint8 = stateDecodeUint8Long
			return decoderNeedsMoreInput
		}
		*value = (1 << *value) + bits
		s.substate_decode_uint8 = stateDecodeUint8None
		return decoderSuccess
	default:
		return decoderErrorUnreachable
	}
}
func decodeMetaBlockLength(s *Reader, br *bitReader) int {
	var bits uint32
	var i int
	for {
		switch s.substate_metablock_header {
		case stateMetablockHeaderNone:
			if !safeReadBits(br, 1, &bits) {
				return decoderNeedsMoreInput
			}
			if bits != 0 {
				s.is_last_metablock = 1
			} else {
				s.is_last_metablock = 0
			}
			s.meta_block_remaining_len = 0
			s.is_uncompressed = 0
			s.is_metadata = 0
			if s.is_last_metablock == 0 {
				s.substate_metablock_header = stateMetablockHeaderNibbles
				break
			}
			s.substate_metablock_header = stateMetablockHeaderEmpty
			fallthrough
		case stateMetablockHeaderEmpty:
			if !safeReadBits(br, 1, &bits) {
				return decoderNeedsMoreInput
			}
			if bits != 0 {
				s.substate_metablock_header = stateMetablockHeaderNone
				return decoderSuccess
			}
			s.substate_metablock_header = stateMetablockHeaderNibbles
			fallthrough
		case stateMetablockHeaderNibbles:
			if !safeReadBits(br, 2, &bits) {
				return decoderNeedsMoreInput
			}
			s.size_nibbles = uint(byte(bits + 4))
			s.loop_counter = 0
			if bits == 3 {
				s.is_metadata = 1
				s.substate_metablock_header = stateMetablockHeaderReserved
				break
			}
			s.substate_metablock_header = stateMetablockHeaderSize
			fallthrough
		case stateMetablockHeaderSize:
			i = s.loop_counter
			for ; i < int(s.size_nibbles); i++ {
				if !safeReadBits(br, 4, &bits) {
					s.loop_counter = i
					return decoderNeedsMoreInput
				}
				if uint(i+1) == s.size_nibbles && s.size_nibbles > 4 && bits == 0 {
					return decoderErrorFormatExuberantNibble
				}
				s.meta_block_remaining_len |= int(bits << uint(i*4))
			}
			s.substate_metablock_header = stateMetablockHeaderUncompressed
			fallthrough
		case stateMetablockHeaderUncompressed:
			if s.is_last_metablock == 0 {
				if !safeReadBits(br, 1, &bits) {
					return decoderNeedsMoreInput
				}
				if bits != 0 {
					s.is_uncompressed = 1
				} else {
					s.is_uncompressed = 0
				}
			}
			s.meta_block_remaining_len++
			s.substate_metablock_header = stateMetablockHeaderNone
			return decoderSuccess
		case stateMetablockHeaderReserved:
			if !safeReadBits(br, 1, &bits) {
				return decoderNeedsMoreInput
			}
			if bits != 0 {
				return decoderErrorFormatReserved
			}
			s.substate_metablock_header = stateMetablockHeaderBytes
			fallthrough
		case stateMetablockHeaderBytes:
			if !safeReadBits(br, 2, &bits) {
				return decoderNeedsMoreInput
			}
			if bits == 0 {
				s.substate_metablock_header = stateMetablockHeaderNone
				return decoderSuccess
			}
			s.size_nibbles = uint(byte(bits))
			s.substate_metablock_header = stateMetablockHeaderMetadata
			fallthrough
		case stateMetablockHeaderMetadata:
			i = s.loop_counter
			for ; i < int(s.size_nibbles); i++ {
				if !safeReadBits(br, 8, &bits) {
					s.loop_counter = i
					return decoderNeedsMoreInput
				}
				if uint(i+1) == s.size_nibbles && s.size_nibbles > 1 && bits == 0 {
					return decoderErrorFormatExuberantMetaNibble
				}
				s.meta_block_remaining_len |= int(bits << uint(i*8))
			}
			s.meta_block_remaining_len++
			s.substate_metablock_header = stateMetablockHeaderNone
			return decoderSuccess
		default:
			return decoderErrorUnreachable
		}
	}
}
func decodeSymbol(bits uint32, table []huffmanCode, br *bitReader) uint32 {
	table = table[bits&huffmanTableMask:]
	if table[0].bits > huffmanTableBits {
		var nbits uint32 = uint32(table[0].bits) - huffmanTableBits
		dropBits(br, huffmanTableBits)
		table = table[uint32(table[0].value)+((bits>>huffmanTableBits)&bitMask(nbits)):]
	}
	dropBits(br, uint32(table[0].bits))
	return uint32(table[0].value)
}
func readSymbol(table []huffmanCode, br *bitReader) uint32 {
	return decodeSymbol(get16BitsUnmasked(br), table, br)
}
func safeDecodeSymbol(table []huffmanCode, br *bitReader, result *uint32) bool {
	var val uint32
	var available_bits uint32 = getAvailableBits(br)
	if available_bits == 0 {
		if table[0].bits == 0 {
			*result = uint32(table[0].value)
			return true
		}
		return false  
	}
	val = uint32(getBitsUnmasked(br))
	table = table[val&huffmanTableMask:]
	if table[0].bits <= huffmanTableBits {
		if uint32(table[0].bits) <= available_bits {
			dropBits(br, uint32(table[0].bits))
			*result = uint32(table[0].value)
			return true
		} else {
			return false  
		}
	}
	if available_bits <= huffmanTableBits {
		return false  
	}
	val = (val & bitMask(uint32(table[0].bits))) >> huffmanTableBits
	available_bits -= huffmanTableBits
	table = table[uint32(table[0].value)+val:]
	if available_bits < uint32(table[0].bits) {
		return false  
	}
	dropBits(br, huffmanTableBits+uint32(table[0].bits))
	*result = uint32(table[0].value)
	return true
}
func safeReadSymbol(table []huffmanCode, br *bitReader, result *uint32) bool {
	var val uint32
	if safeGetBits(br, 15, &val) {
		*result = decodeSymbol(val, table, br)
		return true
	}
	return safeDecodeSymbol(table, br, result)
}
func preloadSymbol(safe int, table []huffmanCode, br *bitReader, bits *uint32, value *uint32) {
	if safe != 0 {
		return
	}
	table = table[getBits(br, huffmanTableBits):]
	*bits = uint32(table[0].bits)
	*value = uint32(table[0].value)
}
func readPreloadedSymbol(table []huffmanCode, br *bitReader, bits *uint32, value *uint32) uint32 {
	var result uint32 = *value
	var ext []huffmanCode
	if *bits > huffmanTableBits {
		var val uint32 = get16BitsUnmasked(br)
		ext = table[val&huffmanTableMask:][*value:]
		var mask uint32 = bitMask((*bits - huffmanTableBits))
		dropBits(br, huffmanTableBits)
		ext = ext[(val>>huffmanTableBits)&mask:]
		dropBits(br, uint32(ext[0].bits))
		result = uint32(ext[0].value)
	} else {
		dropBits(br, *bits)
	}
	preloadSymbol(0, table, br, bits, value)
	return result
}
func log2Floor(x uint32) uint32 {
	var result uint32 = 0
	for x != 0 {
		x >>= 1
		result++
	}
	return result
}
func readSimpleHuffmanSymbols(alphabet_size uint32, max_symbol uint32, s *Reader) int {
	var br *bitReader = &s.br
	var max_bits uint32 = log2Floor(alphabet_size - 1)
	var i uint32 = s.sub_loop_counter
	var num_symbols uint32 = s.symbol
	for i <= num_symbols {
		var v uint32
		if !safeReadBits(br, max_bits, &v) {
			s.sub_loop_counter = i
			s.substate_huffman = stateHuffmanSimpleRead
			return decoderNeedsMoreInput
		}
		if v >= max_symbol {
			return decoderErrorFormatSimpleHuffmanAlphabet
		}
		s.symbols_lists_array[i] = uint16(v)
		i++
	}
	for i = 0; i < num_symbols; i++ {
		var k uint32 = i + 1
		for ; k <= num_symbols; k++ {
			if s.symbols_lists_array[i] == s.symbols_lists_array[k] {
				return decoderErrorFormatSimpleHuffmanSame
			}
		}
	}
	return decoderSuccess
}
func processSingleCodeLength(code_len uint32, symbol *uint32, repeat *uint32, space *uint32, prev_code_len *uint32, symbol_lists symbolList, code_length_histo []uint16, next_symbol []int) {
	*repeat = 0
	if code_len != 0 {  
		symbolListPut(symbol_lists, next_symbol[code_len], uint16(*symbol))
		next_symbol[code_len] = int(*symbol)
		*prev_code_len = code_len
		*space -= 32768 >> code_len
		code_length_histo[code_len]++
	}
	(*symbol)++
}
func processRepeatedCodeLength(code_len uint32, repeat_delta uint32, alphabet_size uint32, symbol *uint32, repeat *uint32, space *uint32, prev_code_len *uint32, repeat_code_len *uint32, symbol_lists symbolList, code_length_histo []uint16, next_symbol []int) {
	var old_repeat uint32    
	var extra_bits uint32 = 3
	var new_len uint32 = 0
	if code_len == repeatPreviousCodeLength {
		new_len = *prev_code_len
		extra_bits = 2
	}
	if *repeat_code_len != new_len {
		*repeat = 0
		*repeat_code_len = new_len
	}
	old_repeat = *repeat
	if *repeat > 0 {
		*repeat -= 2
		*repeat <<= extra_bits
	}
	*repeat += repeat_delta + 3
	repeat_delta = *repeat - old_repeat
	if *symbol+repeat_delta > alphabet_size {
		*symbol = alphabet_size
		*space = 0xFFFFF
		return
	}
	if *repeat_code_len != 0 {
		var last uint = uint(*symbol + repeat_delta)
		var next int = next_symbol[*repeat_code_len]
		for {
			symbolListPut(symbol_lists, next, uint16(*symbol))
			next = int(*symbol)
			(*symbol)++
			if (*symbol) == uint32(last) {
				break
			}
		}
		next_symbol[*repeat_code_len] = next
		*space -= repeat_delta << (15 - *repeat_code_len)
		code_length_histo[*repeat_code_len] = uint16(uint32(code_length_histo[*repeat_code_len]) + repeat_delta)
	} else {
		*symbol += repeat_delta
	}
}
func readSymbolCodeLengths(alphabet_size uint32, s *Reader) int {
	var br *bitReader = &s.br
	var symbol uint32 = s.symbol
	var repeat uint32 = s.repeat
	var space uint32 = s.space
	var prev_code_len uint32 = s.prev_code_len
	var repeat_code_len uint32 = s.repeat_code_len
	var symbol_lists symbolList = s.symbol_lists
	var code_length_histo []uint16 = s.code_length_histo[:]
	var next_symbol []int = s.next_symbol[:]
	if !warmupBitReader(br) {
		return decoderNeedsMoreInput
	}
	var p []huffmanCode
	for symbol < alphabet_size && space > 0 {
		p = s.table[:]
		var code_len uint32
		if !checkInputAmount(br, shortFillBitWindowRead) {
			s.symbol = symbol
			s.repeat = repeat
			s.prev_code_len = prev_code_len
			s.repeat_code_len = repeat_code_len
			s.space = space
			return decoderNeedsMoreInput
		}
		fillBitWindow16(br)
		p = p[getBitsUnmasked(br)&uint64(bitMask(huffmanMaxCodeLengthCodeLength)):]
		dropBits(br, uint32(p[0].bits))  
		code_len = uint32(p[0].value)    
		if code_len < repeatPreviousCodeLength {
			processSingleCodeLength(code_len, &symbol, &repeat, &space, &prev_code_len, symbol_lists, code_length_histo, next_symbol)  
		} else {
			var extra_bits uint32
			if code_len == repeatPreviousCodeLength {
				extra_bits = 2
			} else {
				extra_bits = 3
			}
			var repeat_delta uint32 = uint32(getBitsUnmasked(br)) & bitMask(extra_bits)
			dropBits(br, extra_bits)
			processRepeatedCodeLength(code_len, repeat_delta, alphabet_size, &symbol, &repeat, &space, &prev_code_len, &repeat_code_len, symbol_lists, code_length_histo, next_symbol)
		}
	}
	s.space = space
	return decoderSuccess
}
func safeReadSymbolCodeLengths(alphabet_size uint32, s *Reader) int {
	var br *bitReader = &s.br
	var get_byte bool = false
	var p []huffmanCode
	for s.symbol < alphabet_size && s.space > 0 {
		p = s.table[:]
		var code_len uint32
		var available_bits uint32
		var bits uint32 = 0
		if get_byte && !pullByte(br) {
			return decoderNeedsMoreInput
		}
		get_byte = false
		available_bits = getAvailableBits(br)
		if available_bits != 0 {
			bits = uint32(getBitsUnmasked(br))
		}
		p = p[bits&bitMask(huffmanMaxCodeLengthCodeLength):]
		if uint32(p[0].bits) > available_bits {
			get_byte = true
			continue
		}
		code_len = uint32(p[0].value)  
		if code_len < repeatPreviousCodeLength {
			dropBits(br, uint32(p[0].bits))
			processSingleCodeLength(code_len, &s.symbol, &s.repeat, &s.space, &s.prev_code_len, s.symbol_lists, s.code_length_histo[:], s.next_symbol[:])  
		} else {
			var extra_bits uint32 = code_len - 14
			var repeat_delta uint32 = (bits >> p[0].bits) & bitMask(extra_bits)
			if available_bits < uint32(p[0].bits)+extra_bits {
				get_byte = true
				continue
			}
			dropBits(br, uint32(p[0].bits)+extra_bits)
			processRepeatedCodeLength(code_len, repeat_delta, alphabet_size, &s.symbol, &s.repeat, &s.space, &s.prev_code_len, &s.repeat_code_len, s.symbol_lists, s.code_length_histo[:], s.next_symbol[:])
		}
	}
	return decoderSuccess
}