aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/andybalholm/brotli/state.go
blob: d03348fe8070c5a9d927333332b3d7bff93df214 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
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 = 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)
}