1#![no_std]
2#![allow(non_snake_case)]
3#![allow(unused_parens)]
4#![allow(non_camel_case_types)]
5#![allow(non_snake_case)]
6#![allow(non_upper_case_globals)]
7
8#[macro_use]
12extern crate alloc_no_stdlib as alloc;
13pub use alloc::{Allocator, SliceWrapperMut, SliceWrapper, StackAllocator, AllocatedStackMemory};
14
15use core::mem;
16mod dictionary;
17#[macro_use]
18mod bit_reader;
19mod huffman;
20mod state;
21mod prefix;
22mod context;
23mod transform;
24mod test;
25use transform::{TransformDictionaryWord, kNumTransforms};
26use state::{BlockTypeAndLengthState,
27 BrotliRunningState, BrotliRunningContextMapState, BrotliRunningTreeGroupState,
28 BrotliRunningUncompressedState, BrotliRunningDecodeUint8State,
29 BrotliRunningMetablockHeaderState, BrotliRunningHuffmanState,
30 BrotliRunningReadBlockLengthState, kLiteralContextBits};
31use context:: {kContextLookup, kContextLookupOffsets};
32use ::dictionary::{
33 kBrotliDictionaryOffsetsByLength,
34 kBrotliDictionarySizeBitsByLength,
35 kBrotliMinDictionaryWordLength,
36 kBrotliMaxDictionaryWordLength,
37 kBrotliDictionary };
38pub use huffman::{HuffmanCode, HuffmanTreeGroup};
39pub enum BrotliResult {
40 ResultSuccess,
41 NeedsMoreInput,
42 NeedsMoreOutput,
43 ResultFailure,
44}
45
46const kDefaultCodeLength : u32 = 8;
47const kCodeLengthRepeatCode : u32 = 16;
48const kNumLiteralCodes : u16 = 256;
49const kNumInsertAndCopyCodes : u16 = 704;
50const kNumBlockLengthCodes : u32 = 26;
51const kDistanceContextBits : i32 = 2;
52const HUFFMAN_TABLE_BITS : u32 = 8;
53const HUFFMAN_TABLE_MASK : u32 = 0xff;
54const CODE_LENGTH_CODES : usize = 18;
55const kCodeLengthCodeOrder : [u8;CODE_LENGTH_CODES] = [
56 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
57];
58
59const kCodeLengthPrefixLength : [u8; 16] = [
61 2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4,
62];
63
64const kCodeLengthPrefixValue : [u8;16] = [
65 0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,
66];
67
68
69macro_rules! BROTLI_LOG_UINT (
70 ($num : expr) => {
71 xprintln!("{:?} = {:?}", stringify!($num), $num)
72 };
73);
74
75macro_rules! BROTLI_LOG (
76 ($str : expr, $num : expr) => {xprintln!("{:?} {:?}", $str, $num);};
77 ($str : expr, $num0 : expr, $num1 : expr) => {xprintln!("{:?} {:?} {:?}", $str, $num0, $num1);};
78 ($str : expr, $num0 : expr, $num1 : expr, $num2 : expr) => {xprintln!("{:?} {:?} {:?} {:?}", $str, $num0, $num1, $num2);};
79 ($str : expr, $num0 : expr, $num1 : expr, $num2 : expr, $num3 : expr) => {xprintln!("{:?} {:?} {:?} {:?} {:?}", $str, $num0, $num1, $num2, $num3);};
80);
81
82#[allow(non_snake_case)]
83fn BROTLI_FAILURE() -> BrotliResult {
84 return BrotliResult::ResultFailure;
85}
86macro_rules! BROTLI_LOG_ARRAY_INDEX (
87 ($array : expr, $index : expr) => {
88 xprintln!("{:?}[{:?}] = {:?}", stringify!($array), $index, $array[$index as usize])
89 };
90);
91
92
93const NUM_DISTANCE_SHORT_CODES : u32 = 16;
94
95pub use state::BrotliState;
101fn DecodeWindowBits(mut br : &mut bit_reader::BrotliBitReader) -> u32 {
109 let mut n : u32 = 0;
110 bit_reader::BrotliTakeBits(&mut br, 1, &mut n);
111 if (n == 0) {
112 return 16;
113 }
114 bit_reader::BrotliTakeBits(&mut br, 3, &mut n);
115 if (n != 0) {
116 return 17 + n;
117 }
118 bit_reader::BrotliTakeBits(&mut br, 3, &mut n);
119 if (n != 0) {
120 return 8 + n;
121 }
122 return 17;
123}
124
125#[cold]
126fn mark_unlikely() {
127}
128
129fn DecodeVarLenUint8(substate_decode_uint8 : &mut state::BrotliRunningDecodeUint8State,
130 mut br : &mut bit_reader::BrotliBitReader,
131 mut value : &mut u32,
132 input : &[u8]) -> BrotliResult {
133 let mut bits : u32 = 0;
134 loop {
135 match *substate_decode_uint8 {
136 BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE => {
137 if !bit_reader::BrotliSafeReadBits(&mut br, 1, &mut bits, input) {
138 mark_unlikely();
139 return BrotliResult::NeedsMoreInput;
140 }
141 if (bits == 0) {
142 *value = 0;
143 return BrotliResult::ResultSuccess;
144 }
145 *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_SHORT;
146 },
148 BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_SHORT => {
149 if !bit_reader::BrotliSafeReadBits(&mut br, 3, &mut bits, input) {
150 mark_unlikely();
151 *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_SHORT;
152 return BrotliResult::NeedsMoreInput;
153 }
154 if (bits == 0) {
155 *value = 1;
156 *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE;
157 return BrotliResult::ResultSuccess;
158 }
159 *value = bits;
161 *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_LONG;
163 },
164 BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_LONG => {
165 if !bit_reader::BrotliSafeReadBits(&mut br, *value, &mut bits, input) {
166 mark_unlikely();
167 *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_LONG;
168 return BrotliResult::NeedsMoreInput;
169 }
170 *value = (1u32 << *value) + bits;
171 *substate_decode_uint8 = BrotliRunningDecodeUint8State::BROTLI_STATE_DECODE_UINT8_NONE;
172 return BrotliResult::ResultSuccess;
173 },
174 }
175 }
176}
177
178fn DecodeMetaBlockLength<
179 'a, AllocU8 : alloc::Allocator<u8>,
180 AllocU32 : alloc::Allocator<u32>,
181 AllocHC : alloc::Allocator<HuffmanCode> > (s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> BrotliResult {
182 let mut bits : u32 = 0;
183 loop {
184 match s.substate_metablock_header {
185 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE => {
186 if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
187 return BrotliResult::NeedsMoreInput;
188 }
189 s.is_last_metablock = bits as u8;
190 s.meta_block_remaining_len = 0;
191 s.is_uncompressed = 0;
192 s.is_metadata = 0;
193 if (s.is_last_metablock == 0) {
194 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
195 continue;
196 }
197 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_EMPTY;
198 },
200 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_EMPTY => {
201 if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
202 return BrotliResult::NeedsMoreInput;
203 }
204 if bits != 0 {
205 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE;
206 return BrotliResult::ResultSuccess;
207 }
208 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
209 },
211 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NIBBLES => {
212 if !bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut bits, input) {
213 return BrotliResult::NeedsMoreInput;
214 }
215 s.size_nibbles = (bits + 4) as u8;
216 s.loop_counter = 0;
217 if (bits == 3) {
218 s.is_metadata = 1;
219 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_RESERVED;
220 continue;
221 }
222 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_SIZE;
223 },
226 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_SIZE => {
227 let mut i = s.loop_counter;
228 while i < s.size_nibbles as i32 {
229 if !bit_reader::BrotliSafeReadBits(&mut s.br, 4, &mut bits, input) {
230 s.loop_counter = i;
231 return BrotliResult::NeedsMoreInput;
232 }
233 if (i + 1 == s.size_nibbles as i32 && s.size_nibbles > 4 && bits == 0) {
234 return BROTLI_FAILURE();
235 }
236 s.meta_block_remaining_len |= (bits << (i * 4)) as i32;
237 i += 1;
238 }
239 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
240 },
242 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED => {
243 if (s.is_last_metablock == 0 && s.is_metadata == 0) {
244 if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
245 return BrotliResult::NeedsMoreInput;
246 }
247 s.is_uncompressed = bits as u8;
248 }
249 s.meta_block_remaining_len += 1;
250 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE;
251 return BrotliResult::ResultSuccess;
252 },
253 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_RESERVED => {
254 if !bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input) {
255 return BrotliResult::NeedsMoreInput;
256 }
257 if (bits != 0) {
258 return BROTLI_FAILURE();
259 }
260 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_BYTES;
261 },
263 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_BYTES => {
264 if !bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut bits, input) {
265 return BrotliResult::NeedsMoreInput;
266 }
267 if (bits == 0) {
268 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_NONE;
269 return BrotliResult::ResultSuccess;
270 }
271 s.size_nibbles = bits as u8;
272 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_METADATA;
273 },
275 BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_METADATA => {
276 let mut i = s.loop_counter;
277 while i < s.size_nibbles as i32 {
278 if !bit_reader::BrotliSafeReadBits(&mut s.br, 8, &mut bits, input) {
279 s.loop_counter = i;
280 return BrotliResult::NeedsMoreInput;
281 }
282 if (i + 1 == s.size_nibbles as i32 && s.size_nibbles > 1 && bits == 0) {
283 return BROTLI_FAILURE();
284 }
285 s.meta_block_remaining_len |= (bits << (i * 8)) as i32;
286 i += 1;
287 }
288 s.substate_metablock_header = BrotliRunningMetablockHeaderState::BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
289 continue;
290 },
291 }
292 }
293}
294fn DecodeSymbol(bits : u32,
299 table : &[HuffmanCode],
300 br : &mut bit_reader::BrotliBitReader) -> u32 {
301 let mut table_index = bits & HUFFMAN_TABLE_MASK;
302 let mut table_element = table[table_index as usize];
303 if table_element.bits > HUFFMAN_TABLE_BITS as u8{
304 let nbits = table_element.bits - HUFFMAN_TABLE_BITS as u8;
305 bit_reader::BrotliDropBits(br, HUFFMAN_TABLE_BITS);
306 table_index += table_element.value as u32;
307 table_element = table[(table_index
308 + ((bits >> HUFFMAN_TABLE_BITS) & bit_reader::BitMask(nbits as u32))) as usize];
309 }
310 bit_reader::BrotliDropBits(br, table_element.bits as u32);
311 return table_element.value as u32;
312}
313
314fn ReadSymbol(table : &[HuffmanCode],
317 br : &mut bit_reader::BrotliBitReader,
318 input : &[u8]) -> u32{
319 return DecodeSymbol(bit_reader::BrotliGet16BitsUnmasked(br, input), &table, br);
320}
321
322fn SafeDecodeSymbol(table : &[HuffmanCode],
325 mut br : &mut bit_reader::BrotliBitReader,
326 result : &mut u32) -> bool {
327 let mut available_bits = bit_reader::BrotliGetAvailableBits(&mut br);
328 if (available_bits == 0) {
329 if (table[0].bits == 0) {
330 *result = table[0].value as u32;
331 return true;
332 }
333 return false; }
335 let mut val = bit_reader::BrotliGetBitsUnmasked(&br) as u32;
336 let table_index = (val & HUFFMAN_TABLE_MASK) as usize;
337 let table_element = table[table_index];
338 if (table_element.bits <= HUFFMAN_TABLE_BITS as u8) {
339 if (table_element.bits as u32 <= available_bits) {
340 bit_reader::BrotliDropBits(&mut br, table_element.bits as u32);
341 *result = table_element.value as u32;
342 return true;
343 } else {
344 return false; }
346 }
347 if (available_bits <= HUFFMAN_TABLE_BITS) {
348 return false; }
350
351 val = (val & bit_reader::BitMask(table_element.bits as u32)) >> HUFFMAN_TABLE_BITS;
353 available_bits -= HUFFMAN_TABLE_BITS;
354 let table_sub_element = table[table_index + table_element.value as usize + val as usize];
355 if (available_bits < table_sub_element.bits as u32) {
356 return false; }
358
359 bit_reader::BrotliDropBits(&mut br, HUFFMAN_TABLE_BITS + table_sub_element.bits as u32);
360 *result = table_sub_element.value as u32;
361 return true;
362}
363
364fn SafeReadSymbol (table : &[HuffmanCode],
365 br : &mut bit_reader::BrotliBitReader,
366 result : &mut u32,
367 input : &[u8]) -> bool {
368 let mut val : u32 = 0;
369 if (bit_reader::BrotliSafeGetBits(br, 15, &mut val, input)) {
370 *result = DecodeSymbol(val, &table, br);
371 return true;
372 } else {
373 mark_unlikely();
374 }
375 return SafeDecodeSymbol(&table, br, result);
376}
377
378fn PreloadSymbol(safe : bool,
380 table : &[HuffmanCode],
381 br : &mut bit_reader::BrotliBitReader,
382 bits : &mut u32,
383 value : &mut u32,
384 input : &[u8]) {
385 if (safe) {
386 return;
387 }
388 let table_element = table[bit_reader::BrotliGetBits(br, HUFFMAN_TABLE_BITS, input) as usize];
389 *bits = table_element.bits as u32;
390 *value = table_element.value as u32;
391}
392
393fn ReadPreloadedSymbol(table : &[HuffmanCode],
396 br : &mut bit_reader::BrotliBitReader,
397 bits : &mut u32,
398 value : &mut u32,
399 input : &[u8]) -> u32 {
400 let mut result = *value;
401 if *bits > HUFFMAN_TABLE_BITS {
402 mark_unlikely();
403 let val = bit_reader::BrotliGet16BitsUnmasked(br, input);
404 let mut ext_index = (val & HUFFMAN_TABLE_MASK) + *value;
405 let mask = bit_reader::BitMask((*bits - HUFFMAN_TABLE_BITS));
406 bit_reader::BrotliDropBits(br, HUFFMAN_TABLE_BITS);
407 ext_index += (val >> HUFFMAN_TABLE_BITS) & mask;
408 let ext = table[ext_index as usize];
409 bit_reader::BrotliDropBits(br, ext.bits as u32);
410 result = ext.value as u32;
411 } else {
412 bit_reader::BrotliDropBits(br, *bits);
413 }
414 PreloadSymbol(false, table, br, bits, value, input);
415 return result;
416}
417
418fn Log2Floor(mut x : u32) -> u32{
419 let mut result : u32 = 0;
420 while x != 0 {
421 x >>= 1;
422 result += 1;
423 }
424 return result;
425}
426
427
428fn ReadSimpleHuffmanSymbols<
433 'a, AllocU8 : alloc::Allocator<u8>,
434 AllocU32 : alloc::Allocator<u32>,
435 AllocHC : alloc::Allocator<HuffmanCode> >(alphabet_size : u32,
436 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
437 input : &[u8])
438 -> BrotliResult {
439
440 let max_bits = Log2Floor(alphabet_size - 1);
442 let mut i = s.sub_loop_counter;
443 let num_symbols = s.symbol;
444 for symbols_lists_item in s.symbols_lists_array[s.sub_loop_counter as usize ..
445 num_symbols as usize + 1].iter_mut() {
446 let mut v : u32 = 0;
447 if !bit_reader::BrotliSafeReadBits(&mut s.br, max_bits, &mut v, input) {
448 mark_unlikely();
449 s.sub_loop_counter = i;
450 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_READ;
451 return BrotliResult::NeedsMoreInput;
452 }
453 if (v >= alphabet_size) {
454 return BROTLI_FAILURE();
455 }
456 *symbols_lists_item = v as u16;
457 BROTLI_LOG_UINT!(v);
458 i += 1;
459 }
460 i = 0;
461 for symbols_list_item in s.symbols_lists_array[.. num_symbols as usize].iter() {
462 for other_item in s.symbols_lists_array[i as usize + 1 .. num_symbols as usize+ 1].iter() {
463 if (*symbols_list_item == *other_item) {
464 return BROTLI_FAILURE();
465 }
466 }
467 i += 1;
468 }
469
470 return BrotliResult::ResultSuccess;
471}
472
473fn ProcessSingleCodeLength(code_len : u32,
481 symbol : &mut u32, repeat : &mut u32, space : &mut u32,
482 prev_code_len : &mut u32, symbol_lists : &mut [u16], symbol_list_index_offset : usize,
483 code_length_histo : &mut [u16], next_symbol : &mut [i32]) {
484 *repeat = 0;
485 if (code_len != 0) { symbol_lists[(symbol_list_index_offset as i32 + next_symbol[code_len as usize]) as usize] = (*symbol) as u16;
488 next_symbol[code_len as usize] = (*symbol) as i32;
489 *prev_code_len = code_len;
490 *space -= 32768 >> code_len;
491 code_length_histo[code_len as usize] += 1;
492 BROTLI_LOG!("[ReadHuffmanCode] code_length[{:}]={:} histo[]={:}\n", *symbol, code_len, code_length_histo[code_len as usize]);
493 }
494 (*symbol) += 1;
495}
496
497fn ProcessRepeatedCodeLength(code_len : u32,
507 mut repeat_delta : u32, alphabet_size : u32, symbol : &mut u32,
508 repeat : &mut u32, space : &mut u32, prev_code_len : &mut u32,
509 repeat_code_len : &mut u32, symbol_lists : &mut [u16], symbol_lists_index : usize,
510 code_length_histo : &mut [u16], next_symbol : &mut [i32]) {
511 let old_repeat : u32;
512 let mut new_len : u32 = 0;
513 if (code_len == kCodeLengthRepeatCode) {
514 new_len = *prev_code_len;
515 }
516 if (*repeat_code_len != new_len) {
517 *repeat = 0;
518 *repeat_code_len = new_len;
519 }
520 old_repeat = *repeat;
521 if (*repeat > 0) {
522 *repeat -= 2;
523 *repeat <<= code_len - 14;
524 }
525 *repeat += repeat_delta + 3;
526 repeat_delta = *repeat - old_repeat;
527 if (*symbol + repeat_delta > alphabet_size) {
528 let _unused = BROTLI_FAILURE();
529 *symbol = alphabet_size;
530 *space = 0xFFFFF;
531 return;
532 }
533 BROTLI_LOG!("[ReadHuffmanCode] code_length[{:}..{:}] = {:}\n",
534 *symbol, *symbol + repeat_delta - 1, *repeat_code_len);
535 if (*repeat_code_len != 0) {
536 let last : u32 = *symbol + repeat_delta;
537 let mut next : i32 = next_symbol[*repeat_code_len as usize];
538 loop {
539 symbol_lists[(symbol_lists_index as i32 + next) as usize] = (*symbol) as u16;
540 next = (*symbol) as i32;
541 (*symbol) += 1;
542 if *symbol == last {
543 break;
544 }
545 }
546 next_symbol[*repeat_code_len as usize] = next;
547 *space -= repeat_delta << (15 - *repeat_code_len);
548 code_length_histo[*repeat_code_len as usize] =
549 (code_length_histo[*repeat_code_len as usize] as u32 + repeat_delta) as u16;
550 } else {
551 *symbol += repeat_delta;
552 }
553}
554
555fn ReadSymbolCodeLengths<
557 'a, AllocU8 : alloc::Allocator<u8>,
558 AllocU32 : alloc::Allocator<u32>,
559 AllocHC : alloc::Allocator<HuffmanCode> >(alphabet_size : u32,
560 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
561 input : &[u8])
562 -> BrotliResult {
563
564 let mut symbol = s.symbol;
565 let mut repeat = s.repeat;
566 let mut space = s.space;
567 let mut prev_code_len : u32 = s.prev_code_len;
568 let mut repeat_code_len : u32 = s.repeat_code_len;
569 if (!bit_reader::BrotliWarmupBitReader(&mut s.br, input)) {
570 return BrotliResult::NeedsMoreInput;
571 }
572 while (symbol < alphabet_size && space > 0) {
573 let mut p_index = 0;
574 let code_len : u32;
575 if (!bit_reader::BrotliCheckInputAmount(&s.br, bit_reader::BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
576 s.symbol = symbol;
577 s.repeat = repeat;
578 s.prev_code_len = prev_code_len;
579 s.repeat_code_len = repeat_code_len;
580 s.space = space;
581 return BrotliResult::NeedsMoreInput;
582 }
583 bit_reader::BrotliFillBitWindow16(&mut s.br, input);
584 p_index += bit_reader::BrotliGetBitsUnmasked(& s.br) &
585 bit_reader::BitMask(huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as u32) as u64;
586 let p = s.table[p_index as usize];
587 bit_reader::BrotliDropBits(&mut s.br, p.bits as u32); code_len = p.value as u32; if (code_len < kCodeLengthRepeatCode) {
590 ProcessSingleCodeLength(code_len, &mut symbol, &mut repeat, &mut space,
591 &mut prev_code_len, &mut s.symbols_lists_array, s.symbol_lists_index as usize,
592 &mut s.code_length_histo[..], &mut s.next_symbol[..]);
593 } else { let repeat_delta : u32 =
595 bit_reader::BrotliGetBitsUnmasked(&s.br) as u32 & bit_reader::BitMask(code_len - 14);
596 bit_reader::BrotliDropBits(&mut s.br, code_len - 14);
597 ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
598 &mut symbol, &mut repeat, &mut space, &mut prev_code_len, &mut repeat_code_len,
599 &mut s.symbols_lists_array, s.symbol_lists_index as usize,
600 &mut s.code_length_histo[..], &mut s.next_symbol[..]);
601 }
602 }
603 s.space = space;
604 return BrotliResult::ResultSuccess;
605}
606
607fn SafeReadSymbolCodeLengths<
608 'a, AllocU8 : alloc::Allocator<u8>,
609 AllocU32 : alloc::Allocator<u32>,
610 AllocHC : alloc::Allocator<HuffmanCode> >(alphabet_size : u32,
611 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
612 input : &[u8])
613 -> BrotliResult {
614 while (s.symbol < alphabet_size && s.space > 0) {
615 let mut p_index = 0;
616 let code_len : u32;
617 let mut bits : u32 = 0;
618 let available_bits : u32 = bit_reader::BrotliGetAvailableBits(&s.br);
619 if (available_bits != 0) {
620 bits = bit_reader::BrotliGetBitsUnmasked(&s.br) as u32;
621 }
622 p_index += bits & bit_reader::BitMask(huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as u32);
623 let p = s.table[p_index as usize];
624 if (p.bits as u32> available_bits) {
625 if (!bit_reader::BrotliPullByte(&mut s.br, input)) {
627 return BrotliResult::NeedsMoreInput;
628 }
629 continue;
630 }
631 code_len = p.value as u32; if (code_len < kCodeLengthRepeatCode) {
633 bit_reader::BrotliDropBits(&mut s.br, p.bits as u32);
634 ProcessSingleCodeLength(code_len, &mut s.symbol, &mut s.repeat, &mut s.space,
635 &mut s.prev_code_len,
636 &mut s.symbols_lists_array, s.symbol_lists_index as usize,
637 &mut s.code_length_histo[..], &mut s.next_symbol[..]);
638 } else { let extra_bits : u32 = code_len - 14;
640 let repeat_delta : u32 = (bits >> p.bits) & bit_reader::BitMask(extra_bits);
641 if (available_bits < p.bits as u32 + extra_bits) {
642 if (!bit_reader::BrotliPullByte(&mut s.br, input)) {
644 return BrotliResult::NeedsMoreInput;
645 }
646 continue;
647 }
648 bit_reader::BrotliDropBits(&mut s.br, p.bits as u32 + extra_bits);
649 ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
650 &mut s.symbol, &mut s.repeat, &mut s.space, &mut s.prev_code_len,
651 &mut s.repeat_code_len,
652 &mut s.symbols_lists_array, s.symbol_lists_index as usize,
653 &mut s.code_length_histo[..], &mut s.next_symbol[..]);
654 }
655 }
656 return BrotliResult::ResultSuccess;
657}
658
659fn ReadCodeLengthCodeLengths<
662 'a, AllocU8 : alloc::Allocator<u8>,
663 AllocU32 : alloc::Allocator<u32>,
664 AllocHC : alloc::Allocator<HuffmanCode> >(s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
665 input : &[u8])
666 -> BrotliResult {
667
668 let mut num_codes : u32 = s.repeat;
669 let mut space : u32 = s.space;
670 let mut i = s.sub_loop_counter;
671 for code_length_code_order in kCodeLengthCodeOrder[s.sub_loop_counter as usize.. CODE_LENGTH_CODES as usize].iter() {
672 let code_len_idx = *code_length_code_order;
673 let mut ix : u32 = 0;
674
675 if !bit_reader::BrotliSafeGetBits(&mut s.br, 4, &mut ix, input) {
676 mark_unlikely();
677 let available_bits : u32 = bit_reader::BrotliGetAvailableBits(&s.br);
678 if (available_bits != 0) {
679 ix = bit_reader::BrotliGetBitsUnmasked(&s.br) as u32 & 0xF;
680 } else {
681 ix = 0;
682 }
683 if (kCodeLengthPrefixLength[ix as usize] as u32 > available_bits) {
684 s.sub_loop_counter = i;
685 s.repeat = num_codes;
686 s.space = space;
687 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX;
688 return BrotliResult::NeedsMoreInput;
689 }
690 }
691 BROTLI_LOG_UINT!(ix);
692 let v : u32 = kCodeLengthPrefixValue[ix as usize] as u32;
693 bit_reader::BrotliDropBits(&mut s.br, kCodeLengthPrefixLength[ix as usize] as u32);
694 s.code_length_code_lengths[code_len_idx as usize] = v as u8;
695 BROTLI_LOG_ARRAY_INDEX!(s.code_length_code_lengths, code_len_idx);
696 if v != 0 {
697 space = space - (32 >> v);
698 num_codes += 1;
699 s.code_length_histo[v as usize] += 1;
700 if space.wrapping_sub(1) >= 32 {
701 break;
703 }
704 }
705 i += 1;
706 }
707 if (!(num_codes == 1 || space == 0)) {
708 return BROTLI_FAILURE();
709 }
710 return BrotliResult::ResultSuccess;
711}
712
713
714fn ReadHuffmanCode<
727 'a, AllocU8 : alloc::Allocator<u8>,
728 AllocU32 : alloc::Allocator<u32>,
729 AllocHC : alloc::Allocator<HuffmanCode> > (
730 mut alphabet_size : u32,
731 table :&mut [HuffmanCode],
732 offset : usize,
733 opt_table_size : Option<&mut u32>,
734 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
735 input : &[u8]) -> BrotliResult {
736 alphabet_size &= 0x3ff;
738 loop {
740 match s.substate_huffman {
741 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE => {
742 if !bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut s.sub_loop_counter, input) {
743 return BrotliResult::NeedsMoreInput;
744 }
745
746 BROTLI_LOG_UINT!(s.sub_loop_counter);
747 if (s.sub_loop_counter != 1) {
751 s.space = 32;
752 s.repeat = 0; for code_length_histo in s.code_length_histo[..huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH as usize + 1].iter_mut() {
754 *code_length_histo = 0; }
756 for code_length_code_length in s.code_length_code_lengths[..].iter_mut() {
757 *code_length_code_length = 0;
758 }
759 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX;
760 continue;
762 }
763 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
764 },
766 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE => {
767 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut s.symbol, input)) { s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
770 return BrotliResult::NeedsMoreInput;
771 }
772 s.sub_loop_counter = 0;
773 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_READ;
775 },
776 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_READ => {
777 let result = ReadSimpleHuffmanSymbols(alphabet_size, s, input);
778 match result {
779 BrotliResult::ResultSuccess => {},
780 _ => return result,
781 }
782 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
784 },
785 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD => {
786 let table_size : u32;
787 if (s.symbol == 3) {
788 let mut bits : u32 = 0;
789 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input)) {
790 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
791 return BrotliResult::NeedsMoreInput;
792 }
793 s.symbol += bits;
794 }
795 BROTLI_LOG_UINT!(s.symbol);
796 table_size = huffman::BrotliBuildSimpleHuffmanTable(
797 &mut table[offset..], HUFFMAN_TABLE_BITS as i32, &s.symbols_lists_array[..], s.symbol);
798 match opt_table_size {
799 Some(opt_table_size_ref) => *opt_table_size_ref = table_size,
800 None => {},
801 }
802 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE;
803 return BrotliResult::ResultSuccess;
804 },
805
806 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_COMPLEX => {
808
809 let result = ReadCodeLengthCodeLengths(s, input);
810 match result {
811 BrotliResult::ResultSuccess => {},
812 _ => return result,
813 }
814 huffman::BrotliBuildCodeLengthsHuffmanTable(&mut s.table,
815 &mut s.code_length_code_lengths,
816 &mut s.code_length_histo);
817 for code_length_histo in s.code_length_histo[..].iter_mut() {
818 *code_length_histo = 0; }
820
821 let mut i : u32 = 0;
822 for next_symbol_mut in s.next_symbol[..huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH as usize + 1].iter_mut() {
823 *next_symbol_mut = i as i32 - (huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH as i32 + 1);
824 s.symbols_lists_array[(s.symbol_lists_index as i32
825 + i as i32
826 - (huffman::BROTLI_HUFFMAN_MAX_CODE_LENGTH as i32 + 1)) as usize] = 0xFFFF;
827 i += 1;
828 }
829
830 s.symbol = 0;
831 s.prev_code_len = kDefaultCodeLength;
832 s.repeat = 0;
833 s.repeat_code_len = 0;
834 s.space = 32768;
835 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
837 },
838 BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS => {
839 let table_size : u32;
840 let mut result = ReadSymbolCodeLengths(alphabet_size, s, input);
841 match result {
842 BrotliResult::NeedsMoreInput => result = SafeReadSymbolCodeLengths(alphabet_size, s, input),
843 _ => {},
844 }
845 match result {
846 BrotliResult::ResultSuccess => {},
847 _ => return result,
848 }
849
850 if (s.space != 0) {
851 BROTLI_LOG!("[ReadHuffmanCode] space = %d\n", s.space);
852 return BROTLI_FAILURE();
853 }
854 table_size = huffman::BrotliBuildHuffmanTable(&mut table[offset..], HUFFMAN_TABLE_BITS as i32,
855 &s.symbols_lists_array[..], s.symbol_lists_index, &mut s.code_length_histo);
856 match opt_table_size {
857 Some(opt_table_size_ref) => *opt_table_size_ref = table_size,
858 None => {},
859 }
860 s.substate_huffman = BrotliRunningHuffmanState::BROTLI_STATE_HUFFMAN_NONE;
861 return BrotliResult::ResultSuccess;
862 },
863 }
864 }
865}
866
867fn ReadBlockLength(table : &[HuffmanCode],
869 br : &mut bit_reader::BrotliBitReader,
870 input : &[u8]) -> u32 {
871 let code : u32;
872 let nbits : u32;
873 code = ReadSymbol(table, br, input);
874 nbits = prefix::kBlockLengthPrefixCode[code as usize].nbits as u32; return prefix::kBlockLengthPrefixCode[code as usize].offset as u32
876 + bit_reader::BrotliReadBits(br, nbits, input);
877}
878
879
880fn SafeReadBlockLengthIndex(substate_read_block_length : &state::BrotliRunningReadBlockLengthState,
883 block_length_index : u32,
884 table : &[HuffmanCode],
885 mut br : &mut bit_reader::BrotliBitReader,
886 input : &[u8]) -> (bool, u32) {
887 match *substate_read_block_length {
888 state::BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE => {
889 let mut index : u32 = 0;
890 if (!SafeReadSymbol(&table, &mut br, &mut index, input)) {
891 return (false, 0);
892 }
893 return (true, index);
894 },
895 _ => return (true, block_length_index),
896 }
897}
898fn SafeReadBlockLengthFromIndex<
899 AllocHC : alloc::Allocator<HuffmanCode> >(s : &mut BlockTypeAndLengthState<AllocHC>,
900 br : &mut bit_reader::BrotliBitReader,
901 result : &mut u32,
902 res_index : (bool, u32),
903 input : &[u8]) -> bool{
904 let (res, index) = res_index;
905 if !res {
906 return false;
907 }
908 let mut bits : u32 = 0;
909 let nbits = prefix::kBlockLengthPrefixCode[index as usize].nbits; if (!bit_reader::BrotliSafeReadBits(br, nbits as u32, &mut bits, input)) {
911 s.block_length_index = index;
912 s.substate_read_block_length
913 = state::BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
914 return false;
915 }
916 *result = prefix::kBlockLengthPrefixCode[index as usize].offset as u32 + bits;
917 s.substate_read_block_length
918 = state::BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
919 return true;
920}
921macro_rules! SafeReadBlockLength (
922 ($state : expr, $result : expr , $table : expr) => {
923 SafeReadBlockLengthFromIndex(&mut $state, &mut $result,
924 SafeReadBlockLengthIndex($state.substate_read_block_length,
925 $state.block_length_index,
926 $table,
927 &mut $state.br))
928 };
929);
930
931fn InverseMoveToFrontTransform(v : &mut [u8], v_len : u32, mtf : &mut [u8], mtf_upper_bound :&mut u32) {
947 let mut i : u32 = 0;
949 let mut upper_bound : u32 = *mtf_upper_bound;
950 for item in mtf[0..(upper_bound as usize + 1usize)].iter_mut() {
951 *item = i as u8;
952 i += 1;
953 }
954
955 upper_bound = 0;
957 for v_i in v[0usize .. (v_len as usize)].iter_mut() {
958 let mut index = (*v_i) as i32;
959 let value = mtf[index as usize];
960 upper_bound |= (*v_i) as u32;
961 *v_i = value;
962 if index <= 0 {
963 mtf[0] = 0;
964 } else {
965 loop {
966 index-=1;
967 mtf[(index + 1) as usize] = mtf[index as usize];
968 if index <= 0 {
969 break;
970 }
971 }
972 }
973 mtf[0] = value;
974 }
975 *mtf_upper_bound = upper_bound;
977}
978fn HuffmanTreeGroupDecode<
980 'a,
981 AllocU8 : alloc::Allocator<u8>,
982 AllocU32 : alloc::Allocator<u32>,
983 AllocHC : alloc::Allocator<HuffmanCode>>(group_index : i32,
984 mut s : &mut BrotliState<AllocU8,
985 AllocU32,
986 AllocHC>,
987 input : &[u8]) -> BrotliResult {
988 let mut hcodes : AllocHC::AllocatedMemory;
989 let mut htrees : AllocU32::AllocatedMemory;
990 let alphabet_size : u16;
991 let group_num_htrees : u16;
992 if group_index == 0 {
993 hcodes = mem::replace(&mut s.literal_hgroup.codes, AllocHC::AllocatedMemory::default());
994 htrees = mem::replace(&mut s.literal_hgroup.htrees, AllocU32::AllocatedMemory::default());
995 group_num_htrees = s.literal_hgroup.num_htrees;
996 alphabet_size = s.literal_hgroup.alphabet_size;
997 } else if group_index == 1 {
998 hcodes = mem::replace(&mut s.insert_copy_hgroup.codes, AllocHC::AllocatedMemory::default());
999 htrees = mem::replace(&mut s.insert_copy_hgroup.htrees, AllocU32::AllocatedMemory::default());
1000 group_num_htrees = s.insert_copy_hgroup.num_htrees;
1001 alphabet_size = s.insert_copy_hgroup.alphabet_size;
1002 } else {
1003 assert_eq!(group_index, 2);
1004 hcodes = mem::replace(&mut s.distance_hgroup.codes, AllocHC::AllocatedMemory::default());
1005 htrees = mem::replace(&mut s.distance_hgroup.htrees, AllocU32::AllocatedMemory::default());
1006 group_num_htrees = s.distance_hgroup.num_htrees;
1007 alphabet_size = s.distance_hgroup.alphabet_size;
1008 }
1009 match s.substate_tree_group {
1010 BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_NONE => {
1011 s.htree_next_offset = 0;
1012 s.htree_index = 0;
1013 s.substate_tree_group = BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_LOOP;
1014 },
1015 BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_LOOP => {},
1016 }
1017 let mut result : BrotliResult = BrotliResult::ResultSuccess;
1018 for mut htree_iter in htrees.slice_mut()[s.htree_index as usize .. (group_num_htrees as usize)].iter_mut() {
1019 let mut table_size : u32 = 0;
1020 result = ReadHuffmanCode(alphabet_size as u32,
1021 hcodes.slice_mut(),
1022 s.htree_next_offset as usize,
1023 Some(&mut table_size),
1024 &mut s,
1025 input);
1026 match result {
1027 BrotliResult::ResultSuccess => {},
1028 _ => break, }
1030 *htree_iter = s.htree_next_offset;
1031 s.htree_next_offset += table_size;
1032 s.htree_index += 1;
1033 }
1034 if group_index == 0 {
1035 mem::replace(&mut s.literal_hgroup.codes,
1036 mem::replace(&mut hcodes,
1037 AllocHC::AllocatedMemory::default()));
1038 mem::replace(&mut s.literal_hgroup.htrees,
1039 mem::replace(&mut htrees,
1040 AllocU32::AllocatedMemory::default()));
1041 } else if group_index == 1 {
1042 mem::replace(&mut s.insert_copy_hgroup.codes,
1043 mem::replace(&mut hcodes,
1044 AllocHC::AllocatedMemory::default()));
1045 mem::replace(&mut s.insert_copy_hgroup.htrees,
1046 mem::replace(&mut htrees,
1047 AllocU32::AllocatedMemory::default()));
1048 } else {
1049 mem::replace(&mut s.distance_hgroup.codes,
1050 mem::replace(&mut hcodes,
1051 AllocHC::AllocatedMemory::default()));
1052 mem::replace(&mut s.distance_hgroup.htrees,
1053 mem::replace(&mut htrees,
1054 AllocU32::AllocatedMemory::default()));
1055 }
1056 match result {
1057 BrotliResult::ResultSuccess => s.substate_tree_group = BrotliRunningTreeGroupState::BROTLI_STATE_TREE_GROUP_NONE,
1058 _ => {},
1059 }
1060 return result;
1061}
1062
1063
1064fn bzero(data : &mut [u8]) {
1065 for iter in data.iter_mut() {
1066 *iter = 0;
1067 }
1068}
1069
1070
1071fn DecodeContextMapInner<
1081 'a,
1082 AllocU8 : alloc::Allocator<u8>,
1083 AllocU32 : alloc::Allocator<u32>,
1084 AllocHC : alloc::Allocator<HuffmanCode>> (context_map_size : u32,
1085 num_htrees : &mut u32,
1086 context_map_arg : &mut AllocU8::AllocatedMemory,
1087 mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1088 input : &[u8])
1089 -> BrotliResult {
1090
1091 let mut result : BrotliResult;
1092 loop {
1093 match s.substate_context_map {
1094 BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_NONE => {
1095 result = DecodeVarLenUint8(&mut s.substate_decode_uint8, &mut s.br, num_htrees, input);
1096 match result {
1097 BrotliResult::ResultSuccess => {},
1098 _ => return result,
1099 }
1100 (*num_htrees) += 1;
1101 s.context_index = 0;
1102 BROTLI_LOG_UINT!(context_map_size);
1103 BROTLI_LOG_UINT!(*num_htrees);
1104 *context_map_arg = s.alloc_u8.alloc_cell(context_map_size as usize);
1105 if (context_map_arg.slice().len() < context_map_size as usize) {
1106 return BROTLI_FAILURE();
1107 }
1108 if (*num_htrees <= 1) {
1109 bzero(context_map_arg.slice_mut()); return BrotliResult::ResultSuccess;
1111 }
1112 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
1113 },
1115 BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_READ_PREFIX => {
1116 let mut bits : u32 = 0;
1117 if (!bit_reader::BrotliSafeGetBits(&mut s.br, 5, &mut bits, input)) {
1120 return BrotliResult::NeedsMoreInput;
1121 }
1122 if ((bits & 1) != 0) { s.max_run_length_prefix = (bits >> 1) + 1;
1124 bit_reader::BrotliDropBits(&mut s.br, 5);
1125 } else {
1126 s.max_run_length_prefix = 0;
1127 bit_reader::BrotliDropBits(&mut s.br, 1);
1128 }
1129 BROTLI_LOG_UINT!(s.max_run_length_prefix);
1130 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
1131 }
1133 BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_HUFFMAN => {
1134
1135 let mut local_context_map_table = mem::replace(&mut s.context_map_table,
1136 AllocHC::AllocatedMemory::default());
1137 result = ReadHuffmanCode(*num_htrees + s.max_run_length_prefix,
1138 &mut local_context_map_table.slice_mut(), 0, None, &mut s, input);
1139 mem::replace(&mut s.context_map_table, mem::replace(&mut local_context_map_table,
1140 AllocHC::AllocatedMemory::default()));
1141 match result {
1142 BrotliResult::ResultSuccess => {},
1143 _ => return result,
1144 }
1145 s.code = 0xFFFF;
1146 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_DECODE;
1147 },
1149 BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_DECODE => {
1150 let mut context_index : u32 = s.context_index;
1151 let max_run_length_prefix : u32 = s.max_run_length_prefix;
1152 let mut context_map = &mut context_map_arg.slice_mut();
1153 let mut code : u32 = s.code;
1154 let mut rleCodeGoto : bool = false;
1155 if (code != 0xFFFF) {
1156 rleCodeGoto = true;
1157 }
1158 while (rleCodeGoto || context_index < context_map_size) {
1159 if !rleCodeGoto {
1160 if (!SafeReadSymbol(s.context_map_table.slice(), &mut s.br, &mut code, input)) {
1161 s.code = 0xFFFF;
1162 s.context_index = context_index;
1163 return BrotliResult::NeedsMoreInput;
1164 }
1165 BROTLI_LOG_UINT!(code);
1166
1167 if code == 0 {
1168 context_map[context_index as usize] = 0;
1169 BROTLI_LOG_ARRAY_INDEX!(context_map, context_index as usize);
1170 context_index += 1;
1171 continue;
1172 }
1173 if code > max_run_length_prefix {
1174 context_map[context_index as usize] =
1175 (code - max_run_length_prefix) as u8;
1176 BROTLI_LOG_ARRAY_INDEX!(context_map, context_index as usize);
1177 context_index += 1;
1178 continue;
1179 }
1180 }
1181 rleCodeGoto = false; {
1184 let mut reps : u32 = 0;
1185 if (!bit_reader::BrotliSafeReadBits(&mut s.br, code, &mut reps, input)) {
1186 s.code = code;
1187 s.context_index = context_index;
1188 return BrotliResult::NeedsMoreInput;
1189 }
1190 reps += 1u32 << code;
1191 BROTLI_LOG_UINT!(reps);
1192 if (context_index + reps > context_map_size) {
1193 return BROTLI_FAILURE();
1194 }
1195 loop {
1196 context_map[context_index as usize] = 0;
1197 BROTLI_LOG_ARRAY_INDEX!(context_map, context_index as usize);
1198 context_index += 1;
1199 reps -= 1;
1200 if reps == 0 {
1201 break;
1202 }
1203 }
1204 }
1205 }
1206 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
1208 },
1209 BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_TRANSFORM => {
1210 let mut bits : u32 = 0;
1211 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 1, &mut bits, input)) {
1212 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
1213 return BrotliResult::NeedsMoreInput;
1214 }
1215 if (bits != 0) {
1216 InverseMoveToFrontTransform(context_map_arg.slice_mut(),
1217 context_map_size,
1218 &mut s.mtf,
1219 &mut s.mtf_upper_bound);
1220 }
1221 s.substate_context_map = BrotliRunningContextMapState::BROTLI_STATE_CONTEXT_MAP_NONE;
1222 return BrotliResult::ResultSuccess;
1223 },
1224 }
1225 }
1226 }
1228
1229fn DecodeContextMap<
1230 'a, AllocU8 : alloc::Allocator<u8>,
1231 AllocU32 : alloc::Allocator<u32>,
1232 AllocHC : alloc::Allocator<HuffmanCode>> (context_map_size : usize,
1233 is_dist_context_map : bool,
1234 mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1235 input : &[u8])
1236 -> BrotliResult {
1237
1238 match s.state {
1239 BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1 => assert_eq!(is_dist_context_map, false),
1240 BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2 => assert_eq!(is_dist_context_map, true),
1241 _ => unreachable!(),
1242 }
1243 let mut num_htrees : u32;
1244 let mut context_map_arg : AllocU8::AllocatedMemory;
1245 if is_dist_context_map {
1246 num_htrees = s.num_dist_htrees;
1247 context_map_arg = mem::replace(&mut s.dist_context_map,
1248 AllocU8::AllocatedMemory::default());
1249 } else {
1250 num_htrees = s.num_literal_htrees;
1251 context_map_arg = mem::replace(&mut s.context_map,
1252 AllocU8::AllocatedMemory::default());
1253 }
1254
1255 let retval = DecodeContextMapInner(context_map_size as u32, &mut num_htrees, &mut context_map_arg, &mut s, input);
1256 if is_dist_context_map {
1257 s.num_dist_htrees = num_htrees;
1258 mem::replace(&mut s.dist_context_map, mem::replace(&mut context_map_arg,
1259 AllocU8::AllocatedMemory::default()));
1260 } else {
1261 s.num_literal_htrees = num_htrees;
1262 mem::replace(&mut s.context_map, mem::replace(&mut context_map_arg,
1263 AllocU8::AllocatedMemory::default()));
1264 }
1265 return retval;
1266}
1267fn DecodeBlockTypeAndLength<
1270 AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1271 mut s : &mut BlockTypeAndLengthState<AllocHC>,
1272 mut br : &mut bit_reader::BrotliBitReader,
1273 tree_type : i32,
1274 input : &[u8]) -> bool {
1275 let max_block_type = s.num_block_types[tree_type as usize];
1276 let tree_offset = tree_type as usize * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize;
1277
1278 let mut block_type : u32 = 0;
1279
1280 if (!safe) {
1282 block_type = ReadSymbol(&s.block_type_trees.slice()[tree_offset..], br, input);
1283 s.block_length[tree_type as usize] = ReadBlockLength(&s.block_len_trees.slice()[tree_offset..],
1284 br,
1285 input);
1286 } else {
1287 let memento = bit_reader::BrotliBitReaderSaveState(br);
1288 if (!SafeReadSymbol(&s.block_type_trees.slice()[tree_offset..], br, &mut block_type, input)) {
1289 return false;
1290 }
1291 let mut block_length_out : u32 = 0;
1292
1293 let index_ret = SafeReadBlockLengthIndex(&s.substate_read_block_length,
1294 s.block_length_index,
1295 &s.block_len_trees.slice()[tree_offset..],
1296 br,
1297 input);
1298 if !SafeReadBlockLengthFromIndex(s,
1299 br,
1300 &mut block_length_out, index_ret, input) {
1301 s.substate_read_block_length
1302 = BrotliRunningReadBlockLengthState::BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
1303 bit_reader::BrotliBitReaderRestoreState(br, &memento);
1304 return false;
1305 }
1306 s.block_length[tree_type as usize] = block_length_out;
1307 }
1308 let ringbuffer : &mut [u32]= &mut s.block_type_rb[tree_type as usize * 2 ..];
1309 if (block_type == 1) {
1310 block_type = ringbuffer[1] + 1;
1311 } else if (block_type == 0) {
1312 block_type = ringbuffer[0];
1313 } else {
1314 block_type -= 2;
1315 }
1316 if (block_type >= max_block_type) {
1317 block_type -= max_block_type;
1318 }
1319 ringbuffer[0] = ringbuffer[1];
1320 ringbuffer[1] = block_type;
1321 return true;
1322
1323}
1324pub const FILE_BUFFER_SIZE : usize = 65536;
1325fn DecodeLiteralBlockSwitchInternal<
1329 AllocU8 : alloc::Allocator<u8>,
1330 AllocU32 : alloc::Allocator<u32>,
1331 AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1332 mut s : &mut BrotliState<AllocU8,
1333 AllocU32,
1334 AllocHC>,
1335 input : &[u8]) -> bool {
1336
1337 let context_mode : u8;
1338 let context_offset : u32;
1339 if !DecodeBlockTypeAndLength(safe, &mut s.block_type_length_state, &mut s.br, 0, input) {
1340 return false;
1341 }
1342 context_offset = s.block_type_length_state.block_type_rb[1] << kLiteralContextBits;
1343 s.context_map_slice_index = context_offset as usize;
1344 s.literal_htree_index = s.context_map.slice()[s.context_map_slice_index];
1345 context_mode = s.context_modes.slice()[s.block_type_length_state.block_type_rb[1] as usize];
1347 s.context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode as usize] as usize ..];
1348 s.context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode as usize + 1] as usize..];
1349 return true;
1350}
1351fn DecodeCommandBlockSwitchInternal<
1373 'a,
1374 AllocU8 : alloc::Allocator<u8>,
1375 AllocU32 : alloc::Allocator<u32>,
1376 AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1377 mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> bool {
1378 if (!DecodeBlockTypeAndLength(safe, &mut s.block_type_length_state, &mut s.br, 1, input)) {
1379 return false;
1380 }
1381 s.htree_command_index = s.block_type_length_state.block_type_rb[3] as u16;
1382 return true;
1383}
1384
1385#[allow(dead_code)]
1386fn DecodeCommandBlockSwitch<
1387 'a,
1388 AllocU8 : alloc::Allocator<u8>,
1389 AllocU32 : alloc::Allocator<u32>,
1390 AllocHC : alloc::Allocator<HuffmanCode>> (mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) {
1391 DecodeCommandBlockSwitchInternal(false, s, input);
1392}
1393#[allow(dead_code)]
1394fn SafeDecodeCommandBlockSwitch<
1395 'a,
1396 AllocU8 : alloc::Allocator<u8>,
1397 AllocU32 : alloc::Allocator<u32>,
1398 AllocHC : alloc::Allocator<HuffmanCode>> (mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> bool {
1399 return DecodeCommandBlockSwitchInternal(true, s, input);
1400}
1401
1402fn DecodeDistanceBlockSwitchInternal<
1405 'a,
1406 AllocU8 : alloc::Allocator<u8>,
1407 AllocU32 : alloc::Allocator<u32>,
1408 AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1409 mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> bool {
1410 if (!DecodeBlockTypeAndLength(safe, &mut s.block_type_length_state, &mut s.br, 2, input)) {
1411 return false;
1412 }
1413 s.dist_context_map_slice_index = (s.block_type_length_state.block_type_rb[5] << kDistanceContextBits) as usize;
1414 s.dist_htree_index = s.dist_context_map.slice()[s.dist_context_map_slice_index
1415 + s.distance_context as usize];
1416 return true;
1417}
1418
1419#[allow(dead_code)]
1420fn DecodeDistanceBlockSwitch<
1421 'a,
1422 AllocU8 : alloc::Allocator<u8>,
1423 AllocU32 : alloc::Allocator<u32>,
1424 AllocHC : alloc::Allocator<HuffmanCode>> (mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) {
1425 DecodeDistanceBlockSwitchInternal(false, s, input);
1426}
1427
1428#[allow(dead_code)]
1429fn SafeDecodeDistanceBlockSwitch<
1430 'a,
1431 AllocU8 : alloc::Allocator<u8>,
1432 AllocU32 : alloc::Allocator<u32>,
1433 AllocHC : alloc::Allocator<HuffmanCode>> (mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> bool {
1434 return DecodeDistanceBlockSwitchInternal(true, s, input);
1435}
1436
1437fn WriteRingBuffer<'a, AllocU8 : alloc::Allocator<u8>,
1438 AllocU32 : alloc::Allocator<u32>,
1439 AllocHC : alloc::Allocator<HuffmanCode> >
1440 (available_out : &mut usize, mut output : &mut [u8], mut output_offset : &mut usize,
1441 mut total_out : &mut usize, s : &mut BrotliState<AllocU8, AllocU32, AllocHC>) -> BrotliResult {
1442 let pos : usize;
1443 if s.pos > s.ringbuffer_size {
1444 pos = s.ringbuffer_size as usize;
1445 } else {
1446 pos = s.pos as usize;
1447 }
1448 let partial_pos_rb =
1449 (s.rb_roundtrips as usize * s.ringbuffer_size as usize) + pos as usize;
1450 let to_write = (partial_pos_rb - s.partial_pos_out) as usize;
1451 let mut num_written = *available_out as usize;
1452 if (num_written > to_write) {
1453 num_written = to_write;
1454 }
1455 if (s.meta_block_remaining_len < 0) {
1456 return BROTLI_FAILURE();
1457 }
1458 let start_index = (s.partial_pos_out & s.ringbuffer_mask as usize) as usize;
1459 let start = &s.ringbuffer.slice()[start_index .. start_index + num_written as usize];
1460 output[*output_offset .. *output_offset + num_written as usize].clone_from_slice(start);
1461 *output_offset += num_written;
1462 *available_out -= num_written;
1463 BROTLI_LOG_UINT!(to_write);
1464 BROTLI_LOG_UINT!(num_written);
1465 s.partial_pos_out += num_written as usize;
1466 *total_out = s.partial_pos_out;
1467 if (num_written < to_write) {
1468 return BrotliResult::NeedsMoreOutput;
1469 }
1470 return BrotliResult::ResultSuccess;
1471}
1472
1473fn CopyUncompressedBlockToOutput<'a, AllocU8 : alloc::Allocator<u8>,
1474 AllocU32 : alloc::Allocator<u32>,
1475 AllocHC : alloc::Allocator<HuffmanCode> >
1476 (mut available_out : &mut usize,
1477 mut output : &mut [u8],
1478 mut output_offset : &mut usize,
1479 mut total_out : &mut usize,
1480 mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1481 input : &[u8]) -> BrotliResult {
1482 loop {
1484 match s.substate_uncompressed {
1485 BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_NONE => {
1486 let mut nbytes = bit_reader::BrotliGetRemainingBytes(&s.br) as i32;
1487 if (nbytes > s.meta_block_remaining_len) {
1488 nbytes = s.meta_block_remaining_len;
1489 }
1490 if (s.pos + nbytes > s.ringbuffer_size) {
1491 nbytes = s.ringbuffer_size - s.pos;
1492 }
1493 bit_reader::BrotliCopyBytes(&mut s.ringbuffer.slice_mut()[s.pos as usize..],
1495 &mut s.br,
1496 nbytes as u32,
1497 input);
1498 s.pos += nbytes;
1499 s.meta_block_remaining_len -= nbytes;
1500 if (s.pos < s.ringbuffer_size) {
1501 if (s.meta_block_remaining_len == 0) {
1502 return BrotliResult::ResultSuccess;
1503 }
1504 return BrotliResult::NeedsMoreInput;
1505 }
1506 s.substate_uncompressed = BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_WRITE;
1507 },
1510 BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_WRITE => {
1511 let result = WriteRingBuffer(
1512 &mut available_out, &mut output, &mut output_offset, &mut total_out, &mut s);
1513 match result {
1514 BrotliResult::ResultSuccess => {},
1515 _ => return result,
1516 }
1517 s.pos = 0;
1518 s.rb_roundtrips+=1;
1519 s.max_distance = s.max_backward_distance;
1520 s.substate_uncompressed = BrotliRunningUncompressedState::BROTLI_STATE_UNCOMPRESSED_NONE;
1521 },
1522 }
1523 }
1524}
1525
1526fn BrotliAllocateRingBuffer<
1527 'a, AllocU8 : alloc::Allocator<u8>,
1528 AllocU32 : alloc::Allocator<u32>,
1529 AllocHC : alloc::Allocator<HuffmanCode> > (s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> bool {
1530 const kRingBufferWriteAheadSlack : i32 = 42;
1534 let mut is_last = s.is_last_metablock;
1535 s.ringbuffer_size = 1 << s.window_bits;
1536
1537 if (s.is_uncompressed != 0) {
1538 let next_block_header = bit_reader::BrotliPeekByte(&mut s.br,
1539 s.meta_block_remaining_len as u32,
1540 input);
1541 if (next_block_header != -1) { if ((next_block_header & 3) == 3) { is_last = 1;
1544 }
1545 }
1546 }
1547
1548 if (is_last != 0) {
1551 while (s.ringbuffer_size >= s.meta_block_remaining_len * 2
1552 && s.ringbuffer_size > 32) {
1553 s.ringbuffer_size >>= 1;
1554 }
1555 }
1556
1557 while (s.ringbuffer_size < s.custom_dict_size) {
1559 s.ringbuffer_size <<= 1;
1560 }
1561
1562 s.ringbuffer_mask = s.ringbuffer_size - 1;
1563 s.ringbuffer = s.alloc_u8.alloc_cell((s.ringbuffer_size as usize +
1564 kRingBufferWriteAheadSlack as usize + kBrotliMaxDictionaryWordLength as usize));
1565 if (s.ringbuffer.slice().len() == 0) {
1566 return false;
1567 }
1568 s.ringbuffer.slice_mut()[s.ringbuffer_size as usize - 1] = 0;
1569 s.ringbuffer.slice_mut()[s.ringbuffer_size as usize - 2] = 0;
1570 if (s.custom_dict.slice().len() > 0) {
1571 let offset = ((-s.custom_dict_size) & s.ringbuffer_mask) as usize;
1572 let cds = s.custom_dict_size as usize;
1573 s.ringbuffer.slice_mut()[offset .. offset + cds].clone_from_slice(&s.custom_dict.slice()[0..cds]);
1574 }
1575
1576 return true;
1577}
1578
1579pub fn ReadContextModes<'a, AllocU8 : alloc::Allocator<u8>,
1581 AllocU32 : alloc::Allocator<u32>,
1582 AllocHC : alloc::Allocator<HuffmanCode>> (
1583 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1584 input : &[u8]) -> BrotliResult {
1585
1586 let mut i : i32 = s.loop_counter;
1587
1588 for context_mode_iter in s.context_modes.slice_mut()[i as usize ..
1589 (s.block_type_length_state.num_block_types[0]
1590 as usize)].iter_mut() {
1591 let mut bits : u32 = 0;
1592 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 2, &mut bits, input)) {
1593 mark_unlikely();
1594 s.loop_counter = i;
1595 return BrotliResult::NeedsMoreInput;
1596 }
1597 *context_mode_iter = (bits << 1) as u8;
1598 BROTLI_LOG_UINT!(i);
1599 BROTLI_LOG_UINT!(*context_mode_iter);
1600 i+=1;
1601 }
1602 return BrotliResult::ResultSuccess;
1603}
1604
1605pub fn TakeDistanceFromRingBuffer<'a, AllocU8 : alloc::Allocator<u8>,
1606 AllocU32 : alloc::Allocator<u32>,
1607 AllocHC : alloc::Allocator<HuffmanCode>> (
1608 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>) {
1609 if (s.distance_code == 0) {
1610 s.dist_rb_idx -= 1;
1611 s.distance_code = s.dist_rb[(s.dist_rb_idx & 3) as usize];
1612 } else {
1613 let distance_code = s.distance_code << 1;
1614 const kDistanceShortCodeIndexOffset : u32= 0xaaafff1b;
1617 const kDistanceShortCodeValueOffset : u32 = 0xfa5fa500;
1620 let mut v = (s.dist_rb_idx as i32 +
1621 (kDistanceShortCodeIndexOffset as i32 >> distance_code as i32)) as i32 & 0x3;
1622 s.distance_code = s.dist_rb[v as usize];
1623 v = (kDistanceShortCodeValueOffset >> distance_code) as i32 & 0x3;
1624 if ((distance_code & 0x3) != 0) {
1625 s.distance_code += v;
1626 } else {
1627 s.distance_code -= v;
1628 if (s.distance_code <= 0) {
1629 s.distance_code = 0x0fffffff;
1632 }
1633 }
1634 }
1635}
1636
1637pub fn SafeReadBits(br : &mut bit_reader::BrotliBitReader, n_bits : u32, val : &mut u32, input : &[u8]) -> bool {
1638 if (n_bits != 0) {
1639 return bit_reader::BrotliSafeReadBits(br, n_bits, val, input);
1640 } else {
1641 *val = 0;
1642 return true;
1643 }
1644}
1645
1646pub fn ReadDistanceInternal<'a, AllocU8 : alloc::Allocator<u8>,
1648 AllocU32 : alloc::Allocator<u32>,
1649 AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1650 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1651 input : &[u8],
1652 distance_hgroup : &[&[HuffmanCode]; 256]) -> bool {
1653 let mut distval : i32;
1654 let mut memento = bit_reader::BrotliBitReaderState::default();
1655 if (!safe) {
1656 s.distance_code
1657 = ReadSymbol(distance_hgroup[s.dist_htree_index as usize],
1658 &mut s.br,
1659 input) as i32;
1660 } else {
1661 let mut code : u32 = 0;
1662 memento = bit_reader::BrotliBitReaderSaveState(&s.br);
1663 if !SafeReadSymbol(distance_hgroup[s.dist_htree_index as usize], &mut s.br, &mut code, input) {
1664 return false;
1665 }
1666 s.distance_code = code as i32;
1667 }
1668 if ((s.distance_code as u64 & 0xfffffffffffffff0) == 0) {
1671 TakeDistanceFromRingBuffer(s);
1672 s.block_type_length_state.block_length[2] -= 1;
1673 return true;
1674 }
1675 distval = s.distance_code - s.num_direct_distance_codes as i32;
1676 if (distval >= 0) {
1677 let nbits : u32;
1678 let postfix : i32;
1679 let offset : i32;
1680 if (!safe && (s.distance_postfix_bits == 0)) {
1681 nbits = (distval as u32 >> 1) + 1;
1682 offset = ((2 + (distval & 1)) << nbits) - 4;
1683 s.distance_code = s.num_direct_distance_codes as i32 +
1684 offset + bit_reader::BrotliReadBits(&mut s.br, nbits, input) as i32;
1685 } else {
1686 let mut bits : u32 = 0;
1688 postfix = distval & s.distance_postfix_mask;
1689 distval >>= s.distance_postfix_bits;
1690 nbits = (distval as u32 >> 1) + 1;
1691 if (safe) {
1692 if (!SafeReadBits(&mut s.br, nbits, &mut bits, input)) {
1693 s.distance_code = -1; bit_reader::BrotliBitReaderRestoreState(&mut s.br, &mut memento);
1695 return false;
1696 }
1697 } else {
1698 bits = bit_reader::BrotliReadBits(&mut s.br, nbits, input);
1699 }
1700 offset = ((2 + (distval & 1)) << nbits) - 4;
1701 s.distance_code = s.num_direct_distance_codes as i32 +
1702 ((offset + bits as i32) << s.distance_postfix_bits) + postfix;
1703 }
1704 }
1705 s.distance_code = s.distance_code - NUM_DISTANCE_SHORT_CODES as i32 + 1;
1706 s.block_type_length_state.block_length[2] -= 1;
1707 return true;
1708}
1709
1710
1711pub fn ReadCommandInternal<'a, AllocU8 : alloc::Allocator<u8>,
1712 AllocU32 : alloc::Allocator<u32>,
1713 AllocHC : alloc::Allocator<HuffmanCode>> (safe : bool,
1714 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1715 insert_length : &mut i32,
1716 input : &[u8],
1717 insert_copy_hgroup : &[&[HuffmanCode]; 256]) -> bool {
1718 let mut cmd_code : u32 = 0;
1719 let mut insert_len_extra : u32 = 0;
1720 let mut copy_length : u32 = 0;
1721 let v : prefix::CmdLutElement;
1722 let mut memento = bit_reader::BrotliBitReaderState::default();
1723 if (!safe) {
1724 cmd_code = ReadSymbol(insert_copy_hgroup[s.htree_command_index as usize], &mut s.br, input);
1725 } else {
1726 memento = bit_reader::BrotliBitReaderSaveState(&s.br);
1727 if (!SafeReadSymbol(
1728 insert_copy_hgroup[s.htree_command_index as usize],
1729 &mut s.br, &mut cmd_code, input)) {
1730 return false;
1731 }
1732 }
1733 v = prefix::kCmdLut[cmd_code as usize];
1734 s.distance_code = v.distance_code as i32;
1735 s.distance_context = v.context as i32;
1736 s.dist_htree_index = s.dist_context_map.slice()[s.dist_context_map_slice_index
1737 + s.distance_context as usize];
1738 *insert_length = v.insert_len_offset as i32;
1739 if (!safe) {
1740 if v.insert_len_extra_bits != 0 {
1741 mark_unlikely();
1742 insert_len_extra = bit_reader::BrotliReadBits(&mut s.br, v.insert_len_extra_bits as u32, input);
1743 }
1744 copy_length = bit_reader::BrotliReadBits(&mut s.br, v.copy_len_extra_bits as u32, input);
1745 } else {
1746 if (!SafeReadBits(&mut s.br, v.insert_len_extra_bits as u32, &mut insert_len_extra, input)) ||
1747 (!SafeReadBits(&mut s.br, v.copy_len_extra_bits as u32, &mut copy_length, input)) {
1748 bit_reader::BrotliBitReaderRestoreState(&mut s.br, &memento);
1749 return false;
1750 }
1751 }
1752 s.copy_length = copy_length as i32 + v.copy_len_offset as i32;
1753 s.block_type_length_state.block_length[1] -= 1;
1754 *insert_length += insert_len_extra as i32;
1755 return true;
1756}
1757
1758
1759fn WarmupBitReader(safe : bool, br : &mut bit_reader::BrotliBitReader, input : &[u8]) -> bool {
1760 if (safe) {
1761 return true;
1762 }
1763 return bit_reader::BrotliWarmupBitReader(br, input);
1764}
1765
1766fn CheckInputAmount(safe : bool,
1767 br : &bit_reader::BrotliBitReader, num : u32) -> bool {
1768 if (safe) {
1769 return true;
1770 }
1771 return bit_reader::BrotliCheckInputAmount(br, num);
1772}
1773
1774
1775fn memmove16(data : &mut [u8], u32off_dst : u32, u32off_src :u32) {
1776 let off_dst = u32off_dst as usize;
1777 let off_src = u32off_src as usize;
1778let mut local_array : [u8; 16] = [0;16];
1799 local_array.clone_from_slice(&mut data[off_src as usize .. off_src as usize + 16]);
1800 data[off_dst as usize .. off_dst as usize + 16].clone_from_slice(&mut local_array);
1801
1802
1803}
1804
1805fn memcpy_within_slice(data : &mut [u8],
1806 off_dst : usize,
1807 off_src : usize,
1808 size : usize) {
1809 if off_dst > off_src {
1810 let (src, dst) = data.split_at_mut(off_dst);
1811 dst[..size].clone_from_slice(&src[off_src .. off_src + size]);
1812 } else {
1813 let (dst, src) = data.split_at_mut(off_src);
1814 dst[off_dst..off_dst + size].clone_from_slice(&src[..size]);
1815 }
1816}
1817
1818fn ProcessCommandsInternal<
1819 AllocU8 : alloc::Allocator<u8>,
1820 AllocU32 : alloc::Allocator<u32>,
1821 AllocHC : alloc::Allocator<HuffmanCode> > (safe : bool,
1822 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>,
1823 input : &[u8]) -> BrotliResult {
1824 if (!CheckInputAmount(safe, &s.br, 28)) || (!WarmupBitReader(safe, &mut s.br, input)) {
1825 mark_unlikely();
1826 return BrotliResult::NeedsMoreInput;
1827 }
1828 let mut pos = s.pos;
1829 let mut i : i32 = s.loop_counter; let mut result : BrotliResult = BrotliResult::ResultSuccess;
1831 let mut saved_literal_hgroup = core::mem::replace(&mut s.literal_hgroup,
1832 HuffmanTreeGroup::<AllocU32, AllocHC>::default());
1833 let mut saved_distance_hgroup = core::mem::replace(&mut s.distance_hgroup,
1834 HuffmanTreeGroup::<AllocU32, AllocHC>::default());
1835 let mut saved_insert_copy_hgroup = core::mem::replace(&mut s.insert_copy_hgroup,
1836 HuffmanTreeGroup::<AllocU32, AllocHC>::default());
1837 {
1838
1839 let literal_hgroup = saved_literal_hgroup.build_hgroup_cache();
1840 let distance_hgroup = saved_distance_hgroup.build_hgroup_cache();
1841 let insert_copy_hgroup = saved_insert_copy_hgroup.build_hgroup_cache();
1842
1843 loop {
1844 match s.state {
1845 BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN => {
1846 if (!CheckInputAmount(safe, &s.br, 28)) { mark_unlikely();
1848 result = BrotliResult::NeedsMoreInput;
1849 break; }
1851 if (s.block_type_length_state.block_length[1] == 0) {
1852 mark_unlikely();
1853 if !DecodeCommandBlockSwitchInternal(safe, s, input) {
1854 result = BrotliResult::NeedsMoreInput;
1855 break; }
1857 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
1858 continue; }
1860 if (!ReadCommandInternal(safe, s, &mut i, input, &insert_copy_hgroup)) && safe {
1862 result = BrotliResult::NeedsMoreInput;
1863 break; }
1865 BROTLI_LOG!("[ProcessCommandsInternal] pos = %d insert = %d copy = %d distance_code = %d\n",
1866 pos, i, s.copy_length, s.distance_code);
1867 if (i == 0) {
1868 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
1869 continue; }
1871 s.meta_block_remaining_len -= i;
1872 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
1873 },
1874 BrotliRunningState::BROTLI_STATE_COMMAND_INNER => {
1875 if (s.trivial_literal_context != 0) {
1877 let mut bits : u32 = 0;
1878 let mut value : u32 = 0;
1879 let mut literal_htree = &literal_hgroup[s.literal_htree_index as usize];
1880 PreloadSymbol(safe, literal_htree, &mut s.br, &mut bits, &mut value, input);
1881 let mut inner_return : bool = false;
1882 loop {
1883 if (!CheckInputAmount(safe, &s.br, 28)) { result = BrotliResult::NeedsMoreInput;
1885 inner_return = true;
1886 break;
1887 }
1888 if (s.block_type_length_state.block_length[0] == 0) {
1889 mark_unlikely();
1890 if (!DecodeLiteralBlockSwitchInternal(safe,
1891 s,
1892 input)) && safe { result = BrotliResult::NeedsMoreInput;
1894 inner_return = true;
1895 break;
1896 }
1897 literal_htree = &literal_hgroup[s.literal_htree_index as usize];
1898 PreloadSymbol(safe, literal_htree, &mut s.br, &mut bits, &mut value, input);
1899 }
1900 if (!safe) {
1901 s.ringbuffer.slice_mut()[pos as usize] = ReadPreloadedSymbol(
1902 literal_htree, &mut s.br, &mut bits, &mut value, input) as u8;
1903 } else {
1904 let mut literal : u32 = 0;
1905 if (!SafeReadSymbol(literal_htree, &mut s.br, &mut literal, input)) {
1906 result = BrotliResult::NeedsMoreInput;
1907 inner_return = true;
1908 break;
1909 }
1910 s.ringbuffer.slice_mut()[pos as usize] = literal as u8;
1911 }
1912 s.block_type_length_state.block_length[0] -= 1;
1913 BROTLI_LOG_UINT!(s.literal_htree_index);
1914 BROTLI_LOG_ARRAY_INDEX!(s.ringbuffer.slice(), pos);
1915 pos += 1;
1916 if (pos == s.ringbuffer_size) {
1917 mark_unlikely();
1918 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER_WRITE;
1919 i -= 1;
1920 inner_return = true;
1921 break;
1922 }
1923 i -= 1;
1924 if i == 0 {
1925 break;
1926 }
1927 }
1928 if inner_return {
1929 break; }
1931 } else {
1932 let mut p1 = s.ringbuffer.slice()[((pos - 1) & s.ringbuffer_mask) as usize];
1933 let mut p2 = s.ringbuffer.slice()[((pos - 2) & s.ringbuffer_mask) as usize];
1934 let mut inner_return : bool = false;
1935 loop {
1936 if (!CheckInputAmount(safe, &s.br, 28)) { s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
1938 result = BrotliResult::NeedsMoreInput;
1939 inner_return = true;
1940 break;
1941 }
1942 if (s.block_type_length_state.block_length[0] == 0) {
1943 mark_unlikely();
1944 if (!DecodeLiteralBlockSwitchInternal(safe,
1945 s,
1946 input)) && safe {
1947 result = BrotliResult::NeedsMoreInput;
1948 inner_return = true;
1949 break;
1950 }
1951 }
1952 let context = s.context_lookup1[p1 as usize] | s.context_lookup2[p2 as usize];
1953 BROTLI_LOG_UINT!(context);
1954 let hc = &literal_hgroup[s.context_map.slice()[s.context_map_slice_index + context as usize]as usize];
1955 p2 = p1;
1956 if (!safe) {
1957 p1 = ReadSymbol(hc, &mut s.br, input) as u8;
1958 } else {
1959 let mut literal : u32 = 0;
1960 if (!SafeReadSymbol(hc, &mut s.br, &mut literal, input)) {
1961 result = BrotliResult::NeedsMoreInput;
1962 inner_return = true;
1963 break;
1964 }
1965 p1 = literal as u8;
1966 }
1967 s.ringbuffer.slice_mut()[pos as usize] = p1;
1968 s.block_type_length_state.block_length[0] -= 1;
1969 BROTLI_LOG_UINT!(s.context_map.slice()[s.context_map_slice_index as usize + context as usize]);
1970 BROTLI_LOG_ARRAY_INDEX!(s.ringbuffer.slice(), pos & s.ringbuffer_mask);
1971 pos += 1;
1972 if (pos == s.ringbuffer_size) {
1973 mark_unlikely();
1974 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER_WRITE;
1975 i -= 1;
1976 inner_return = true;
1977 break;
1978 }
1979 i -= 1;
1980 if i == 0 {
1981 break;
1982 }
1983 }
1984 if inner_return {
1985 break; }
1987 }
1988 if (s.meta_block_remaining_len <= 0) {
1989 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
1990 break; }
1992 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
1993 },
1994 BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS => {
1995 if s.distance_code >= 0 {
1996 s.dist_rb_idx -= 1;
1997 s.distance_code = s.dist_rb[(s.dist_rb_idx & 3) as usize]
1998 } else {
2000 if s.block_type_length_state.block_length[2] == 0 {
2001 mark_unlikely();
2002 if (!DecodeDistanceBlockSwitchInternal(safe, s, input)) && safe {
2003 result = BrotliResult::NeedsMoreInput;
2004 break; }
2006 }
2007 if (!ReadDistanceInternal(safe, s, input, &distance_hgroup)) && safe {
2008 result = BrotliResult::NeedsMoreInput;
2009 break; }
2011 }
2012 BROTLI_LOG!("[ProcessCommandsInternal] pos = %d distance = %d\n",
2014 pos, s.distance_code);
2015
2016 if (s.max_distance != s.max_backward_distance) {
2017 if (pos < s.max_backward_distance_minus_custom_dict_size) {
2018 s.max_distance = pos + s.custom_dict_size;
2019 } else {
2020 s.max_distance = s.max_backward_distance;
2021 }
2022 }
2023 i = s.copy_length;
2024 if (s.distance_code > s.max_distance) {
2027 if (i >= kBrotliMinDictionaryWordLength as i32 &&
2028 i <= kBrotliMaxDictionaryWordLength as i32) {
2029 let mut offset = kBrotliDictionaryOffsetsByLength[i as usize] as i32;
2030 let word_id = s.distance_code - s.max_distance - 1;
2031 let shift = kBrotliDictionarySizeBitsByLength[i as usize];
2032 let mask = bit_reader::BitMask(shift as u32) as i32;
2033 let word_idx = word_id & mask;
2034 let transform_idx = word_id >> shift;
2035 offset += word_idx * i;
2036 if (transform_idx < kNumTransforms) {
2037 let mut len = i;
2038 let word = &kBrotliDictionary[offset as usize .. (offset + len) as usize];
2039 if (transform_idx == 0) {
2040 s.ringbuffer.slice_mut()[pos as usize .. ((pos + len) as usize)].clone_from_slice(
2041 word);
2042 } else {
2043 len = TransformDictionaryWord(
2044 &mut s.ringbuffer.slice_mut()[pos as usize..], word, len, transform_idx);
2045 }
2046 pos += len;
2047 s.meta_block_remaining_len -= len;
2048 if (pos >= s.ringbuffer_size) {
2049 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1;
2051 break; }
2053 } else {
2054 BROTLI_LOG!("Invalid backward reference. pos: %d distance: %d len: %d bytes left: %d\n",
2055 pos, s.distance_code, i,
2056 s.meta_block_remaining_len);
2057 result = BROTLI_FAILURE();
2058 break; }
2060 } else {
2061 BROTLI_LOG!("Invalid backward reference. pos: %d distance: %d len: %d bytes left: %d\n", pos, s.distance_code, i,
2062 s.meta_block_remaining_len);
2063 result = BROTLI_FAILURE();
2064 break; }
2066 } else {
2067 s.dist_rb[(s.dist_rb_idx & 3) as usize] = s.distance_code;
2069 s.dist_rb_idx += 1;
2070 s.meta_block_remaining_len -= i;
2071 if (s.meta_block_remaining_len < 0) {
2072 mark_unlikely();
2073 BROTLI_LOG!("Invalid backward reference. pos: %d distance: %d len: %d bytes left: %d\n", pos, s.distance_code, i,
2074 s.meta_block_remaining_len);
2075 result = BROTLI_FAILURE();
2076 break; }
2078 let src_start = ((pos - s.distance_code) & s.ringbuffer_mask) as u32;
2083 let dst_start = pos as u32;
2084 let dst_end = pos as u32 + i as u32;
2085 let src_end = src_start + i as u32;
2086 memmove16(&mut s.ringbuffer.slice_mut(), dst_start, src_start);
2087 if (src_end > pos as u32 && dst_end > src_start) {
2090 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2091 continue; }
2093 if (dst_end >= s.ringbuffer_size as u32 || src_end >= s.ringbuffer_size as u32) {
2094 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2095 continue; }
2097 pos += i;
2098 if (i > 16) {
2099 if (i > 32) {
2100 memcpy_within_slice(s.ringbuffer.slice_mut(),
2101 dst_start as usize + 16,
2102 src_start as usize + 16,
2103 (i - 16) as usize);
2104 } else {
2105 memmove16(&mut s.ringbuffer.slice_mut(), dst_start + 16, src_start + 16);
2108 }
2109 }
2110 }
2111 if (s.meta_block_remaining_len <= 0) {
2112 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2114 break; } else {
2116 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
2117 continue; }
2119 },
2120 BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY => {
2121 let mut wrap_guard = s.ringbuffer_size - pos;
2122 let mut inner_return : bool = false;
2123 while i > 0 {
2124 i -= 1;
2125 s.ringbuffer.slice_mut()[pos as usize] =
2126 s.ringbuffer.slice()[((pos - s.distance_code) & s.ringbuffer_mask) as usize];
2127 pos += 1;
2128 wrap_guard -= 1;
2129 if (wrap_guard == 0) {
2130 mark_unlikely();
2131 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2;
2133 inner_return = true;
2134 break; }
2136 }
2137 if inner_return {
2138 mark_unlikely();
2139 break;
2140 }
2141 i -= 1;
2142 if (s.meta_block_remaining_len <= 0) {
2143 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2145 break; } else {
2147 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
2148 continue;
2149 }
2150 },
2151 _ => {
2152 result = BROTLI_FAILURE();
2153 break; },
2155 }
2156 }
2157 }
2158 s.pos = pos;
2159 s.loop_counter = i;
2160
2161 core::mem::replace(&mut s.literal_hgroup,
2162 core::mem::replace(&mut saved_literal_hgroup,
2163 HuffmanTreeGroup::<AllocU32, AllocHC>::default()));
2164
2165 core::mem::replace(&mut s.distance_hgroup,
2166 core::mem::replace(&mut saved_distance_hgroup,
2167 HuffmanTreeGroup::<AllocU32, AllocHC>::default()));
2168
2169 core::mem::replace(&mut s.insert_copy_hgroup,
2170 core::mem::replace(&mut saved_insert_copy_hgroup,
2171 HuffmanTreeGroup::<AllocU32, AllocHC>::default()));
2172
2173 return result;
2174}
2175
2176fn ProcessCommands<
2177 'a, AllocU8 : alloc::Allocator<u8>,
2178 AllocU32 : alloc::Allocator<u32>,
2179 AllocHC : alloc::Allocator<HuffmanCode> > (
2180 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> BrotliResult {
2181 return ProcessCommandsInternal(false, s, input);
2182}
2183
2184fn SafeProcessCommands<
2185 'a, AllocU8 : alloc::Allocator<u8>,
2186 AllocU32 : alloc::Allocator<u32>,
2187 AllocHC : alloc::Allocator<HuffmanCode> > (
2188 s : &mut BrotliState<AllocU8, AllocU32, AllocHC>, input : &[u8]) -> BrotliResult {
2189 return ProcessCommandsInternal(true, s, input);
2190}
2191
2192
2193
2194
2195pub fn BrotliDecompressStream<'a, AllocU8 : alloc::Allocator<u8>,
2196 AllocU32 : alloc::Allocator<u32>,
2197 AllocHC : alloc::Allocator<HuffmanCode>> (
2198 mut available_in : &mut usize, input_offset : &mut usize, xinput : &[u8], mut available_out : &mut usize, mut output_offset : &mut usize, mut output : &mut [u8],
2200 mut total_out : &mut usize, mut s : &mut BrotliState<AllocU8, AllocU32, AllocHC>)
2201 -> BrotliResult {
2202
2203 let mut result : BrotliResult = BrotliResult::ResultSuccess;
2204
2205 let mut saved_buffer : [u8; 8] = s.buffer.clone();
2206 let mut local_input : &[u8];
2207 if *available_in as u64 >= (1u64 << 32) {
2208 return BrotliResult::ResultFailure;
2209 }
2210 if *input_offset as u64 >= (1u64 << 32) {
2211 return BrotliResult::ResultFailure;
2212 }
2213 if s.buffer_length == 0 {
2214 local_input = xinput;
2215 s.br.avail_in = *available_in as u32;
2216 s.br.next_in = *input_offset as u32;
2217 } else {
2218 result = BrotliResult::NeedsMoreInput;
2219 let copy_len = core::cmp::min(saved_buffer.len() - s.buffer_length as usize, *available_in);
2220 if copy_len > 0 {
2221 saved_buffer[s.buffer_length as usize .. (s.buffer_length as usize + copy_len)].
2222 clone_from_slice(&xinput[*input_offset .. copy_len + *input_offset]);
2223 s.buffer[s.buffer_length as usize .. (s.buffer_length as usize + copy_len)].
2224 clone_from_slice(&xinput[*input_offset .. copy_len + *input_offset]);
2225 }
2226 local_input = &saved_buffer[..];
2227 s.br.next_in = 0;
2228 s.br.avail_in = s.buffer_length;
2229 }
2230 loop {
2231 match result {
2232 BrotliResult::ResultSuccess => {},
2233 _ => {
2234 match result {
2235 BrotliResult::NeedsMoreInput => {
2236 if s.ringbuffer.slice().len() != 0 {
2237 let _result = WriteRingBuffer(available_out, &mut output, &mut output_offset,
2238 &mut total_out, &mut s);
2239 }
2240 if s.buffer_length != 0 { if s.br.avail_in == 0 { s.buffer_length = 0;
2245 result = BrotliResult::ResultSuccess;
2247 local_input = xinput;
2248 s.br.avail_in = *available_in as u32;
2249 s.br.next_in = *input_offset as u32;
2250 continue;
2251 } else if *available_in != 0 {
2252 result = BrotliResult::ResultSuccess;
2255 let new_byte = xinput[*input_offset];
2256 s.buffer[s.buffer_length as usize] = new_byte;
2257 assert_eq!(saved_buffer[s.buffer_length as usize], new_byte);
2260 s.buffer_length += 1;
2261 s.br.avail_in = s.buffer_length;
2262 (*input_offset) += 1;
2263 (*available_in) -= 1;
2264 continue;
2267 }
2268 break;
2274 } else { *input_offset = s.br.next_in as usize;
2277 *available_in = s.br.avail_in as usize;
2278 while *available_in != 0 {
2279 s.buffer[s.buffer_length as usize] = xinput[*input_offset];
2280 s.buffer_length += 1;
2281 (*input_offset)+=1;
2282 (*available_in)-=1;
2283 }
2284 break;
2285 }
2286 },
2288 _ => {
2289 if s.buffer_length != 0 {
2291 s.buffer_length = 0;
2294 } else {
2295 bit_reader::BrotliBitReaderUnload(&mut s.br);
2299 *available_in = s.br.avail_in as usize;
2300 *input_offset = s.br.next_in as usize;
2301 }
2302 },
2303 }
2304 break;
2305 },
2306 }
2307 loop { match s.state {
2309 BrotliRunningState::BROTLI_STATE_UNINITED => {
2310 if (!bit_reader::BrotliWarmupBitReader(&mut s.br, local_input)) {
2312 result = BrotliResult::NeedsMoreInput;
2313 break;
2314 }
2315 s.window_bits = DecodeWindowBits(&mut s.br); BROTLI_LOG_UINT!(s.window_bits);
2318 if (s.window_bits == 9) {
2319 result = BROTLI_FAILURE();
2321 break;
2322 }
2323 s.max_backward_distance = (1 << s.window_bits) - 16;
2324 s.max_backward_distance_minus_custom_dict_size =
2325 s.max_backward_distance - s.custom_dict_size;
2326
2327 s.block_type_length_state.block_type_trees
2329 = s.alloc_hc.alloc_cell(3 * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
2330 if (s.block_type_length_state.block_type_trees.slice().len() == 0) {
2331 result = BROTLI_FAILURE();
2332 break;
2333 }
2334 s.block_type_length_state.block_len_trees
2335 = s.alloc_hc.alloc_cell(3 * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as usize);
2336
2337 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN;
2338 },
2340 BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN => {
2341 s.BrotliStateMetablockBegin();
2342 BROTLI_LOG_UINT!(s.pos);
2343 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER;
2344 },
2346 BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER => {
2347 result = DecodeMetaBlockLength(&mut s, local_input); match result {
2349 BrotliResult::ResultSuccess => {},
2350 _ => break,
2351 }
2352 BROTLI_LOG_UINT!(s.is_last_metablock);
2353 BROTLI_LOG_UINT!(s.meta_block_remaining_len);
2354 BROTLI_LOG_UINT!(s.is_metadata);
2355 BROTLI_LOG_UINT!(s.is_uncompressed);
2356 if (s.is_metadata != 0 || s.is_uncompressed != 0) {
2357 if (!bit_reader::BrotliJumpToByteBoundary(&mut s.br)) {
2358 result = BROTLI_FAILURE();
2359 break;
2360 }
2361 }
2362 if (s.is_metadata != 0) {
2363 s.state = BrotliRunningState::BROTLI_STATE_METADATA;
2364 break;
2365 }
2366 if (s.meta_block_remaining_len == 0) {
2367 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2368 break;
2369 }
2370 if (s.ringbuffer.slice().len() == 0) {
2371 if (!BrotliAllocateRingBuffer(&mut s, local_input)) {
2372 result = BROTLI_FAILURE();
2373 break;
2374 }
2375 }
2376 if (s.is_uncompressed != 0) {
2377 s.state = BrotliRunningState::BROTLI_STATE_UNCOMPRESSED;
2378 break;
2379 }
2380 s.loop_counter = 0;
2381 s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_0;
2382 break;
2383 },
2384 BrotliRunningState::BROTLI_STATE_UNCOMPRESSED => {
2385 let mut _bytes_copied = s.meta_block_remaining_len;
2386 result = CopyUncompressedBlockToOutput(
2387 &mut available_out, &mut output, &mut output_offset, &mut total_out, &mut s, local_input);
2388 _bytes_copied -= s.meta_block_remaining_len;
2389 match result {
2390 BrotliResult::ResultSuccess => {},
2391 _ => break,
2392 }
2393 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2394 break;
2395 },
2396 BrotliRunningState::BROTLI_STATE_METADATA => {
2397 while s.meta_block_remaining_len > 0 {
2398 let mut bits = 0u32;
2399 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 8, &mut bits, local_input)) {
2401 result = BrotliResult::NeedsMoreInput;
2402 break;
2403 }
2404 s.meta_block_remaining_len -= 1;
2405 }
2406 match result {
2407 BrotliResult::ResultSuccess => s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE,
2408 _ => {},
2409 }
2410 break;
2411 },
2412 BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_0 => {
2413 if (s.loop_counter >= 3) {
2414 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER_2;
2415 break;
2416 }
2417 result = DecodeVarLenUint8(&mut s.substate_decode_uint8, &mut s.br, &mut s.block_type_length_state.num_block_types[s.loop_counter as usize], local_input);
2419 match result {
2420 BrotliResult::ResultSuccess => {},
2421 _ => break,
2422 }
2423 s.block_type_length_state.num_block_types[s.loop_counter as usize] += 1;
2424 BROTLI_LOG_UINT!(s.block_type_length_state.num_block_types[s.loop_counter as usize]);
2425 if (s.block_type_length_state.num_block_types[s.loop_counter as usize] < 2) {
2426 s.loop_counter+=1;
2427 break;
2428 }
2429 s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_1;
2430 },
2432 BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_1 => {
2433 let tree_offset = s.loop_counter * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as i32;
2434 let mut new_huffman_table = mem::replace(&mut s.block_type_length_state.block_type_trees,
2435 AllocHC::AllocatedMemory::default());
2436 result
2437 = ReadHuffmanCode(s.block_type_length_state.num_block_types[s.loop_counter as usize] +2,
2438 new_huffman_table.slice_mut(), tree_offset as usize, None, &mut s, local_input);
2439 mem::replace(&mut s.block_type_length_state.block_type_trees,
2440 new_huffman_table);
2441 match result {
2442 BrotliResult::ResultSuccess => {},
2443 _ => break,
2444 }
2445 s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_2;
2446 },
2448 BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_2 => {
2449 let tree_offset = s.loop_counter * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as i32;
2450 let mut new_huffman_table = mem::replace(&mut s.block_type_length_state.block_len_trees,
2451 AllocHC::AllocatedMemory::default());
2452 result = ReadHuffmanCode(kNumBlockLengthCodes,
2453 new_huffman_table.slice_mut(), tree_offset as usize, None, &mut s, local_input);
2454 mem::replace(&mut s.block_type_length_state.block_len_trees,
2455 new_huffman_table);
2456 match result {
2457 BrotliResult::ResultSuccess => {},
2458 _ => break,
2459 }
2460 s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_3;
2461 },
2463 BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_3 => {
2464 let tree_offset = s.loop_counter * huffman::BROTLI_HUFFMAN_MAX_TABLE_SIZE as i32;
2465 let mut block_length_out : u32 = 0;
2466 let index_ret = SafeReadBlockLengthIndex(&s.block_type_length_state.substate_read_block_length,
2467 s.block_type_length_state.block_length_index,
2468 &s.block_type_length_state.block_len_trees.slice()[tree_offset as usize ..],
2469 &mut s.br, local_input);
2470
2471 if !SafeReadBlockLengthFromIndex(&mut s.block_type_length_state,
2472 &mut s.br, &mut block_length_out, index_ret, local_input) {
2473 result = BrotliResult::NeedsMoreInput;
2474 break;
2475 }
2476 s.block_type_length_state.block_length[s.loop_counter as usize] = block_length_out;
2477 BROTLI_LOG_UINT!(s.block_type_length_state.block_length[s.loop_counter as usize]);
2478 s.loop_counter += 1;
2479 s.state = BrotliRunningState::BROTLI_STATE_HUFFMAN_CODE_0;
2480 break;
2481 }
2482 BrotliRunningState::BROTLI_STATE_METABLOCK_HEADER_2 => {
2483 let mut bits : u32 = 0;
2484 if (!bit_reader::BrotliSafeReadBits(&mut s.br, 6, &mut bits, local_input)) {
2485 result = BrotliResult::NeedsMoreInput;
2486 break;
2487 }
2488 s.distance_postfix_bits = bits & bit_reader::BitMask(2);
2489 bits >>= 2;
2490 s.num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
2491 (bits << s.distance_postfix_bits);
2492 BROTLI_LOG_UINT!(s.num_direct_distance_codes);
2493 BROTLI_LOG_UINT!(s.distance_postfix_bits);
2494 s.distance_postfix_mask = bit_reader::BitMask(s.distance_postfix_bits) as i32;
2495 s.context_modes = s.alloc_u8.alloc_cell(s.block_type_length_state.num_block_types[0] as usize);
2496 if (s.context_modes.slice().len() == 0) {
2497 result = BROTLI_FAILURE();
2498 break;
2499 }
2500 s.loop_counter = 0;
2501 s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MODES;
2502 },
2504 BrotliRunningState::BROTLI_STATE_CONTEXT_MODES => {
2505 result = ReadContextModes(&mut s, local_input);
2506 match result {
2507 BrotliResult::ResultSuccess => {},
2508 _ => break,
2509 }
2510 s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1;
2511 },
2513 BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_1 => {
2514 result = DecodeContextMap((s.block_type_length_state.num_block_types[0] as usize) << kLiteralContextBits as usize,
2515 false, &mut s, local_input);
2516 match result {
2517 BrotliResult::ResultSuccess => {},
2518 _ => break,
2519 }
2520 let mut is_trivial_context = 1;
2521 let mut j : usize = 0;
2522 for context_map_item in s.context_map.slice()[0 .. (s.block_type_length_state.num_block_types[0] as usize) << (kLiteralContextBits as usize)].iter() {
2523 if (*context_map_item != (j >> kLiteralContextBits) as u8) {
2524 is_trivial_context = 0;
2525 break;
2526 }
2527 j += 1;
2528 }
2529 s.trivial_literal_context = is_trivial_context;
2530 s.state = BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2;
2531 },
2533 BrotliRunningState::BROTLI_STATE_CONTEXT_MAP_2 => {
2534 {
2535 let num_distance_codes : u32 =
2536 s.num_direct_distance_codes + (48u32 << s.distance_postfix_bits);
2537 result = DecodeContextMap(
2538 (s.block_type_length_state.num_block_types[2] as usize) << kDistanceContextBits as usize,
2539 true, s, local_input);
2540 match result {
2541 BrotliResult::ResultSuccess => {},
2542 _ => break,
2543 }
2544 s.literal_hgroup.init(&mut s.alloc_u32,
2545 &mut s.alloc_hc,
2546 kNumLiteralCodes, s.num_literal_htrees as u16);
2547 s.insert_copy_hgroup.init(&mut s.alloc_u32,
2548 &mut s.alloc_hc,
2549 kNumInsertAndCopyCodes, s.block_type_length_state.num_block_types[1] as u16);
2550 s.distance_hgroup.init(&mut s.alloc_u32,
2551 &mut s.alloc_hc,
2552 num_distance_codes as u16, s.num_dist_htrees as u16);
2553 if (s.literal_hgroup.codes.slice().len() == 0 ||
2554 s.insert_copy_hgroup.codes.slice().len() == 0 ||
2555 s.distance_hgroup.codes.slice().len() == 0) {
2556 return BROTLI_FAILURE();
2557 }
2558 }
2559 s.loop_counter = 0;
2560 s.state = BrotliRunningState::BROTLI_STATE_TREE_GROUP;
2561 },
2563 BrotliRunningState::BROTLI_STATE_TREE_GROUP => {
2564 result = HuffmanTreeGroupDecode(s.loop_counter, &mut s, local_input);
2565 match result {
2566 BrotliResult::ResultSuccess => {},
2567 _ => break,
2568 }
2569 s.loop_counter += 1;
2570 if (s.loop_counter >= 3) {
2571 let context_mode = s.context_modes.slice()[s.block_type_length_state.block_type_rb[1] as usize];
2572 s.context_map_slice_index = 0;
2573 s.dist_context_map_slice_index = 0;
2574 s.context_lookup1 =
2575 &kContextLookup[kContextLookupOffsets[context_mode as usize] as usize ..];
2576 s.context_lookup2 =
2577 &kContextLookup[kContextLookupOffsets[context_mode as usize + 1] as usize ..];
2578 s.htree_command_index = 0;
2579 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
2581 }
2582 break;
2583 },
2584 BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN
2585 | BrotliRunningState::BROTLI_STATE_COMMAND_INNER
2586 | BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS
2587 | BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY => {
2588 result = ProcessCommands(s, local_input);
2589 match result {
2590 BrotliResult::NeedsMoreInput => result = SafeProcessCommands(s, local_input),
2591 _ => {},
2592 }
2593 break;
2594 },
2595 BrotliRunningState::BROTLI_STATE_COMMAND_INNER_WRITE
2596 | BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1
2597 | BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2 => {
2598 result = WriteRingBuffer(&mut available_out, &mut output, &mut output_offset, &mut total_out, &mut s);
2599 match result {
2600 BrotliResult::ResultSuccess => {},
2601 _ => break,
2602 }
2603 s.pos -= s.ringbuffer_size;
2604 s.rb_roundtrips += 1;
2605 s.max_distance = s.max_backward_distance;
2606 match s.state {
2607 BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_1 => {
2608 memcpy_within_slice(s.ringbuffer.slice_mut(),
2620 0,
2621 s.ringbuffer_size as usize,
2622 s.pos as usize);
2623 if (s.meta_block_remaining_len <= 0) {
2625 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2627 } else {
2628 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_BEGIN;
2629 }
2630 break;
2631 },
2632 BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRITE_2 => {
2633 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_WRAP_COPY;
2634 },
2635 _ => { if (s.loop_counter == 0) {
2637 if (s.meta_block_remaining_len <= 0) {
2638 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_DONE;
2639 } else {
2640 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
2641 }
2642 break;
2643 }
2644 s.state = BrotliRunningState::BROTLI_STATE_COMMAND_INNER;
2645 },
2646 }
2647 break;
2648 },
2649 BrotliRunningState::BROTLI_STATE_METABLOCK_DONE => {
2650 s.BrotliStateCleanupAfterMetablock();
2651 if (s.is_last_metablock == 0) {
2652 s.state = BrotliRunningState::BROTLI_STATE_METABLOCK_BEGIN;
2653 break;
2654 }
2655 if (!bit_reader::BrotliJumpToByteBoundary(&mut s.br)) {
2656 result = BROTLI_FAILURE();
2657 }
2658 if (s.buffer_length == 0) {
2659 bit_reader::BrotliBitReaderUnload(&mut s.br);
2660 *available_in = s.br.avail_in as usize;
2661 *input_offset = s.br.next_in as usize;
2662 }
2663 s.state = BrotliRunningState::BROTLI_STATE_DONE;
2664 },
2666 BrotliRunningState::BROTLI_STATE_DONE => {
2667 if (s.ringbuffer.slice().len() != 0) {
2668 result = WriteRingBuffer(&mut available_out, &mut output, &mut output_offset, &mut total_out, &mut s);
2669 match result {
2670 BrotliResult::ResultSuccess => {},
2671 _ => break,
2672 }
2673 }
2674 return result;
2675 }
2676 }
2677 }
2678 }
2679
2680 return result;
2681}