[145] | 1 | package brotli
|
---|
| 2 |
|
---|
| 3 | import "io"
|
---|
| 4 |
|
---|
| 5 | /* Copyright 2015 Google Inc. All Rights Reserved.
|
---|
| 6 |
|
---|
| 7 | Distributed under MIT license.
|
---|
| 8 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
---|
| 9 | */
|
---|
| 10 |
|
---|
| 11 | /* Brotli state for partial streaming decoding. */
|
---|
| 12 | const (
|
---|
| 13 | stateUninited = iota
|
---|
| 14 | stateLargeWindowBits
|
---|
| 15 | stateInitialize
|
---|
| 16 | stateMetablockBegin
|
---|
| 17 | stateMetablockHeader
|
---|
| 18 | stateMetablockHeader2
|
---|
| 19 | stateContextModes
|
---|
| 20 | stateCommandBegin
|
---|
| 21 | stateCommandInner
|
---|
| 22 | stateCommandPostDecodeLiterals
|
---|
| 23 | stateCommandPostWrapCopy
|
---|
| 24 | stateUncompressed
|
---|
| 25 | stateMetadata
|
---|
| 26 | stateCommandInnerWrite
|
---|
| 27 | stateMetablockDone
|
---|
| 28 | stateCommandPostWrite1
|
---|
| 29 | stateCommandPostWrite2
|
---|
| 30 | stateHuffmanCode0
|
---|
| 31 | stateHuffmanCode1
|
---|
| 32 | stateHuffmanCode2
|
---|
| 33 | stateHuffmanCode3
|
---|
| 34 | stateContextMap1
|
---|
| 35 | stateContextMap2
|
---|
| 36 | stateTreeGroup
|
---|
| 37 | stateDone
|
---|
| 38 | )
|
---|
| 39 |
|
---|
| 40 | const (
|
---|
| 41 | stateMetablockHeaderNone = iota
|
---|
| 42 | stateMetablockHeaderEmpty
|
---|
| 43 | stateMetablockHeaderNibbles
|
---|
| 44 | stateMetablockHeaderSize
|
---|
| 45 | stateMetablockHeaderUncompressed
|
---|
| 46 | stateMetablockHeaderReserved
|
---|
| 47 | stateMetablockHeaderBytes
|
---|
| 48 | stateMetablockHeaderMetadata
|
---|
| 49 | )
|
---|
| 50 |
|
---|
| 51 | const (
|
---|
| 52 | stateUncompressedNone = iota
|
---|
| 53 | stateUncompressedWrite
|
---|
| 54 | )
|
---|
| 55 |
|
---|
| 56 | const (
|
---|
| 57 | stateTreeGroupNone = iota
|
---|
| 58 | stateTreeGroupLoop
|
---|
| 59 | )
|
---|
| 60 |
|
---|
| 61 | const (
|
---|
| 62 | stateContextMapNone = iota
|
---|
| 63 | stateContextMapReadPrefix
|
---|
| 64 | stateContextMapHuffman
|
---|
| 65 | stateContextMapDecode
|
---|
| 66 | stateContextMapTransform
|
---|
| 67 | )
|
---|
| 68 |
|
---|
| 69 | const (
|
---|
| 70 | stateHuffmanNone = iota
|
---|
| 71 | stateHuffmanSimpleSize
|
---|
| 72 | stateHuffmanSimpleRead
|
---|
| 73 | stateHuffmanSimpleBuild
|
---|
| 74 | stateHuffmanComplex
|
---|
| 75 | stateHuffmanLengthSymbols
|
---|
| 76 | )
|
---|
| 77 |
|
---|
| 78 | const (
|
---|
| 79 | stateDecodeUint8None = iota
|
---|
| 80 | stateDecodeUint8Short
|
---|
| 81 | stateDecodeUint8Long
|
---|
| 82 | )
|
---|
| 83 |
|
---|
| 84 | const (
|
---|
| 85 | stateReadBlockLengthNone = iota
|
---|
| 86 | stateReadBlockLengthSuffix
|
---|
| 87 | )
|
---|
| 88 |
|
---|
| 89 | type Reader struct {
|
---|
| 90 | src io.Reader
|
---|
| 91 | buf []byte // scratch space for reading from src
|
---|
| 92 | in []byte // current chunk to decode; usually aliases buf
|
---|
| 93 |
|
---|
| 94 | state int
|
---|
| 95 | loop_counter int
|
---|
| 96 | br bitReader
|
---|
| 97 | buffer struct {
|
---|
| 98 | u64 uint64
|
---|
| 99 | u8 [8]byte
|
---|
| 100 | }
|
---|
| 101 | buffer_length uint32
|
---|
| 102 | pos int
|
---|
| 103 | max_backward_distance int
|
---|
| 104 | max_distance int
|
---|
| 105 | ringbuffer_size int
|
---|
| 106 | ringbuffer_mask int
|
---|
| 107 | dist_rb_idx int
|
---|
| 108 | dist_rb [4]int
|
---|
| 109 | error_code int
|
---|
| 110 | sub_loop_counter uint32
|
---|
| 111 | ringbuffer []byte
|
---|
| 112 | ringbuffer_end []byte
|
---|
| 113 | htree_command []huffmanCode
|
---|
| 114 | context_lookup []byte
|
---|
| 115 | context_map_slice []byte
|
---|
| 116 | dist_context_map_slice []byte
|
---|
| 117 | literal_hgroup huffmanTreeGroup
|
---|
| 118 | insert_copy_hgroup huffmanTreeGroup
|
---|
| 119 | distance_hgroup huffmanTreeGroup
|
---|
| 120 | block_type_trees []huffmanCode
|
---|
| 121 | block_len_trees []huffmanCode
|
---|
| 122 | trivial_literal_context int
|
---|
| 123 | distance_context int
|
---|
| 124 | meta_block_remaining_len int
|
---|
| 125 | block_length_index uint32
|
---|
| 126 | block_length [3]uint32
|
---|
| 127 | num_block_types [3]uint32
|
---|
| 128 | block_type_rb [6]uint32
|
---|
| 129 | distance_postfix_bits uint32
|
---|
| 130 | num_direct_distance_codes uint32
|
---|
| 131 | distance_postfix_mask int
|
---|
| 132 | num_dist_htrees uint32
|
---|
| 133 | dist_context_map []byte
|
---|
| 134 | literal_htree []huffmanCode
|
---|
| 135 | dist_htree_index byte
|
---|
| 136 | repeat_code_len uint32
|
---|
| 137 | prev_code_len uint32
|
---|
| 138 | copy_length int
|
---|
| 139 | distance_code int
|
---|
| 140 | rb_roundtrips uint
|
---|
| 141 | partial_pos_out uint
|
---|
| 142 | symbol uint32
|
---|
| 143 | repeat uint32
|
---|
| 144 | space uint32
|
---|
| 145 | table [32]huffmanCode
|
---|
| 146 | symbol_lists symbolList
|
---|
| 147 | symbols_lists_array [huffmanMaxCodeLength + 1 + numCommandSymbols]uint16
|
---|
| 148 | next_symbol [32]int
|
---|
| 149 | code_length_code_lengths [codeLengthCodes]byte
|
---|
| 150 | code_length_histo [16]uint16
|
---|
| 151 | htree_index int
|
---|
| 152 | next []huffmanCode
|
---|
| 153 | context_index uint32
|
---|
| 154 | max_run_length_prefix uint32
|
---|
| 155 | code uint32
|
---|
| 156 | context_map_table [huffmanMaxSize272]huffmanCode
|
---|
| 157 | substate_metablock_header int
|
---|
| 158 | substate_tree_group int
|
---|
| 159 | substate_context_map int
|
---|
| 160 | substate_uncompressed int
|
---|
| 161 | substate_huffman int
|
---|
| 162 | substate_decode_uint8 int
|
---|
| 163 | substate_read_block_length int
|
---|
| 164 | is_last_metablock uint
|
---|
| 165 | is_uncompressed uint
|
---|
| 166 | is_metadata uint
|
---|
| 167 | should_wrap_ringbuffer uint
|
---|
| 168 | canny_ringbuffer_allocation uint
|
---|
| 169 | large_window bool
|
---|
| 170 | size_nibbles uint
|
---|
| 171 | window_bits uint32
|
---|
| 172 | new_ringbuffer_size int
|
---|
| 173 | num_literal_htrees uint32
|
---|
| 174 | context_map []byte
|
---|
| 175 | context_modes []byte
|
---|
| 176 | dictionary *dictionary
|
---|
| 177 | transforms *transforms
|
---|
| 178 | trivial_literal_contexts [8]uint32
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | func decoderStateInit(s *Reader) bool {
|
---|
| 182 | s.error_code = 0 /* BROTLI_DECODER_NO_ERROR */
|
---|
| 183 |
|
---|
| 184 | initBitReader(&s.br)
|
---|
| 185 | s.state = stateUninited
|
---|
| 186 | s.large_window = false
|
---|
| 187 | s.substate_metablock_header = stateMetablockHeaderNone
|
---|
| 188 | s.substate_tree_group = stateTreeGroupNone
|
---|
| 189 | s.substate_context_map = stateContextMapNone
|
---|
| 190 | s.substate_uncompressed = stateUncompressedNone
|
---|
| 191 | s.substate_huffman = stateHuffmanNone
|
---|
| 192 | s.substate_decode_uint8 = stateDecodeUint8None
|
---|
| 193 | s.substate_read_block_length = stateReadBlockLengthNone
|
---|
| 194 |
|
---|
| 195 | s.buffer_length = 0
|
---|
| 196 | s.loop_counter = 0
|
---|
| 197 | s.pos = 0
|
---|
| 198 | s.rb_roundtrips = 0
|
---|
| 199 | s.partial_pos_out = 0
|
---|
| 200 |
|
---|
| 201 | s.block_type_trees = nil
|
---|
| 202 | s.block_len_trees = nil
|
---|
| 203 | s.ringbuffer = nil
|
---|
| 204 | s.ringbuffer_size = 0
|
---|
| 205 | s.new_ringbuffer_size = 0
|
---|
| 206 | s.ringbuffer_mask = 0
|
---|
| 207 |
|
---|
| 208 | s.context_map = nil
|
---|
| 209 | s.context_modes = nil
|
---|
| 210 | s.dist_context_map = nil
|
---|
| 211 | s.context_map_slice = nil
|
---|
| 212 | s.dist_context_map_slice = nil
|
---|
| 213 |
|
---|
| 214 | s.sub_loop_counter = 0
|
---|
| 215 |
|
---|
| 216 | s.literal_hgroup.codes = nil
|
---|
| 217 | s.literal_hgroup.htrees = nil
|
---|
| 218 | s.insert_copy_hgroup.codes = nil
|
---|
| 219 | s.insert_copy_hgroup.htrees = nil
|
---|
| 220 | s.distance_hgroup.codes = nil
|
---|
| 221 | s.distance_hgroup.htrees = nil
|
---|
| 222 |
|
---|
| 223 | s.is_last_metablock = 0
|
---|
| 224 | s.is_uncompressed = 0
|
---|
| 225 | s.is_metadata = 0
|
---|
| 226 | s.should_wrap_ringbuffer = 0
|
---|
| 227 | s.canny_ringbuffer_allocation = 1
|
---|
| 228 |
|
---|
| 229 | s.window_bits = 0
|
---|
| 230 | s.max_distance = 0
|
---|
| 231 | s.dist_rb[0] = 16
|
---|
| 232 | s.dist_rb[1] = 15
|
---|
| 233 | s.dist_rb[2] = 11
|
---|
| 234 | s.dist_rb[3] = 4
|
---|
| 235 | s.dist_rb_idx = 0
|
---|
| 236 | s.block_type_trees = nil
|
---|
| 237 | s.block_len_trees = nil
|
---|
| 238 |
|
---|
| 239 | s.symbol_lists.storage = s.symbols_lists_array[:]
|
---|
| 240 | s.symbol_lists.offset = huffmanMaxCodeLength + 1
|
---|
| 241 |
|
---|
| 242 | s.dictionary = getDictionary()
|
---|
| 243 | s.transforms = getTransforms()
|
---|
| 244 |
|
---|
| 245 | return true
|
---|
| 246 | }
|
---|
| 247 |
|
---|
| 248 | func decoderStateMetablockBegin(s *Reader) {
|
---|
| 249 | s.meta_block_remaining_len = 0
|
---|
| 250 | s.block_length[0] = 1 << 24
|
---|
| 251 | s.block_length[1] = 1 << 24
|
---|
| 252 | s.block_length[2] = 1 << 24
|
---|
| 253 | s.num_block_types[0] = 1
|
---|
| 254 | s.num_block_types[1] = 1
|
---|
| 255 | s.num_block_types[2] = 1
|
---|
| 256 | s.block_type_rb[0] = 1
|
---|
| 257 | s.block_type_rb[1] = 0
|
---|
| 258 | s.block_type_rb[2] = 1
|
---|
| 259 | s.block_type_rb[3] = 0
|
---|
| 260 | s.block_type_rb[4] = 1
|
---|
| 261 | s.block_type_rb[5] = 0
|
---|
| 262 | s.context_map = nil
|
---|
| 263 | s.context_modes = nil
|
---|
| 264 | s.dist_context_map = nil
|
---|
| 265 | s.context_map_slice = nil
|
---|
| 266 | s.literal_htree = nil
|
---|
| 267 | s.dist_context_map_slice = nil
|
---|
| 268 | s.dist_htree_index = 0
|
---|
| 269 | s.context_lookup = nil
|
---|
| 270 | s.literal_hgroup.codes = nil
|
---|
| 271 | s.literal_hgroup.htrees = nil
|
---|
| 272 | s.insert_copy_hgroup.codes = nil
|
---|
| 273 | s.insert_copy_hgroup.htrees = nil
|
---|
| 274 | s.distance_hgroup.codes = nil
|
---|
| 275 | s.distance_hgroup.htrees = nil
|
---|
| 276 | }
|
---|
| 277 |
|
---|
| 278 | func decoderStateCleanupAfterMetablock(s *Reader) {
|
---|
| 279 | s.context_modes = nil
|
---|
| 280 | s.context_map = nil
|
---|
| 281 | s.dist_context_map = nil
|
---|
| 282 | s.literal_hgroup.htrees = nil
|
---|
| 283 | s.insert_copy_hgroup.htrees = nil
|
---|
| 284 | s.distance_hgroup.htrees = nil
|
---|
| 285 | }
|
---|
| 286 |
|
---|
| 287 | func decoderHuffmanTreeGroupInit(s *Reader, group *huffmanTreeGroup, alphabet_size uint32, max_symbol uint32, ntrees uint32) bool {
|
---|
| 288 | var max_table_size uint = uint(kMaxHuffmanTableSize[(alphabet_size+31)>>5])
|
---|
| 289 | group.alphabet_size = uint16(alphabet_size)
|
---|
| 290 | group.max_symbol = uint16(max_symbol)
|
---|
| 291 | group.num_htrees = uint16(ntrees)
|
---|
| 292 | group.htrees = make([][]huffmanCode, ntrees)
|
---|
| 293 | group.codes = make([]huffmanCode, (uint(ntrees) * max_table_size))
|
---|
| 294 | return !(group.codes == nil)
|
---|
| 295 | }
|
---|