| 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 |