OLD | NEW |
1 /* Copyright 2013 Google Inc. All Rights Reserved. | 1 /* Copyright 2013 Google Inc. All Rights Reserved. |
2 | 2 |
3 Licensed under the Apache License, Version 2.0 (the "License"); | 3 Licensed under the Apache License, Version 2.0 (the "License"); |
4 you may not use this file except in compliance with the License. | 4 you may not use this file except in compliance with the License. |
5 You may obtain a copy of the License at | 5 You may obtain a copy of the License at |
6 | 6 |
7 http://www.apache.org/licenses/LICENSE-2.0 | 7 http://www.apache.org/licenses/LICENSE-2.0 |
8 | 8 |
9 Unless required by applicable law or agreed to in writing, software | 9 Unless required by applicable law or agreed to in writing, software |
10 distributed under the License is distributed on an "AS IS" BASIS, | 10 distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 int nbits = (int)BrotliReadBits(br, 3); | 79 int nbits = (int)BrotliReadBits(br, 3); |
80 if (nbits == 0) { | 80 if (nbits == 0) { |
81 return 1; | 81 return 1; |
82 } else { | 82 } else { |
83 return (int)BrotliReadBits(br, nbits) + (1 << nbits); | 83 return (int)BrotliReadBits(br, nbits) + (1 << nbits); |
84 } | 84 } |
85 } | 85 } |
86 return 0; | 86 return 0; |
87 } | 87 } |
88 | 88 |
89 static void DecodeMetaBlockLength(BrotliBitReader* br, | 89 /* Advances the bit reader position to the next byte boundary and verifies |
90 int* meta_block_length, | 90 that any skipped bits are set to zero. */ |
91 int* input_end, | 91 static BROTLI_INLINE int JumpToByteBoundary(BrotliBitReader* br) { |
92 int* is_uncompressed) { | 92 uint32_t new_bit_pos = (br->bit_pos_ + 7) & (uint32_t)(~7UL); |
| 93 uint32_t pad_bits = BrotliReadBits(br, (int)(new_bit_pos - br->bit_pos_)); |
| 94 return pad_bits == 0; |
| 95 } |
| 96 |
| 97 static int DecodeMetaBlockLength(BrotliBitReader* br, |
| 98 int* meta_block_length, |
| 99 int* input_end, |
| 100 int* is_metadata, |
| 101 int* is_uncompressed) { |
93 int size_nibbles; | 102 int size_nibbles; |
| 103 int size_bytes; |
94 int i; | 104 int i; |
95 *input_end = (int)BrotliReadBits(br, 1); | 105 *input_end = (int)BrotliReadBits(br, 1); |
96 *meta_block_length = 0; | 106 *meta_block_length = 0; |
97 *is_uncompressed = 0; | 107 *is_uncompressed = 0; |
| 108 *is_metadata = 0; |
98 if (*input_end && BrotliReadBits(br, 1)) { | 109 if (*input_end && BrotliReadBits(br, 1)) { |
99 return; | 110 return 1; |
100 } | 111 } |
101 size_nibbles = (int)BrotliReadBits(br, 2) + 4; | 112 size_nibbles = (int)BrotliReadBits(br, 2) + 4; |
102 for (i = 0; i < size_nibbles; ++i) { | 113 if (size_nibbles == 7) { |
103 *meta_block_length |= (int)BrotliReadBits(br, 4) << (i * 4); | 114 *is_metadata = 1; |
| 115 /* Verify reserved bit. */ |
| 116 if (BrotliReadBits(br, 1) != 0) { |
| 117 return 0; |
| 118 } |
| 119 size_bytes = (int)BrotliReadBits(br, 2); |
| 120 if (size_bytes == 0) { |
| 121 return 1; |
| 122 } |
| 123 for (i = 0; i < size_bytes; ++i) { |
| 124 int next_byte = (int)BrotliReadBits(br, 8); |
| 125 if (i + 1 == size_bytes && size_bytes > 1 && next_byte == 0) { |
| 126 return 0; |
| 127 } |
| 128 *meta_block_length |= next_byte << (i * 8); |
| 129 } |
| 130 } else { |
| 131 for (i = 0; i < size_nibbles; ++i) { |
| 132 int next_nibble = (int)BrotliReadBits(br, 4); |
| 133 if (i + 1 == size_nibbles && size_nibbles > 4 && next_nibble == 0) { |
| 134 return 0; |
| 135 } |
| 136 *meta_block_length |= next_nibble << (i * 4); |
| 137 } |
104 } | 138 } |
105 ++(*meta_block_length); | 139 ++(*meta_block_length); |
106 if (!*input_end) { | 140 if (!*input_end && !*is_metadata) { |
107 *is_uncompressed = (int)BrotliReadBits(br, 1); | 141 *is_uncompressed = (int)BrotliReadBits(br, 1); |
108 } | 142 } |
| 143 return 1; |
109 } | 144 } |
110 | 145 |
111 /* Decodes the next Huffman code from bit-stream. */ | 146 /* Decodes the next Huffman code from bit-stream. */ |
112 static BROTLI_INLINE int ReadSymbol(const HuffmanCode* table, | 147 static BROTLI_INLINE int ReadSymbol(const HuffmanCode* table, |
113 BrotliBitReader* br) { | 148 BrotliBitReader* br) { |
114 int nbits; | 149 int nbits; |
115 BrotliFillBitWindow(br); | 150 BrotliFillBitWindow(br); |
116 table += (int)(br->val_ >> br->bit_pos_) & HUFFMAN_TABLE_MASK; | 151 table += (int)(br->val_ >> br->bit_pos_) & HUFFMAN_TABLE_MASK; |
117 nbits = table->bits - HUFFMAN_TABLE_BITS; | 152 nbits = table->bits - HUFFMAN_TABLE_BITS; |
118 if (nbits > 0) { | 153 if (nbits > 0) { |
(...skipping 30 matching lines...) Expand all Loading... |
149 PrintUcharVector(code_length_code_lengths, CODE_LENGTH_CODES); | 184 PrintUcharVector(code_length_code_lengths, CODE_LENGTH_CODES); |
150 return BROTLI_RESULT_ERROR; | 185 return BROTLI_RESULT_ERROR; |
151 } | 186 } |
152 s->sub_state[1] = BROTLI_STATE_SUB_HUFFMAN_LENGTH_SYMBOLS; | 187 s->sub_state[1] = BROTLI_STATE_SUB_HUFFMAN_LENGTH_SYMBOLS; |
153 /* No break, continue to next state. */ | 188 /* No break, continue to next state. */ |
154 case BROTLI_STATE_SUB_HUFFMAN_LENGTH_SYMBOLS: | 189 case BROTLI_STATE_SUB_HUFFMAN_LENGTH_SYMBOLS: |
155 while (s->symbol < num_symbols && s->space > 0) { | 190 while (s->symbol < num_symbols && s->space > 0) { |
156 const HuffmanCode* p = s->table; | 191 const HuffmanCode* p = s->table; |
157 uint8_t code_len; | 192 uint8_t code_len; |
158 if (!BrotliReadMoreInput(br)) { | 193 if (!BrotliReadMoreInput(br)) { |
159 return BROTLI_RESULT_PARTIAL; | 194 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
160 } | 195 } |
161 BrotliFillBitWindow(br); | 196 BrotliFillBitWindow(br); |
162 p += (br->val_ >> br->bit_pos_) & 31; | 197 p += (br->val_ >> br->bit_pos_) & 31; |
163 br->bit_pos_ += p->bits; | 198 br->bit_pos_ += p->bits; |
164 code_len = (uint8_t)p->value; | 199 code_len = (uint8_t)p->value; |
165 if (code_len < kCodeLengthRepeatCode) { | 200 if (code_len < kCodeLengthRepeatCode) { |
166 s->repeat = 0; | 201 s->repeat = 0; |
167 code_lengths[s->symbol++] = code_len; | 202 code_lengths[s->symbol++] = code_len; |
168 if (code_len != 0) { | 203 if (code_len != 0) { |
169 s->prev_code_len = code_len; | 204 s->prev_code_len = code_len; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 int* opt_table_size, | 252 int* opt_table_size, |
218 BrotliState* s) { | 253 BrotliState* s) { |
219 BrotliBitReader* br = &s->br; | 254 BrotliBitReader* br = &s->br; |
220 BrotliResult result = BROTLI_RESULT_SUCCESS; | 255 BrotliResult result = BROTLI_RESULT_SUCCESS; |
221 int table_size = 0; | 256 int table_size = 0; |
222 /* State machine */ | 257 /* State machine */ |
223 for (;;) { | 258 for (;;) { |
224 switch(s->sub_state[1]) { | 259 switch(s->sub_state[1]) { |
225 case BROTLI_STATE_SUB_NONE: | 260 case BROTLI_STATE_SUB_NONE: |
226 if (!BrotliReadMoreInput(br)) { | 261 if (!BrotliReadMoreInput(br)) { |
227 return BROTLI_RESULT_PARTIAL; | 262 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
228 } | 263 } |
229 s->code_lengths = | 264 s->code_lengths = |
230 (uint8_t*)BrotliSafeMalloc((uint64_t)alphabet_size, | 265 (uint8_t*)BrotliSafeMalloc((uint64_t)alphabet_size, |
231 sizeof(*s->code_lengths)); | 266 sizeof(*s->code_lengths)); |
232 if (s->code_lengths == NULL) { | 267 if (s->code_lengths == NULL) { |
233 return BROTLI_RESULT_ERROR; | 268 return BROTLI_RESULT_ERROR; |
234 } | 269 } |
235 /* simple_code_or_skip is used as follows: | 270 /* simple_code_or_skip is used as follows: |
236 1 for simple code; | 271 1 for simple code; |
237 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ | 272 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ |
238 s->simple_code_or_skip = (int)BrotliReadBits(br, 2); | 273 s->simple_code_or_skip = (int)BrotliReadBits(br, 2); |
239 BROTLI_LOG_UINT(s->simple_code_or_skip); | 274 BROTLI_LOG_UINT(s->simple_code_or_skip); |
240 if (s->simple_code_or_skip == 1) { | 275 if (s->simple_code_or_skip == 1) { |
241 /* Read symbols, codes & code lengths directly. */ | 276 /* Read symbols, codes & code lengths directly. */ |
242 int i; | 277 int i; |
243 int max_bits_counter = alphabet_size - 1; | 278 int max_bits_counter = alphabet_size - 1; |
244 int max_bits = 0; | 279 int max_bits = 0; |
245 int symbols[4] = { 0 }; | 280 int symbols[4] = { 0 }; |
246 const int num_symbols = (int)BrotliReadBits(br, 2) + 1; | 281 const int num_symbols = (int)BrotliReadBits(br, 2) + 1; |
247 while (max_bits_counter) { | 282 while (max_bits_counter) { |
248 max_bits_counter >>= 1; | 283 max_bits_counter >>= 1; |
249 ++max_bits; | 284 ++max_bits; |
250 } | 285 } |
251 memset(s->code_lengths, 0, (size_t)alphabet_size); | 286 memset(s->code_lengths, 0, (size_t)alphabet_size); |
252 for (i = 0; i < num_symbols; ++i) { | 287 for (i = 0; i < num_symbols; ++i) { |
253 symbols[i] = (int)BrotliReadBits(br, max_bits) % alphabet_size; | 288 symbols[i] = (int)BrotliReadBits(br, max_bits); |
| 289 if (symbols[i] >= alphabet_size) { |
| 290 return BROTLI_RESULT_ERROR; |
| 291 } |
254 s->code_lengths[symbols[i]] = 2; | 292 s->code_lengths[symbols[i]] = 2; |
255 } | 293 } |
256 s->code_lengths[symbols[0]] = 1; | 294 s->code_lengths[symbols[0]] = 1; |
257 switch (num_symbols) { | 295 switch (num_symbols) { |
258 case 1: | 296 case 1: |
259 break; | 297 break; |
260 case 3: | 298 case 3: |
261 if ((symbols[0] == symbols[1]) || | 299 if ((symbols[0] == symbols[1]) || |
262 (symbols[0] == symbols[2]) || | 300 (symbols[0] == symbols[2]) || |
263 (symbols[1] == symbols[2])) { | 301 (symbols[1] == symbols[2])) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 if (code < NUM_DISTANCE_SHORT_CODES) { | 406 if (code < NUM_DISTANCE_SHORT_CODES) { |
369 index += kDistanceShortCodeIndexOffset[code]; | 407 index += kDistanceShortCodeIndexOffset[code]; |
370 index &= 3; | 408 index &= 3; |
371 val = ringbuffer[index] + kDistanceShortCodeValueOffset[code]; | 409 val = ringbuffer[index] + kDistanceShortCodeValueOffset[code]; |
372 } else { | 410 } else { |
373 val = code - NUM_DISTANCE_SHORT_CODES + 1; | 411 val = code - NUM_DISTANCE_SHORT_CODES + 1; |
374 } | 412 } |
375 return val; | 413 return val; |
376 } | 414 } |
377 | 415 |
378 static void MoveToFront(uint8_t* v, uint8_t index) { | |
379 uint8_t value = v[index]; | |
380 uint8_t i = index; | |
381 for (; i; --i) v[i] = v[i - 1]; | |
382 v[0] = value; | |
383 } | |
384 | |
385 static void InverseMoveToFrontTransform(uint8_t* v, int v_len) { | 416 static void InverseMoveToFrontTransform(uint8_t* v, int v_len) { |
386 uint8_t mtf[256]; | 417 uint8_t mtf[256]; |
387 int i; | 418 int i; |
388 for (i = 0; i < 256; ++i) { | 419 for (i = 0; i < 256; ++i) { |
389 mtf[i] = (uint8_t)i; | 420 mtf[i] = (uint8_t)i; |
390 } | 421 } |
391 for (i = 0; i < v_len; ++i) { | 422 for (i = 0; i < v_len; ++i) { |
392 uint8_t index = v[i]; | 423 uint8_t index = v[i]; |
393 v[i] = mtf[index]; | 424 uint8_t value = mtf[index]; |
394 if (index) MoveToFront(mtf, index); | 425 v[i] = value; |
| 426 for (; index; --index) { |
| 427 mtf[index] = mtf[index - 1]; |
| 428 } |
| 429 mtf[0] = value; |
395 } | 430 } |
396 } | 431 } |
397 | 432 |
398 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, | 433 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, |
399 BrotliState* s) { | 434 BrotliState* s) { |
400 switch (s->sub_state[0]) { | 435 switch (s->sub_state[0]) { |
401 case BROTLI_STATE_SUB_NONE: | 436 case BROTLI_STATE_SUB_NONE: |
402 s->next = group->codes; | 437 s->next = group->codes; |
403 s->htree_index = 0; | 438 s->htree_index = 0; |
404 s->sub_state[0] = BROTLI_STATE_SUB_TREE_GROUP; | 439 s->sub_state[0] = BROTLI_STATE_SUB_TREE_GROUP; |
(...skipping 24 matching lines...) Expand all Loading... |
429 int* num_htrees, | 464 int* num_htrees, |
430 uint8_t** context_map, | 465 uint8_t** context_map, |
431 BrotliState* s) { | 466 BrotliState* s) { |
432 BrotliBitReader* br = &s->br; | 467 BrotliBitReader* br = &s->br; |
433 BrotliResult result = BROTLI_RESULT_SUCCESS; | 468 BrotliResult result = BROTLI_RESULT_SUCCESS; |
434 int use_rle_for_zeros; | 469 int use_rle_for_zeros; |
435 | 470 |
436 switch(s->sub_state[0]) { | 471 switch(s->sub_state[0]) { |
437 case BROTLI_STATE_SUB_NONE: | 472 case BROTLI_STATE_SUB_NONE: |
438 if (!BrotliReadMoreInput(br)) { | 473 if (!BrotliReadMoreInput(br)) { |
439 return BROTLI_RESULT_PARTIAL; | 474 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
440 } | 475 } |
441 *num_htrees = DecodeVarLenUint8(br) + 1; | 476 *num_htrees = DecodeVarLenUint8(br) + 1; |
442 | 477 |
443 s->context_index = 0; | 478 s->context_index = 0; |
444 | 479 |
445 BROTLI_LOG_UINT(context_map_size); | 480 BROTLI_LOG_UINT(context_map_size); |
446 BROTLI_LOG_UINT(*num_htrees); | 481 BROTLI_LOG_UINT(*num_htrees); |
447 | 482 |
448 *context_map = (uint8_t*)malloc((size_t)context_map_size); | 483 *context_map = (uint8_t*)malloc((size_t)context_map_size); |
449 if (*context_map == 0) { | 484 if (*context_map == 0) { |
(...skipping 20 matching lines...) Expand all Loading... |
470 case BROTLI_STATE_SUB_CONTEXT_MAP_HUFFMAN: | 505 case BROTLI_STATE_SUB_CONTEXT_MAP_HUFFMAN: |
471 result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix, | 506 result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix, |
472 s->context_map_table, NULL, s); | 507 s->context_map_table, NULL, s); |
473 if (result != BROTLI_RESULT_SUCCESS) return result; | 508 if (result != BROTLI_RESULT_SUCCESS) return result; |
474 s->sub_state[0] = BROTLI_STATE_SUB_CONTEXT_MAPS; | 509 s->sub_state[0] = BROTLI_STATE_SUB_CONTEXT_MAPS; |
475 /* No break, continue to next state. */ | 510 /* No break, continue to next state. */ |
476 case BROTLI_STATE_SUB_CONTEXT_MAPS: | 511 case BROTLI_STATE_SUB_CONTEXT_MAPS: |
477 while (s->context_index < context_map_size) { | 512 while (s->context_index < context_map_size) { |
478 int code; | 513 int code; |
479 if (!BrotliReadMoreInput(br)) { | 514 if (!BrotliReadMoreInput(br)) { |
480 return BROTLI_RESULT_PARTIAL; | 515 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
481 } | 516 } |
482 code = ReadSymbol(s->context_map_table, br); | 517 code = ReadSymbol(s->context_map_table, br); |
483 if (code == 0) { | 518 if (code == 0) { |
484 (*context_map)[s->context_index] = 0; | 519 (*context_map)[s->context_index] = 0; |
485 ++s->context_index; | 520 ++s->context_index; |
486 } else if (code <= s->max_run_length_prefix) { | 521 } else if (code <= s->max_run_length_prefix) { |
487 int reps = 1 + (1 << code) + (int)BrotliReadBits(br, code); | 522 int reps = 1 + (1 << code) + (int)BrotliReadBits(br, code); |
488 while (--reps) { | 523 while (--reps) { |
489 if (s->context_index >= context_map_size) { | 524 if (s->context_index >= context_map_size) { |
490 return BROTLI_RESULT_ERROR; | 525 return BROTLI_RESULT_ERROR; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 | 640 |
606 BrotliResult CopyUncompressedBlockToOutput(BrotliOutput output, | 641 BrotliResult CopyUncompressedBlockToOutput(BrotliOutput output, |
607 int pos, | 642 int pos, |
608 BrotliState* s) { | 643 BrotliState* s) { |
609 const int rb_size = s->ringbuffer_mask + 1; | 644 const int rb_size = s->ringbuffer_mask + 1; |
610 uint8_t* ringbuffer_end = s->ringbuffer + rb_size; | 645 uint8_t* ringbuffer_end = s->ringbuffer + rb_size; |
611 int rb_pos = pos & s->ringbuffer_mask; | 646 int rb_pos = pos & s->ringbuffer_mask; |
612 int br_pos = s->br.pos_ & BROTLI_IBUF_MASK; | 647 int br_pos = s->br.pos_ & BROTLI_IBUF_MASK; |
613 uint32_t remaining_bits; | 648 uint32_t remaining_bits; |
614 int num_read; | 649 int num_read; |
| 650 int num_written; |
615 | 651 |
616 /* State machine */ | 652 /* State machine */ |
617 for (;;) { | 653 for (;;) { |
618 switch (s->sub_state[0]) { | 654 switch (s->sub_state[0]) { |
619 case BROTLI_STATE_SUB_NONE: | 655 case BROTLI_STATE_SUB_NONE: |
620 /* For short lengths copy byte-by-byte */ | 656 /* For short lengths copy byte-by-byte */ |
621 if (s->meta_block_remaining_len < 8 || s->br.bit_pos_ + | 657 if (s->meta_block_remaining_len < 8 || s->br.bit_pos_ + |
622 (uint32_t)(s->meta_block_remaining_len << 3) < s->br.bit_end_pos_) { | 658 (uint32_t)(s->meta_block_remaining_len << 3) < s->br.bit_end_pos_) { |
623 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_SHORT; | 659 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_SHORT; |
624 break; | 660 break; |
(...skipping 24 matching lines...) Expand all Loading... |
649 memcpy(&s->ringbuffer[rb_pos], &s->br.buf_[br_pos], (size_t)tail); | 685 memcpy(&s->ringbuffer[rb_pos], &s->br.buf_[br_pos], (size_t)tail); |
650 s->nbytes -= tail; | 686 s->nbytes -= tail; |
651 rb_pos += tail; | 687 rb_pos += tail; |
652 s->meta_block_remaining_len -= tail; | 688 s->meta_block_remaining_len -= tail; |
653 br_pos = 0; | 689 br_pos = 0; |
654 } | 690 } |
655 memcpy(&s->ringbuffer[rb_pos], &s->br.buf_[br_pos], (size_t)s->nbytes); | 691 memcpy(&s->ringbuffer[rb_pos], &s->br.buf_[br_pos], (size_t)s->nbytes); |
656 rb_pos += s->nbytes; | 692 rb_pos += s->nbytes; |
657 s->meta_block_remaining_len -= s->nbytes; | 693 s->meta_block_remaining_len -= s->nbytes; |
658 | 694 |
| 695 s->partially_written = 0; |
| 696 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_WRITE_1; |
| 697 /* No break, continue to next state */ |
| 698 case BROTLI_STATE_SUB_UNCOMPRESSED_WRITE_1: |
659 /* If we wrote past the logical end of the ringbuffer, copy the tail of | 699 /* If we wrote past the logical end of the ringbuffer, copy the tail of |
660 the ringbuffer to its beginning and flush the ringbuffer to the | 700 the ringbuffer to its beginning and flush the ringbuffer to the |
661 output. */ | 701 output. */ |
662 if (rb_pos >= rb_size) { | 702 if (rb_pos >= rb_size) { |
663 if (BrotliWrite(output, s->ringbuffer, (size_t)rb_size) < rb_size) { | 703 num_written = BrotliWrite(output, |
| 704 s->ringbuffer + s->partially_written, |
| 705 (size_t)(rb_size - s->partially_written)); |
| 706 if (num_written < 0) { |
664 return BROTLI_RESULT_ERROR; | 707 return BROTLI_RESULT_ERROR; |
665 } | 708 } |
| 709 s->partially_written += num_written; |
| 710 if (s->partially_written < rb_size) { |
| 711 return BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 712 } |
666 rb_pos -= rb_size; | 713 rb_pos -= rb_size; |
667 s->meta_block_remaining_len += rb_size; | 714 s->meta_block_remaining_len += rb_size; |
668 memcpy(s->ringbuffer, ringbuffer_end, (size_t)rb_pos); | 715 memcpy(s->ringbuffer, ringbuffer_end, (size_t)rb_pos); |
669 } | 716 } |
670 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_FILL; | 717 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_FILL; |
671 break; | 718 break; |
672 case BROTLI_STATE_SUB_UNCOMPRESSED_SHORT: | 719 case BROTLI_STATE_SUB_UNCOMPRESSED_SHORT: |
673 while (s->meta_block_remaining_len > 0) { | 720 while (s->meta_block_remaining_len > 0) { |
674 if (!BrotliReadMoreInput(&s->br)) { | 721 if (!BrotliReadMoreInput(&s->br)) { |
675 return BROTLI_RESULT_PARTIAL; | 722 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
676 } | 723 } |
677 s->ringbuffer[rb_pos++] = (uint8_t)BrotliReadBits(&s->br, 8); | 724 s->ringbuffer[rb_pos++] = (uint8_t)BrotliReadBits(&s->br, 8); |
678 if (rb_pos == rb_size) { | 725 if (rb_pos == rb_size) { |
679 if (BrotliWrite(output, s->ringbuffer, (size_t)rb_size) < rb_size) { | 726 s->partially_written = 0; |
680 return BROTLI_RESULT_ERROR; | 727 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_WRITE_2; |
681 } | 728 break; |
682 rb_pos = 0; | |
683 } | 729 } |
684 s->meta_block_remaining_len--; | 730 s->meta_block_remaining_len--; |
685 } | 731 } |
686 s->sub_state[0] = BROTLI_STATE_SUB_NONE; | 732 if (s->sub_state[0] == BROTLI_STATE_SUB_UNCOMPRESSED_SHORT) { |
687 return BROTLI_RESULT_SUCCESS; | 733 s->sub_state[0] = BROTLI_STATE_SUB_NONE; |
| 734 return BROTLI_RESULT_SUCCESS; |
| 735 } |
| 736 /* No break, if state is updated, continue to next state */ |
| 737 case BROTLI_STATE_SUB_UNCOMPRESSED_WRITE_2: |
| 738 num_written = BrotliWrite(output, s->ringbuffer + s->partially_written, |
| 739 (size_t)(rb_size - s->partially_written)); |
| 740 if (num_written < 0) { |
| 741 return BROTLI_RESULT_ERROR; |
| 742 } |
| 743 s->partially_written += num_written; |
| 744 if (s->partially_written < rb_size) { |
| 745 return BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 746 } |
| 747 rb_pos = 0; |
| 748 s->meta_block_remaining_len--; |
| 749 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_SHORT; |
| 750 break; |
688 case BROTLI_STATE_SUB_UNCOMPRESSED_FILL: | 751 case BROTLI_STATE_SUB_UNCOMPRESSED_FILL: |
689 /* If we have more to copy than the remaining size of the ringbuffer, | 752 /* If we have more to copy than the remaining size of the ringbuffer, |
690 then we first fill the ringbuffer from the input and then flush the | 753 then we first fill the ringbuffer from the input and then flush the |
691 ringbuffer to the output */ | 754 ringbuffer to the output */ |
692 while (rb_pos + s->meta_block_remaining_len >= rb_size) { | 755 if (rb_pos + s->meta_block_remaining_len >= rb_size) { |
693 s->nbytes = rb_size - rb_pos; | 756 s->nbytes = rb_size - rb_pos; |
694 if (BrotliRead(s->br.input_, &s->ringbuffer[rb_pos], | 757 if (BrotliRead(s->br.input_, &s->ringbuffer[rb_pos], |
695 (size_t)s->nbytes) < s->nbytes) { | 758 (size_t)s->nbytes) < s->nbytes) { |
696 return BROTLI_RESULT_PARTIAL; | 759 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
697 } | 760 } |
698 if (BrotliWrite(output, s->ringbuffer, (size_t)rb_size) < s->nbytes) { | 761 s->partially_written = 0; |
699 return BROTLI_RESULT_ERROR; | 762 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_WRITE_3; |
700 } | 763 } else { |
701 s->meta_block_remaining_len -= s->nbytes; | 764 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_COPY; |
702 rb_pos = 0; | 765 break; |
703 } | 766 } |
704 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_COPY; | |
705 /* No break, continue to next state */ | 767 /* No break, continue to next state */ |
| 768 case BROTLI_STATE_SUB_UNCOMPRESSED_WRITE_3: |
| 769 num_written = BrotliWrite(output, s->ringbuffer + s->partially_written, |
| 770 (size_t)(rb_size - s->partially_written)); |
| 771 if (num_written < 0) { |
| 772 return BROTLI_RESULT_ERROR; |
| 773 } |
| 774 s->partially_written += num_written; |
| 775 if (s->partially_written < rb_size) { |
| 776 return BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 777 } |
| 778 s->meta_block_remaining_len -= s->nbytes; |
| 779 rb_pos = 0; |
| 780 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_FILL; |
| 781 break; |
706 case BROTLI_STATE_SUB_UNCOMPRESSED_COPY: | 782 case BROTLI_STATE_SUB_UNCOMPRESSED_COPY: |
707 /* Copy straight from the input onto the ringbuffer. The ringbuffer will | 783 /* Copy straight from the input onto the ringbuffer. The ringbuffer will |
708 be flushed to the output at a later time. */ | 784 be flushed to the output at a later time. */ |
709 num_read = BrotliRead(s->br.input_, &s->ringbuffer[rb_pos], | 785 num_read = BrotliRead(s->br.input_, &s->ringbuffer[rb_pos], |
710 (size_t)s->meta_block_remaining_len); | 786 (size_t)s->meta_block_remaining_len); |
711 s->meta_block_remaining_len -= num_read; | 787 s->meta_block_remaining_len -= num_read; |
712 if (s->meta_block_remaining_len > 0) { | 788 if (s->meta_block_remaining_len > 0) { |
713 return BROTLI_RESULT_PARTIAL; | 789 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
714 } | 790 } |
715 | 791 |
716 /* Restore the state of the bit reader. */ | 792 /* Restore the state of the bit reader. */ |
717 BrotliInitBitReader(&s->br, s->br.input_, s->br.finish_); | 793 BrotliInitBitReader(&s->br, s->br.input_, s->br.finish_); |
718 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_WARMUP; | 794 s->sub_state[0] = BROTLI_STATE_SUB_UNCOMPRESSED_WARMUP; |
719 /* No break, continue to next state */ | 795 /* No break, continue to next state */ |
720 case BROTLI_STATE_SUB_UNCOMPRESSED_WARMUP: | 796 case BROTLI_STATE_SUB_UNCOMPRESSED_WARMUP: |
721 if (!BrotliWarmupBitReader(&s->br)) { | 797 if (!BrotliWarmupBitReader(&s->br)) { |
722 return BROTLI_RESULT_PARTIAL; | 798 return BROTLI_RESULT_NEEDS_MORE_INPUT; |
723 } | 799 } |
724 s->sub_state[0] = BROTLI_STATE_SUB_NONE; | 800 s->sub_state[0] = BROTLI_STATE_SUB_NONE; |
725 return BROTLI_RESULT_SUCCESS; | 801 return BROTLI_RESULT_SUCCESS; |
726 break; | 802 break; |
727 default: | 803 default: |
728 return BROTLI_RESULT_ERROR; /* Unknown state */ | 804 return BROTLI_RESULT_ERROR; /* Unknown state */ |
729 } | 805 } |
730 } | 806 } |
731 return BROTLI_RESULT_ERROR; | 807 return BROTLI_RESULT_ERROR; |
732 } | 808 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 BrotliResult success = BrotliDecompress(in, out); | 879 BrotliResult success = BrotliDecompress(in, out); |
804 *decoded_size = mout.pos; | 880 *decoded_size = mout.pos; |
805 return success; | 881 return success; |
806 } | 882 } |
807 | 883 |
808 BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output) { | 884 BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output) { |
809 BrotliState s; | 885 BrotliState s; |
810 BrotliResult result; | 886 BrotliResult result; |
811 BrotliStateInit(&s); | 887 BrotliStateInit(&s); |
812 result = BrotliDecompressStreaming(input, output, 1, &s); | 888 result = BrotliDecompressStreaming(input, output, 1, &s); |
813 if (result == BROTLI_RESULT_PARTIAL) { | 889 if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) { |
814 /* Not ok: it didn't finish even though this is a non-streaming function. */ | 890 /* Not ok: it didn't finish even though this is a non-streaming function. */ |
815 result = BROTLI_RESULT_ERROR; | 891 result = BROTLI_RESULT_ERROR; |
816 } | 892 } |
817 BrotliStateCleanup(&s); | 893 BrotliStateCleanup(&s); |
818 return result; | 894 return result; |
819 } | 895 } |
820 | 896 |
821 BrotliResult BrotliDecompressBufferStreaming(size_t* available_in, | 897 BrotliResult BrotliDecompressBufferStreaming(size_t* available_in, |
822 const uint8_t** next_in, | 898 const uint8_t** next_in, |
823 int finish, | 899 int finish, |
(...skipping 23 matching lines...) Expand all Loading... |
847 | 923 |
848 BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output, | 924 BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output, |
849 int finish, BrotliState* s) { | 925 int finish, BrotliState* s) { |
850 uint8_t context; | 926 uint8_t context; |
851 int pos = s->pos; | 927 int pos = s->pos; |
852 int i = s->loop_counter; | 928 int i = s->loop_counter; |
853 BrotliResult result = BROTLI_RESULT_SUCCESS; | 929 BrotliResult result = BROTLI_RESULT_SUCCESS; |
854 BrotliBitReader* br = &s->br; | 930 BrotliBitReader* br = &s->br; |
855 int initial_remaining_len; | 931 int initial_remaining_len; |
856 int bytes_copied; | 932 int bytes_copied; |
| 933 int num_written; |
857 | 934 |
858 /* We need the slack region for the following reasons: | 935 /* We need the slack region for the following reasons: |
859 - always doing two 8-byte copies for fast backward copying | 936 - always doing two 8-byte copies for fast backward copying |
860 - transforms | 937 - transforms |
861 - flushing the input s->ringbuffer when decoding uncompressed blocks */ | 938 - flushing the input s->ringbuffer when decoding uncompressed blocks */ |
862 static const int kRingBufferWriteAheadSlack = 128 + BROTLI_READ_SIZE; | 939 static const int kRingBufferWriteAheadSlack = 128 + BROTLI_READ_SIZE; |
863 | 940 |
864 s->br.finish_ = finish; | 941 s->br.finish_ = finish; |
865 | 942 |
866 /* State machine */ | 943 /* State machine */ |
867 for (;;) { | 944 for (;;) { |
868 if (result != BROTLI_RESULT_SUCCESS) { | 945 if (result != BROTLI_RESULT_SUCCESS) { |
869 if (result == BROTLI_RESULT_PARTIAL && finish) { | 946 if (result == BROTLI_RESULT_NEEDS_MORE_INPUT && finish) { |
870 printf("Unexpected end of input. State: %d\n", s->state); | 947 printf("Unexpected end of input. State: %d\n", s->state); |
871 result = BROTLI_RESULT_ERROR; | 948 result = BROTLI_RESULT_ERROR; |
872 } | 949 } |
873 break; /* Fail, or partial data. */ | 950 break; /* Fail, or partial data. */ |
874 } | 951 } |
875 | 952 |
876 switch (s->state) { | 953 switch (s->state) { |
877 case BROTLI_STATE_UNINITED: | 954 case BROTLI_STATE_UNINITED: |
878 pos = 0; | 955 pos = 0; |
879 s->input_end = 0; | 956 s->input_end = 0; |
880 s->window_bits = 0; | 957 s->window_bits = 0; |
881 s->max_distance = 0; | 958 s->max_distance = 0; |
882 s->dist_rb[0] = 16; | 959 s->dist_rb[0] = 16; |
883 s->dist_rb[1] = 15; | 960 s->dist_rb[1] = 15; |
884 s->dist_rb[2] = 11; | 961 s->dist_rb[2] = 11; |
885 s->dist_rb[3] = 4; | 962 s->dist_rb[3] = 4; |
886 s->dist_rb_idx = 0; | 963 s->dist_rb_idx = 0; |
887 s->prev_byte1 = 0; | 964 s->prev_byte1 = 0; |
888 s->prev_byte2 = 0; | 965 s->prev_byte2 = 0; |
889 s->block_type_trees = NULL; | 966 s->block_type_trees = NULL; |
890 s->block_len_trees = NULL; | 967 s->block_len_trees = NULL; |
891 | 968 |
892 BrotliInitBitReader(br, input, finish); | 969 BrotliInitBitReader(br, input, finish); |
893 | 970 |
894 s->state = BROTLI_STATE_BITREADER_WARMUP; | 971 s->state = BROTLI_STATE_BITREADER_WARMUP; |
895 /* No break, continue to next state */ | 972 /* No break, continue to next state */ |
896 case BROTLI_STATE_BITREADER_WARMUP: | 973 case BROTLI_STATE_BITREADER_WARMUP: |
897 if (!BrotliWarmupBitReader(br)) { | 974 if (!BrotliWarmupBitReader(br)) { |
898 result = BROTLI_RESULT_PARTIAL; | 975 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
899 break; | 976 break; |
900 } | 977 } |
901 /* Decode window size. */ | 978 /* Decode window size. */ |
902 s->window_bits = DecodeWindowBits(br); | 979 s->window_bits = DecodeWindowBits(br); |
903 s->max_backward_distance = (1 << s->window_bits) - 16; | 980 s->max_backward_distance = (1 << s->window_bits) - 16; |
904 | 981 |
905 s->ringbuffer_size = 1 << s->window_bits; | 982 s->ringbuffer_size = 1 << s->window_bits; |
906 s->ringbuffer_mask = s->ringbuffer_size - 1; | 983 s->ringbuffer_mask = s->ringbuffer_size - 1; |
907 s->ringbuffer = (uint8_t*)malloc((size_t)(s->ringbuffer_size + | 984 s->ringbuffer = (uint8_t*)malloc((size_t)(s->ringbuffer_size + |
908 kRingBufferWriteAheadSlack + | 985 kRingBufferWriteAheadSlack + |
(...skipping 10 matching lines...) Expand all Loading... |
919 3 * BROTLI_HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode)); | 996 3 * BROTLI_HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode)); |
920 if (s->block_type_trees == NULL || s->block_len_trees == NULL) { | 997 if (s->block_type_trees == NULL || s->block_len_trees == NULL) { |
921 result = BROTLI_RESULT_ERROR; | 998 result = BROTLI_RESULT_ERROR; |
922 break; | 999 break; |
923 } | 1000 } |
924 | 1001 |
925 s->state = BROTLI_STATE_METABLOCK_BEGIN; | 1002 s->state = BROTLI_STATE_METABLOCK_BEGIN; |
926 /* No break, continue to next state */ | 1003 /* No break, continue to next state */ |
927 case BROTLI_STATE_METABLOCK_BEGIN: | 1004 case BROTLI_STATE_METABLOCK_BEGIN: |
928 if (!BrotliReadMoreInput(br)) { | 1005 if (!BrotliReadMoreInput(br)) { |
929 result = BROTLI_RESULT_PARTIAL; | 1006 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
930 break; | 1007 break; |
931 } | 1008 } |
932 if (s->input_end) { | 1009 if (s->input_end) { |
| 1010 s->partially_written = 0; |
933 s->state = BROTLI_STATE_DONE; | 1011 s->state = BROTLI_STATE_DONE; |
934 break; | 1012 break; |
935 } | 1013 } |
936 s->meta_block_remaining_len = 0; | 1014 s->meta_block_remaining_len = 0; |
937 s->block_length[0] = 1 << 28; | 1015 s->block_length[0] = 1 << 28; |
938 s->block_length[1] = 1 << 28; | 1016 s->block_length[1] = 1 << 28; |
939 s->block_length[2] = 1 << 28; | 1017 s->block_length[2] = 1 << 28; |
940 s->block_type[0] = 0; | 1018 s->block_type[0] = 0; |
941 s->num_block_types[0] = 1; | 1019 s->num_block_types[0] = 1; |
942 s->num_block_types[1] = 1; | 1020 s->num_block_types[1] = 1; |
(...skipping 17 matching lines...) Expand all Loading... |
960 s->context_lookup_offset1 = 0; | 1038 s->context_lookup_offset1 = 0; |
961 s->context_lookup_offset2 = 0; | 1039 s->context_lookup_offset2 = 0; |
962 for (i = 0; i < 3; ++i) { | 1040 for (i = 0; i < 3; ++i) { |
963 s->hgroup[i].codes = NULL; | 1041 s->hgroup[i].codes = NULL; |
964 s->hgroup[i].htrees = NULL; | 1042 s->hgroup[i].htrees = NULL; |
965 } | 1043 } |
966 s->state = BROTLI_STATE_METABLOCK_HEADER_1; | 1044 s->state = BROTLI_STATE_METABLOCK_HEADER_1; |
967 /* No break, continue to next state */ | 1045 /* No break, continue to next state */ |
968 case BROTLI_STATE_METABLOCK_HEADER_1: | 1046 case BROTLI_STATE_METABLOCK_HEADER_1: |
969 if (!BrotliReadMoreInput(br)) { | 1047 if (!BrotliReadMoreInput(br)) { |
970 result = BROTLI_RESULT_PARTIAL; | 1048 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
971 break; | 1049 break; |
972 } | 1050 } |
973 BROTLI_LOG_UINT(pos); | 1051 BROTLI_LOG_UINT(pos); |
974 DecodeMetaBlockLength(br, &s->meta_block_remaining_len, | 1052 if (!DecodeMetaBlockLength(br, |
975 &s->input_end, &s->is_uncompressed); | 1053 &s->meta_block_remaining_len, |
| 1054 &s->input_end, |
| 1055 &s->is_metadata, |
| 1056 &s->is_uncompressed)) { |
| 1057 result = BROTLI_RESULT_ERROR; |
| 1058 break; |
| 1059 } |
976 BROTLI_LOG_UINT(s->meta_block_remaining_len); | 1060 BROTLI_LOG_UINT(s->meta_block_remaining_len); |
| 1061 if (s->is_metadata) { |
| 1062 if (!JumpToByteBoundary(&s->br)) { |
| 1063 result = BROTLI_RESULT_ERROR; |
| 1064 break; |
| 1065 } |
| 1066 s->state = BROTLI_STATE_METADATA; |
| 1067 break; |
| 1068 } |
977 if (s->meta_block_remaining_len == 0) { | 1069 if (s->meta_block_remaining_len == 0) { |
978 s->state = BROTLI_STATE_METABLOCK_DONE; | 1070 s->state = BROTLI_STATE_METABLOCK_DONE; |
979 break; | 1071 break; |
980 } | 1072 } |
981 if (s->is_uncompressed) { | 1073 if (s->is_uncompressed) { |
982 BrotliSetBitPos(br, (s->br.bit_pos_ + 7) & (uint32_t)(~7UL)); | 1074 if (!JumpToByteBoundary(&s->br)) { |
| 1075 result = BROTLI_RESULT_ERROR; |
| 1076 break; |
| 1077 } |
983 s->state = BROTLI_STATE_UNCOMPRESSED; | 1078 s->state = BROTLI_STATE_UNCOMPRESSED; |
984 break; | 1079 break; |
985 } | 1080 } |
986 i = 0; | 1081 i = 0; |
987 s->state = BROTLI_STATE_HUFFMAN_CODE_0; | 1082 s->state = BROTLI_STATE_HUFFMAN_CODE_0; |
988 break; | 1083 break; |
989 case BROTLI_STATE_UNCOMPRESSED: | 1084 case BROTLI_STATE_UNCOMPRESSED: |
990 initial_remaining_len = s->meta_block_remaining_len; | 1085 initial_remaining_len = s->meta_block_remaining_len; |
991 /* pos is given as argument since s->pos is only updated at the end. */ | 1086 /* pos is given as argument since s->pos is only updated at the end. */ |
992 result = CopyUncompressedBlockToOutput(output, pos, s); | 1087 result = CopyUncompressedBlockToOutput(output, pos, s); |
| 1088 if (result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { |
| 1089 break; |
| 1090 } |
993 bytes_copied = initial_remaining_len - s->meta_block_remaining_len; | 1091 bytes_copied = initial_remaining_len - s->meta_block_remaining_len; |
994 pos += bytes_copied; | 1092 pos += bytes_copied; |
995 if (bytes_copied > 0) { | 1093 if (bytes_copied > 0) { |
996 s->prev_byte2 = bytes_copied == 1 ? s->prev_byte1 : | 1094 s->prev_byte2 = bytes_copied == 1 ? s->prev_byte1 : |
997 s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; | 1095 s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; |
998 s->prev_byte1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; | 1096 s->prev_byte1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; |
999 } | 1097 } |
1000 if (result != BROTLI_RESULT_SUCCESS) break; | 1098 if (result != BROTLI_RESULT_SUCCESS) break; |
1001 s->state = BROTLI_STATE_METABLOCK_DONE; | 1099 s->state = BROTLI_STATE_METABLOCK_DONE; |
1002 break; | 1100 break; |
| 1101 case BROTLI_STATE_METADATA: |
| 1102 for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) { |
| 1103 if (!BrotliReadMoreInput(&s->br)) { |
| 1104 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
| 1105 break; |
| 1106 } |
| 1107 /* Read one byte and ignore it. */ |
| 1108 BrotliReadBits(&s->br, 8); |
| 1109 } |
| 1110 s->state = BROTLI_STATE_METABLOCK_DONE; |
| 1111 break; |
1003 case BROTLI_STATE_HUFFMAN_CODE_0: | 1112 case BROTLI_STATE_HUFFMAN_CODE_0: |
1004 if (i >= 3) { | 1113 if (i >= 3) { |
1005 BROTLI_LOG_UINT(s->num_block_types[0]); | 1114 BROTLI_LOG_UINT(s->num_block_types[0]); |
1006 BROTLI_LOG_UINT(s->num_block_types[1]); | 1115 BROTLI_LOG_UINT(s->num_block_types[1]); |
1007 BROTLI_LOG_UINT(s->num_block_types[2]); | 1116 BROTLI_LOG_UINT(s->num_block_types[2]); |
1008 BROTLI_LOG_UINT(s->block_length[0]); | 1117 BROTLI_LOG_UINT(s->block_length[0]); |
1009 BROTLI_LOG_UINT(s->block_length[1]); | 1118 BROTLI_LOG_UINT(s->block_length[1]); |
1010 BROTLI_LOG_UINT(s->block_length[2]); | 1119 BROTLI_LOG_UINT(s->block_length[2]); |
1011 | 1120 |
1012 s->state = BROTLI_STATE_METABLOCK_HEADER_2; | 1121 s->state = BROTLI_STATE_METABLOCK_HEADER_2; |
(...skipping 21 matching lines...) Expand all Loading... |
1034 NULL, s); | 1143 NULL, s); |
1035 if (result != BROTLI_RESULT_SUCCESS) break; | 1144 if (result != BROTLI_RESULT_SUCCESS) break; |
1036 s->block_length[i] = ReadBlockLength( | 1145 s->block_length[i] = ReadBlockLength( |
1037 &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br); | 1146 &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br); |
1038 s->block_type_rb_index[i] = 1; | 1147 s->block_type_rb_index[i] = 1; |
1039 i++; | 1148 i++; |
1040 s->state = BROTLI_STATE_HUFFMAN_CODE_0; | 1149 s->state = BROTLI_STATE_HUFFMAN_CODE_0; |
1041 break; | 1150 break; |
1042 case BROTLI_STATE_METABLOCK_HEADER_2: | 1151 case BROTLI_STATE_METABLOCK_HEADER_2: |
1043 if (!BrotliReadMoreInput(br)) { | 1152 if (!BrotliReadMoreInput(br)) { |
1044 result = BROTLI_RESULT_PARTIAL; | 1153 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
1045 break; | 1154 break; |
1046 } | 1155 } |
1047 s->distance_postfix_bits = (int)BrotliReadBits(br, 2); | 1156 s->distance_postfix_bits = (int)BrotliReadBits(br, 2); |
1048 s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + | 1157 s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + |
1049 ((int)BrotliReadBits(br, 4) << s->distance_postfix_bits); | 1158 ((int)BrotliReadBits(br, 4) << s->distance_postfix_bits); |
1050 s->distance_postfix_mask = (1 << s->distance_postfix_bits) - 1; | 1159 s->distance_postfix_mask = (1 << s->distance_postfix_bits) - 1; |
1051 s->num_distance_codes = (s->num_direct_distance_codes + | 1160 s->num_distance_codes = (s->num_direct_distance_codes + |
1052 (48 << s->distance_postfix_bits)); | 1161 (48 << s->distance_postfix_bits)); |
1053 s->context_modes = (uint8_t*)malloc((size_t)s->num_block_types[0]); | 1162 s->context_modes = (uint8_t*)malloc((size_t)s->num_block_types[0]); |
1054 if (s->context_modes == 0) { | 1163 if (s->context_modes == 0) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 | 1217 |
1109 s->state = BROTLI_STATE_BLOCK_BEGIN; | 1218 s->state = BROTLI_STATE_BLOCK_BEGIN; |
1110 break; | 1219 break; |
1111 } | 1220 } |
1112 | 1221 |
1113 break; | 1222 break; |
1114 case BROTLI_STATE_BLOCK_BEGIN: | 1223 case BROTLI_STATE_BLOCK_BEGIN: |
1115 /* Block decoding is the inner loop, jumping with goto makes it 3% faster */ | 1224 /* Block decoding is the inner loop, jumping with goto makes it 3% faster */ |
1116 BlockBegin: | 1225 BlockBegin: |
1117 if (!BrotliReadMoreInput(br)) { | 1226 if (!BrotliReadMoreInput(br)) { |
1118 result = BROTLI_RESULT_PARTIAL; | 1227 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
1119 break; | 1228 break; |
1120 } | 1229 } |
1121 if (s->meta_block_remaining_len <= 0) { | 1230 if (s->meta_block_remaining_len <= 0) { |
1122 /* Protect pos from overflow, wrap it around at every GB of input. */ | 1231 /* Protect pos from overflow, wrap it around at every GB of input. */ |
1123 pos &= 0x3fffffff; | 1232 pos &= 0x3fffffff; |
1124 | 1233 |
1125 /* Next metablock, if any */ | 1234 /* Next metablock, if any */ |
1126 s->state = BROTLI_STATE_METABLOCK_DONE; | 1235 s->state = BROTLI_STATE_METABLOCK_DONE; |
1127 break; | 1236 break; |
1128 } | 1237 } |
(...skipping 28 matching lines...) Expand all Loading... |
1157 BROTLI_LOG_UINT(s->copy_length); | 1266 BROTLI_LOG_UINT(s->copy_length); |
1158 BROTLI_LOG_UINT(s->distance_code); | 1267 BROTLI_LOG_UINT(s->distance_code); |
1159 | 1268 |
1160 i = 0; | 1269 i = 0; |
1161 s->state = BROTLI_STATE_BLOCK_INNER; | 1270 s->state = BROTLI_STATE_BLOCK_INNER; |
1162 /* No break, go to next state */ | 1271 /* No break, go to next state */ |
1163 case BROTLI_STATE_BLOCK_INNER: | 1272 case BROTLI_STATE_BLOCK_INNER: |
1164 if (s->trivial_literal_context) { | 1273 if (s->trivial_literal_context) { |
1165 while (i < s->insert_length) { | 1274 while (i < s->insert_length) { |
1166 if (!BrotliReadMoreInput(br)) { | 1275 if (!BrotliReadMoreInput(br)) { |
1167 result = BROTLI_RESULT_PARTIAL; | 1276 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
1168 break; | 1277 break; |
1169 } | 1278 } |
1170 if (s->block_length[0] == 0) { | 1279 if (s->block_length[0] == 0) { |
1171 DecodeBlockTypeWithContext(s, br); | 1280 DecodeBlockTypeWithContext(s, br); |
1172 } | 1281 } |
1173 | 1282 |
1174 s->ringbuffer[pos & s->ringbuffer_mask] = (uint8_t)ReadSymbol( | 1283 s->ringbuffer[pos & s->ringbuffer_mask] = (uint8_t)ReadSymbol( |
1175 s->hgroup[0].htrees[s->literal_htree_index], br); | 1284 s->hgroup[0].htrees[s->literal_htree_index], br); |
1176 | 1285 |
1177 --s->block_length[0]; | 1286 --s->block_length[0]; |
1178 BROTLI_LOG_UINT(s->literal_htree_index); | 1287 BROTLI_LOG_UINT(s->literal_htree_index); |
1179 BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask); | 1288 BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask); |
1180 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { | 1289 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { |
1181 if (BrotliWrite(output, s->ringbuffer, | 1290 s->partially_written = 0; |
1182 (size_t)s->ringbuffer_size) < 0) { | 1291 s->state = BROTLI_STATE_BLOCK_INNER_WRITE; |
1183 result = BROTLI_RESULT_ERROR; | 1292 break; |
1184 break; | |
1185 } | |
1186 } | 1293 } |
| 1294 /* Modifications to this code shold be reflected in |
| 1295 BROTLI_STATE_BLOCK_INNER_WRITE case */ |
1187 ++pos; | 1296 ++pos; |
1188 ++i; | 1297 ++i; |
1189 } | 1298 } |
1190 } else { | 1299 } else { |
1191 while (i < s->insert_length) { | 1300 while (i < s->insert_length) { |
1192 if (!BrotliReadMoreInput(br)) { | 1301 if (!BrotliReadMoreInput(br)) { |
1193 result = BROTLI_RESULT_PARTIAL; | 1302 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
1194 break; | 1303 break; |
1195 } | 1304 } |
1196 if (s->block_length[0] == 0) { | 1305 if (s->block_length[0] == 0) { |
1197 DecodeBlockTypeWithContext(s, br); | 1306 DecodeBlockTypeWithContext(s, br); |
1198 } | 1307 } |
1199 | 1308 |
1200 context = | 1309 context = |
1201 (kContextLookup[s->context_lookup_offset1 + s->prev_byte1] | | 1310 (kContextLookup[s->context_lookup_offset1 + s->prev_byte1] | |
1202 kContextLookup[s->context_lookup_offset2 + s->prev_byte2]); | 1311 kContextLookup[s->context_lookup_offset2 + s->prev_byte2]); |
1203 BROTLI_LOG_UINT(context); | 1312 BROTLI_LOG_UINT(context); |
1204 s->literal_htree_index = s->context_map_slice[context]; | 1313 s->literal_htree_index = s->context_map_slice[context]; |
1205 --s->block_length[0]; | 1314 --s->block_length[0]; |
1206 s->prev_byte2 = s->prev_byte1; | 1315 s->prev_byte2 = s->prev_byte1; |
1207 s->prev_byte1 = (uint8_t)ReadSymbol( | 1316 s->prev_byte1 = (uint8_t)ReadSymbol( |
1208 s->hgroup[0].htrees[s->literal_htree_index], br); | 1317 s->hgroup[0].htrees[s->literal_htree_index], br); |
1209 s->ringbuffer[pos & s->ringbuffer_mask] = s->prev_byte1; | 1318 s->ringbuffer[pos & s->ringbuffer_mask] = s->prev_byte1; |
1210 BROTLI_LOG_UINT(s->literal_htree_index); | 1319 BROTLI_LOG_UINT(s->literal_htree_index); |
1211 BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask); | 1320 BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask); |
1212 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { | 1321 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { |
1213 if (BrotliWrite(output, s->ringbuffer, | 1322 s->partially_written = 0; |
1214 (size_t)s->ringbuffer_size) < 0) { | 1323 s->state = BROTLI_STATE_BLOCK_INNER_WRITE; |
1215 result = BROTLI_RESULT_ERROR; | 1324 break; |
1216 break; | |
1217 } | |
1218 } | 1325 } |
| 1326 /* Modifications to this code shold be reflected in |
| 1327 BROTLI_STATE_BLOCK_INNER_WRITE case */ |
1219 ++pos; | 1328 ++pos; |
1220 ++i; | 1329 ++i; |
1221 } | 1330 } |
1222 } | 1331 } |
1223 | 1332 if (result != BROTLI_RESULT_SUCCESS || |
1224 if (result != BROTLI_RESULT_SUCCESS) break; | 1333 s->state == BROTLI_STATE_BLOCK_INNER_WRITE) break; |
1225 | 1334 |
1226 s->meta_block_remaining_len -= s->insert_length; | 1335 s->meta_block_remaining_len -= s->insert_length; |
1227 if (s->meta_block_remaining_len <= 0) { | 1336 if (s->meta_block_remaining_len <= 0) { |
1228 s->state = BROTLI_STATE_METABLOCK_DONE; | 1337 s->state = BROTLI_STATE_METABLOCK_DONE; |
1229 break; | 1338 break; |
1230 } else if (s->distance_code < 0) { | 1339 } else if (s->distance_code < 0) { |
1231 s->state = BROTLI_STATE_BLOCK_DISTANCE; | 1340 s->state = BROTLI_STATE_BLOCK_DISTANCE; |
1232 } else { | 1341 } else { |
1233 s->state = BROTLI_STATE_BLOCK_POST; | 1342 s->state = BROTLI_STATE_BLOCK_POST; |
1234 break; | 1343 break; |
1235 } | 1344 } |
1236 /* No break, go to next state */ | 1345 /* No break, go to next state */ |
1237 case BROTLI_STATE_BLOCK_DISTANCE: | 1346 case BROTLI_STATE_BLOCK_DISTANCE: |
1238 if (!BrotliReadMoreInput(br)) { | 1347 if (!BrotliReadMoreInput(br)) { |
1239 result = BROTLI_RESULT_PARTIAL; | 1348 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
1240 break; | 1349 break; |
1241 } | 1350 } |
1242 assert(s->distance_code < 0); | 1351 assert(s->distance_code < 0); |
1243 | 1352 |
1244 if (s->block_length[2] == 0) { | 1353 if (s->block_length[2] == 0) { |
1245 DecodeBlockType(s->num_block_types[2], | 1354 DecodeBlockType(s->num_block_types[2], |
1246 s->block_type_trees, 2, | 1355 s->block_type_trees, 2, |
1247 s->block_type, s->block_type_rb, | 1356 s->block_type, s->block_type_rb, |
1248 s->block_type_rb_index, br); | 1357 s->block_type_rb_index, br); |
1249 s->block_length[2] = ReadBlockLength( | 1358 s->block_length[2] = ReadBlockLength( |
(...skipping 17 matching lines...) Expand all Loading... |
1267 nbits = (s->distance_code >> 1) + 1; | 1376 nbits = (s->distance_code >> 1) + 1; |
1268 offset = ((2 + (s->distance_code & 1)) << nbits) - 4; | 1377 offset = ((2 + (s->distance_code & 1)) << nbits) - 4; |
1269 s->distance_code = s->num_direct_distance_codes + | 1378 s->distance_code = s->num_direct_distance_codes + |
1270 ((offset + (int)BrotliReadBits(br, nbits)) << | 1379 ((offset + (int)BrotliReadBits(br, nbits)) << |
1271 s->distance_postfix_bits) + postfix; | 1380 s->distance_postfix_bits) + postfix; |
1272 } | 1381 } |
1273 s->state = BROTLI_STATE_BLOCK_POST; | 1382 s->state = BROTLI_STATE_BLOCK_POST; |
1274 /* No break, go to next state */ | 1383 /* No break, go to next state */ |
1275 case BROTLI_STATE_BLOCK_POST: | 1384 case BROTLI_STATE_BLOCK_POST: |
1276 if (!BrotliReadMoreInput(br)) { | 1385 if (!BrotliReadMoreInput(br)) { |
1277 result = BROTLI_RESULT_PARTIAL; | 1386 result = BROTLI_RESULT_NEEDS_MORE_INPUT; |
1278 break; | 1387 break; |
1279 } | 1388 } |
1280 /* Convert the distance code to the actual distance by possibly */ | 1389 /* Convert the distance code to the actual distance by possibly */ |
1281 /* looking up past distnaces from the s->ringbuffer. */ | 1390 /* looking up past distnaces from the s->ringbuffer. */ |
1282 s->distance = | 1391 s->distance = |
1283 TranslateShortCodes(s->distance_code, s->dist_rb, s->dist_rb_idx); | 1392 TranslateShortCodes(s->distance_code, s->dist_rb, s->dist_rb_idx); |
1284 if (s->distance < 0) { | 1393 if (s->distance < 0) { |
1285 result = BROTLI_RESULT_ERROR; | 1394 result = BROTLI_RESULT_ERROR; |
1286 break; | 1395 break; |
1287 } | 1396 } |
(...skipping 19 matching lines...) Expand all Loading... |
1307 int transform_idx = word_id >> shift; | 1416 int transform_idx = word_id >> shift; |
1308 offset += word_idx * s->copy_length; | 1417 offset += word_idx * s->copy_length; |
1309 if (transform_idx < kNumTransforms) { | 1418 if (transform_idx < kNumTransforms) { |
1310 const uint8_t* word = &kBrotliDictionary[offset]; | 1419 const uint8_t* word = &kBrotliDictionary[offset]; |
1311 int len = TransformDictionaryWord( | 1420 int len = TransformDictionaryWord( |
1312 s->copy_dst, word, s->copy_length, transform_idx); | 1421 s->copy_dst, word, s->copy_length, transform_idx); |
1313 s->copy_dst += len; | 1422 s->copy_dst += len; |
1314 pos += len; | 1423 pos += len; |
1315 s->meta_block_remaining_len -= len; | 1424 s->meta_block_remaining_len -= len; |
1316 if (s->copy_dst >= s->ringbuffer_end) { | 1425 if (s->copy_dst >= s->ringbuffer_end) { |
1317 if (BrotliWrite(output, s->ringbuffer, | 1426 s->partially_written = 0; |
1318 (size_t)s->ringbuffer_size) < 0) { | 1427 num_written = BrotliWrite(output, s->ringbuffer, |
| 1428 (size_t)s->ringbuffer_size); |
| 1429 if (num_written < 0) { |
1319 result = BROTLI_RESULT_ERROR; | 1430 result = BROTLI_RESULT_ERROR; |
1320 break; | 1431 break; |
1321 } | 1432 } |
| 1433 s->partially_written += num_written; |
| 1434 if (s->partially_written < s->ringbuffer_size) { |
| 1435 result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 1436 s->state = BROTLI_STATE_BLOCK_POST_WRITE_1; |
| 1437 break; |
| 1438 } |
| 1439 /* Modifications to this code shold be reflected in |
| 1440 BROTLI_STATE_BLOCK_POST_WRITE_1 case */ |
1322 memcpy(s->ringbuffer, s->ringbuffer_end, | 1441 memcpy(s->ringbuffer, s->ringbuffer_end, |
1323 (size_t)(s->copy_dst - s->ringbuffer_end)); | 1442 (size_t)(s->copy_dst - s->ringbuffer_end)); |
1324 } | 1443 } |
1325 } else { | 1444 } else { |
1326 printf("Invalid backward reference. pos: %d distance: %d " | 1445 printf("Invalid backward reference. pos: %d distance: %d " |
1327 "len: %d bytes left: %d\n", | 1446 "len: %d bytes left: %d\n", |
1328 pos, s->distance, s->copy_length, | 1447 pos, s->distance, s->copy_length, |
1329 s->meta_block_remaining_len); | 1448 s->meta_block_remaining_len); |
1330 result = BROTLI_RESULT_ERROR; | 1449 result = BROTLI_RESULT_ERROR; |
1331 break; | 1450 break; |
(...skipping 29 matching lines...) Expand all Loading... |
1361 UNALIGNED_COPY64(s->copy_dst, s->copy_src); | 1480 UNALIGNED_COPY64(s->copy_dst, s->copy_src); |
1362 UNALIGNED_COPY64(s->copy_dst + 8, s->copy_src + 8); | 1481 UNALIGNED_COPY64(s->copy_dst + 8, s->copy_src + 8); |
1363 } else { | 1482 } else { |
1364 IncrementalCopyFastPath(s->copy_dst, s->copy_src, s->copy_length); | 1483 IncrementalCopyFastPath(s->copy_dst, s->copy_src, s->copy_length); |
1365 } | 1484 } |
1366 pos += s->copy_length; | 1485 pos += s->copy_length; |
1367 s->meta_block_remaining_len -= s->copy_length; | 1486 s->meta_block_remaining_len -= s->copy_length; |
1368 s->copy_length = 0; | 1487 s->copy_length = 0; |
1369 } | 1488 } |
1370 #endif | 1489 #endif |
1371 | 1490 /* Modifications to this loop shold be reflected in |
| 1491 BROTLI_STATE_BLOCK_POST_WRITE_2 case */ |
1372 for (i = 0; i < s->copy_length; ++i) { | 1492 for (i = 0; i < s->copy_length; ++i) { |
1373 s->ringbuffer[pos & s->ringbuffer_mask] = | 1493 s->ringbuffer[pos & s->ringbuffer_mask] = |
1374 s->ringbuffer[(pos - s->distance) & s->ringbuffer_mask]; | 1494 s->ringbuffer[(pos - s->distance) & s->ringbuffer_mask]; |
1375 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { | 1495 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { |
1376 if (BrotliWrite(output, s->ringbuffer, | 1496 s->partially_written = 0; |
1377 (size_t)s->ringbuffer_size) < 0) { | 1497 num_written = BrotliWrite(output, s->ringbuffer, |
| 1498 (size_t)s->ringbuffer_size); |
| 1499 if (num_written < 0) { |
1378 result = BROTLI_RESULT_ERROR; | 1500 result = BROTLI_RESULT_ERROR; |
1379 break; | 1501 break; |
1380 } | 1502 } |
| 1503 s->partially_written += num_written; |
| 1504 if (s->partially_written < s->ringbuffer_size) { |
| 1505 result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 1506 s->state = BROTLI_STATE_BLOCK_POST_WRITE_2; |
| 1507 break; |
| 1508 } |
1381 } | 1509 } |
1382 ++pos; | 1510 ++pos; |
1383 --s->meta_block_remaining_len; | 1511 --s->meta_block_remaining_len; |
1384 } | 1512 } |
| 1513 if (result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { |
| 1514 break; |
| 1515 } |
1385 } | 1516 } |
1386 | 1517 /* No break, continue to next state */ |
| 1518 case BROTLI_STATE_BLOCK_POST_CONTINUE: |
1387 /* When we get here, we must have inserted at least one literal and */ | 1519 /* When we get here, we must have inserted at least one literal and */ |
1388 /* made a copy of at least length two, therefore accessing the last 2 */ | 1520 /* made a copy of at least length two, therefore accessing the last 2 */ |
1389 /* bytes is valid. */ | 1521 /* bytes is valid. */ |
1390 s->prev_byte1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; | 1522 s->prev_byte1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; |
1391 s->prev_byte2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; | 1523 s->prev_byte2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; |
1392 s->state = BROTLI_STATE_BLOCK_BEGIN; | 1524 s->state = BROTLI_STATE_BLOCK_BEGIN; |
1393 goto BlockBegin; | 1525 goto BlockBegin; |
| 1526 case BROTLI_STATE_BLOCK_INNER_WRITE: |
| 1527 case BROTLI_STATE_BLOCK_POST_WRITE_1: |
| 1528 case BROTLI_STATE_BLOCK_POST_WRITE_2: |
| 1529 num_written = BrotliWrite( |
| 1530 output, s->ringbuffer + s->partially_written, |
| 1531 (size_t)(s->ringbuffer_size - s->partially_written)); |
| 1532 if (num_written < 0) { |
| 1533 result = BROTLI_RESULT_ERROR; |
| 1534 break; |
| 1535 } |
| 1536 s->partially_written += num_written; |
| 1537 if (s->partially_written < s->ringbuffer_size) { |
| 1538 result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 1539 break; |
| 1540 } |
| 1541 if (s->state == BROTLI_STATE_BLOCK_POST_WRITE_1) { |
| 1542 memcpy(s->ringbuffer, s->ringbuffer_end, |
| 1543 (size_t)(s->copy_dst - s->ringbuffer_end)); |
| 1544 s->state = BROTLI_STATE_BLOCK_POST_CONTINUE; |
| 1545 } else if (s->state == BROTLI_STATE_BLOCK_POST_WRITE_2) { |
| 1546 /* The tail of "i < s->copy_length" loop. */ |
| 1547 ++pos; |
| 1548 --s->meta_block_remaining_len; |
| 1549 ++i; |
| 1550 /* Reenter the loop. */ |
| 1551 for (; i < s->copy_length; ++i) { |
| 1552 s->ringbuffer[pos & s->ringbuffer_mask] = |
| 1553 s->ringbuffer[(pos - s->distance) & s->ringbuffer_mask]; |
| 1554 if ((pos & s->ringbuffer_mask) == s->ringbuffer_mask) { |
| 1555 s->partially_written = 0; |
| 1556 num_written = BrotliWrite(output, s->ringbuffer, |
| 1557 (size_t)s->ringbuffer_size); |
| 1558 if (num_written < 0) { |
| 1559 result = BROTLI_RESULT_ERROR; |
| 1560 break; |
| 1561 } |
| 1562 s->partially_written += num_written; |
| 1563 if (s->partially_written < s->ringbuffer_size) { |
| 1564 result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 1565 break; |
| 1566 } |
| 1567 } |
| 1568 ++pos; |
| 1569 --s->meta_block_remaining_len; |
| 1570 } |
| 1571 if (result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { |
| 1572 break; |
| 1573 } |
| 1574 s->state = BROTLI_STATE_BLOCK_POST_CONTINUE; |
| 1575 } else { /* BROTLI_STATE_BLOCK_INNER_WRITE */ |
| 1576 /* The tail of "i < s->insert_length" loop. */ |
| 1577 ++pos; |
| 1578 ++i; |
| 1579 s->state = BROTLI_STATE_BLOCK_INNER; |
| 1580 } |
| 1581 break; |
1394 case BROTLI_STATE_METABLOCK_DONE: | 1582 case BROTLI_STATE_METABLOCK_DONE: |
1395 if (s->context_modes != 0) { | 1583 if (s->context_modes != 0) { |
1396 free(s->context_modes); | 1584 free(s->context_modes); |
1397 s->context_modes = NULL; | 1585 s->context_modes = NULL; |
1398 } | 1586 } |
1399 if (s->context_map != 0) { | 1587 if (s->context_map != 0) { |
1400 free(s->context_map); | 1588 free(s->context_map); |
1401 s->context_map = NULL; | 1589 s->context_map = NULL; |
1402 } | 1590 } |
1403 if (s->dist_context_map != 0) { | 1591 if (s->dist_context_map != 0) { |
1404 free(s->dist_context_map); | 1592 free(s->dist_context_map); |
1405 s->dist_context_map = NULL; | 1593 s->dist_context_map = NULL; |
1406 } | 1594 } |
1407 for (i = 0; i < 3; ++i) { | 1595 for (i = 0; i < 3; ++i) { |
1408 BrotliHuffmanTreeGroupRelease(&s->hgroup[i]); | 1596 BrotliHuffmanTreeGroupRelease(&s->hgroup[i]); |
1409 s->hgroup[i].codes = NULL; | 1597 s->hgroup[i].codes = NULL; |
1410 s->hgroup[i].htrees = NULL; | 1598 s->hgroup[i].htrees = NULL; |
1411 } | 1599 } |
1412 s->state = BROTLI_STATE_METABLOCK_BEGIN; | 1600 s->state = BROTLI_STATE_METABLOCK_BEGIN; |
1413 break; | 1601 break; |
1414 case BROTLI_STATE_DONE: | 1602 case BROTLI_STATE_DONE: |
1415 if (s->ringbuffer != 0) { | 1603 if (s->ringbuffer != 0) { |
1416 if (BrotliWrite(output, s->ringbuffer, | 1604 num_written = BrotliWrite( |
1417 (size_t)(pos & s->ringbuffer_mask)) < 0) { | 1605 output, s->ringbuffer + s->partially_written, |
| 1606 (size_t)((pos & s->ringbuffer_mask) - s->partially_written)); |
| 1607 if (num_written < 0) { |
1418 result = BROTLI_RESULT_ERROR; | 1608 result = BROTLI_RESULT_ERROR; |
1419 } | 1609 } |
| 1610 s->partially_written += num_written; |
| 1611 if (s->partially_written < (pos & s->ringbuffer_mask)) { |
| 1612 result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; |
| 1613 break; |
| 1614 } |
| 1615 } |
| 1616 if (!JumpToByteBoundary(&s->br)) { |
| 1617 result = BROTLI_RESULT_ERROR; |
1420 } | 1618 } |
1421 return result; | 1619 return result; |
1422 default: | 1620 default: |
1423 printf("Unknown state %d\n", s->state); | 1621 printf("Unknown state %d\n", s->state); |
1424 result = BROTLI_RESULT_ERROR; | 1622 result = BROTLI_RESULT_ERROR; |
1425 } | 1623 } |
1426 } | 1624 } |
1427 | 1625 |
1428 s->pos = pos; | 1626 s->pos = pos; |
1429 s->loop_counter = i; | 1627 s->loop_counter = i; |
1430 return result; | 1628 return result; |
1431 } | 1629 } |
1432 | 1630 |
1433 #if defined(__cplusplus) || defined(c_plusplus) | 1631 #if defined(__cplusplus) || defined(c_plusplus) |
1434 } /* extern "C" */ | 1632 } /* extern "C" */ |
1435 #endif | 1633 #endif |
OLD | NEW |