123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- package brotli
- import "io"
- /* Copyright 2015 Google Inc. All Rights Reserved.
- Distributed under MIT license.
- See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
- */
- /* Brotli state for partial streaming decoding. */
- const (
- stateUninited = iota
- stateLargeWindowBits
- stateInitialize
- stateMetablockBegin
- stateMetablockHeader
- stateMetablockHeader2
- stateContextModes
- stateCommandBegin
- stateCommandInner
- stateCommandPostDecodeLiterals
- stateCommandPostWrapCopy
- stateUncompressed
- stateMetadata
- stateCommandInnerWrite
- stateMetablockDone
- stateCommandPostWrite1
- stateCommandPostWrite2
- stateHuffmanCode0
- stateHuffmanCode1
- stateHuffmanCode2
- stateHuffmanCode3
- stateContextMap1
- stateContextMap2
- stateTreeGroup
- stateDone
- )
- const (
- stateMetablockHeaderNone = iota
- stateMetablockHeaderEmpty
- stateMetablockHeaderNibbles
- stateMetablockHeaderSize
- stateMetablockHeaderUncompressed
- stateMetablockHeaderReserved
- stateMetablockHeaderBytes
- stateMetablockHeaderMetadata
- )
- const (
- stateUncompressedNone = iota
- stateUncompressedWrite
- )
- const (
- stateTreeGroupNone = iota
- stateTreeGroupLoop
- )
- const (
- stateContextMapNone = iota
- stateContextMapReadPrefix
- stateContextMapHuffman
- stateContextMapDecode
- stateContextMapTransform
- )
- const (
- stateHuffmanNone = iota
- stateHuffmanSimpleSize
- stateHuffmanSimpleRead
- stateHuffmanSimpleBuild
- stateHuffmanComplex
- stateHuffmanLengthSymbols
- )
- const (
- stateDecodeUint8None = iota
- stateDecodeUint8Short
- stateDecodeUint8Long
- )
- const (
- stateReadBlockLengthNone = iota
- stateReadBlockLengthSuffix
- )
- type Reader struct {
- src io.Reader
- buf []byte // scratch space for reading from src
- in []byte // current chunk to decode; usually aliases buf
- state int
- loop_counter int
- br bitReader
- buffer struct {
- u64 uint64
- u8 [8]byte
- }
- buffer_length uint32
- pos int
- max_backward_distance int
- max_distance int
- ringbuffer_size int
- ringbuffer_mask int
- dist_rb_idx int
- dist_rb [4]int
- error_code int
- sub_loop_counter uint32
- ringbuffer []byte
- ringbuffer_end []byte
- htree_command []huffmanCode
- context_lookup []byte
- context_map_slice []byte
- dist_context_map_slice []byte
- literal_hgroup huffmanTreeGroup
- insert_copy_hgroup huffmanTreeGroup
- distance_hgroup huffmanTreeGroup
- block_type_trees []huffmanCode
- block_len_trees []huffmanCode
- trivial_literal_context int
- distance_context int
- meta_block_remaining_len int
- block_length_index uint32
- block_length [3]uint32
- num_block_types [3]uint32
- block_type_rb [6]uint32
- distance_postfix_bits uint32
- num_direct_distance_codes uint32
- distance_postfix_mask int
- num_dist_htrees uint32
- dist_context_map []byte
- literal_htree []huffmanCode
- dist_htree_index byte
- repeat_code_len uint32
- prev_code_len uint32
- copy_length int
- distance_code int
- rb_roundtrips uint
- partial_pos_out uint
- symbol uint32
- repeat uint32
- space uint32
- table [32]huffmanCode
- symbol_lists symbolList
- symbols_lists_array [huffmanMaxCodeLength + 1 + numCommandSymbols]uint16
- next_symbol [32]int
- code_length_code_lengths [codeLengthCodes]byte
- code_length_histo [16]uint16
- htree_index int
- next []huffmanCode
- context_index uint32
- max_run_length_prefix uint32
- code uint32
- context_map_table [huffmanMaxSize272]huffmanCode
- substate_metablock_header int
- substate_tree_group int
- substate_context_map int
- substate_uncompressed int
- substate_huffman int
- substate_decode_uint8 int
- substate_read_block_length int
- is_last_metablock uint
- is_uncompressed uint
- is_metadata uint
- should_wrap_ringbuffer uint
- canny_ringbuffer_allocation uint
- large_window bool
- size_nibbles uint
- window_bits uint32
- new_ringbuffer_size int
- num_literal_htrees uint32
- context_map []byte
- context_modes []byte
- dictionary *dictionary
- transforms *transforms
- trivial_literal_contexts [8]uint32
- }
- func decoderStateInit(s *Reader) bool {
- s.error_code = 0 /* BROTLI_DECODER_NO_ERROR */
- initBitReader(&s.br)
- s.state = stateUninited
- s.large_window = false
- s.substate_metablock_header = stateMetablockHeaderNone
- s.substate_tree_group = stateTreeGroupNone
- s.substate_context_map = stateContextMapNone
- s.substate_uncompressed = stateUncompressedNone
- s.substate_huffman = stateHuffmanNone
- s.substate_decode_uint8 = stateDecodeUint8None
- s.substate_read_block_length = stateReadBlockLengthNone
- s.buffer_length = 0
- s.loop_counter = 0
- s.pos = 0
- s.rb_roundtrips = 0
- s.partial_pos_out = 0
- s.block_type_trees = nil
- s.block_len_trees = nil
- s.ringbuffer_size = 0
- s.new_ringbuffer_size = 0
- s.ringbuffer_mask = 0
- s.context_map = nil
- s.context_modes = nil
- s.dist_context_map = nil
- s.context_map_slice = nil
- s.dist_context_map_slice = nil
- s.sub_loop_counter = 0
- s.literal_hgroup.codes = nil
- s.literal_hgroup.htrees = nil
- s.insert_copy_hgroup.codes = nil
- s.insert_copy_hgroup.htrees = nil
- s.distance_hgroup.codes = nil
- s.distance_hgroup.htrees = nil
- s.is_last_metablock = 0
- s.is_uncompressed = 0
- s.is_metadata = 0
- s.should_wrap_ringbuffer = 0
- s.canny_ringbuffer_allocation = 1
- s.window_bits = 0
- s.max_distance = 0
- s.dist_rb[0] = 16
- s.dist_rb[1] = 15
- s.dist_rb[2] = 11
- s.dist_rb[3] = 4
- s.dist_rb_idx = 0
- s.block_type_trees = nil
- s.block_len_trees = nil
- s.symbol_lists.storage = s.symbols_lists_array[:]
- s.symbol_lists.offset = huffmanMaxCodeLength + 1
- s.dictionary = getDictionary()
- s.transforms = getTransforms()
- return true
- }
- func decoderStateMetablockBegin(s *Reader) {
- s.meta_block_remaining_len = 0
- s.block_length[0] = 1 << 24
- s.block_length[1] = 1 << 24
- s.block_length[2] = 1 << 24
- s.num_block_types[0] = 1
- s.num_block_types[1] = 1
- s.num_block_types[2] = 1
- s.block_type_rb[0] = 1
- s.block_type_rb[1] = 0
- s.block_type_rb[2] = 1
- s.block_type_rb[3] = 0
- s.block_type_rb[4] = 1
- s.block_type_rb[5] = 0
- s.context_map = nil
- s.context_modes = nil
- s.dist_context_map = nil
- s.context_map_slice = nil
- s.literal_htree = nil
- s.dist_context_map_slice = nil
- s.dist_htree_index = 0
- s.context_lookup = nil
- s.literal_hgroup.codes = nil
- s.literal_hgroup.htrees = nil
- s.insert_copy_hgroup.codes = nil
- s.insert_copy_hgroup.htrees = nil
- s.distance_hgroup.codes = nil
- s.distance_hgroup.htrees = nil
- }
- func decoderStateCleanupAfterMetablock(s *Reader) {
- s.context_modes = nil
- s.context_map = nil
- s.dist_context_map = nil
- s.literal_hgroup.htrees = nil
- s.insert_copy_hgroup.htrees = nil
- s.distance_hgroup.htrees = nil
- }
- func decoderHuffmanTreeGroupInit(s *Reader, group *huffmanTreeGroup, alphabet_size uint32, max_symbol uint32, ntrees uint32) bool {
- var max_table_size uint = uint(kMaxHuffmanTableSize[(alphabet_size+31)>>5])
- group.alphabet_size = uint16(alphabet_size)
- group.max_symbol = uint16(max_symbol)
- group.num_htrees = uint16(ntrees)
- group.htrees = make([][]huffmanCode, ntrees)
- group.codes = make([]huffmanCode, (uint(ntrees) * max_table_size))
- return !(group.codes == nil)
- }
|