OLD | NEW |
(Empty) | |
| 1 /* Copyright 2013 Google Inc. All Rights Reserved. |
| 2 |
| 3 Licensed under the Apache License, Version 2.0 (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 |
| 6 |
| 7 http://www.apache.org/licenses/LICENSE-2.0 |
| 8 |
| 9 Unless required by applicable law or agreed to in writing, software |
| 10 distributed under the License is distributed on an "AS IS" BASIS, |
| 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 See the License for the specific language governing permissions and |
| 13 limitations under the License. |
| 14 */ |
| 15 |
| 16 #include <stdlib.h> |
| 17 #include <stdio.h> |
| 18 #include <string.h> |
| 19 #include "./bit_reader.h" |
| 20 #include "./context.h" |
| 21 #include "./decode.h" |
| 22 #include "./dictionary.h" |
| 23 #include "./transform.h" |
| 24 #include "./huffman.h" |
| 25 #include "./prefix.h" |
| 26 #include "./safe_malloc.h" |
| 27 |
| 28 #if defined(__cplusplus) || defined(c_plusplus) |
| 29 extern "C" { |
| 30 #endif |
| 31 |
| 32 #ifdef BROTLI_DECODE_DEBUG |
| 33 #define BROTLI_LOG_UINT(name) \ |
| 34 printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)) |
| 35 #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \ |
| 36 printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \ |
| 37 (unsigned long)(idx), (unsigned long)array_name[idx]) |
| 38 #else |
| 39 #define BROTLI_LOG_UINT(name) |
| 40 #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) |
| 41 #endif |
| 42 |
| 43 static const uint8_t kDefaultCodeLength = 8; |
| 44 static const uint8_t kCodeLengthRepeatCode = 16; |
| 45 static const int kNumLiteralCodes = 256; |
| 46 static const int kNumInsertAndCopyCodes = 704; |
| 47 static const int kNumBlockLengthCodes = 26; |
| 48 static const int kLiteralContextBits = 6; |
| 49 static const int kDistanceContextBits = 2; |
| 50 |
| 51 #define HUFFMAN_TABLE_BITS 8 |
| 52 #define HUFFMAN_TABLE_MASK 0xff |
| 53 /* Maximum possible Huffman table size for an alphabet size of 704, max code |
| 54 * length 15 and root table bits 8. */ |
| 55 #define HUFFMAN_MAX_TABLE_SIZE 1080 |
| 56 |
| 57 #define CODE_LENGTH_CODES 18 |
| 58 static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = { |
| 59 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
| 60 }; |
| 61 |
| 62 #define NUM_DISTANCE_SHORT_CODES 16 |
| 63 static const int kDistanceShortCodeIndexOffset[NUM_DISTANCE_SHORT_CODES] = { |
| 64 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 |
| 65 }; |
| 66 |
| 67 static const int kDistanceShortCodeValueOffset[NUM_DISTANCE_SHORT_CODES] = { |
| 68 0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3 |
| 69 }; |
| 70 |
| 71 static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) { |
| 72 if (BrotliReadBits(br, 1)) { |
| 73 return 17 + (int)BrotliReadBits(br, 3); |
| 74 } else { |
| 75 return 16; |
| 76 } |
| 77 } |
| 78 |
| 79 /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ |
| 80 static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) { |
| 81 if (BrotliReadBits(br, 1)) { |
| 82 int nbits = (int)BrotliReadBits(br, 3); |
| 83 if (nbits == 0) { |
| 84 return 1; |
| 85 } else { |
| 86 return (int)BrotliReadBits(br, nbits) + (1 << nbits); |
| 87 } |
| 88 } |
| 89 return 0; |
| 90 } |
| 91 |
| 92 static void DecodeMetaBlockLength(BrotliBitReader* br, |
| 93 int* meta_block_length, |
| 94 int* input_end, |
| 95 int* is_uncompressed) { |
| 96 int size_nibbles; |
| 97 int i; |
| 98 *input_end = (int)BrotliReadBits(br, 1); |
| 99 *meta_block_length = 0; |
| 100 *is_uncompressed = 0; |
| 101 if (*input_end && BrotliReadBits(br, 1)) { |
| 102 return; |
| 103 } |
| 104 size_nibbles = (int)BrotliReadBits(br, 2) + 4; |
| 105 for (i = 0; i < size_nibbles; ++i) { |
| 106 *meta_block_length |= (int)BrotliReadBits(br, 4) << (i * 4); |
| 107 } |
| 108 ++(*meta_block_length); |
| 109 if (!*input_end) { |
| 110 *is_uncompressed = (int)BrotliReadBits(br, 1); |
| 111 } |
| 112 } |
| 113 |
| 114 /* Decodes the next Huffman code from bit-stream. */ |
| 115 static BROTLI_INLINE int ReadSymbol(const HuffmanCode* table, |
| 116 BrotliBitReader* br) { |
| 117 int nbits; |
| 118 BrotliFillBitWindow(br); |
| 119 table += (int)(br->val_ >> br->bit_pos_) & HUFFMAN_TABLE_MASK; |
| 120 nbits = table->bits - HUFFMAN_TABLE_BITS; |
| 121 if (nbits > 0) { |
| 122 br->bit_pos_ += HUFFMAN_TABLE_BITS; |
| 123 table += table->value; |
| 124 table += (int)(br->val_ >> br->bit_pos_) & ((1 << nbits) - 1); |
| 125 } |
| 126 br->bit_pos_ += table->bits; |
| 127 return table->value; |
| 128 } |
| 129 |
| 130 static void PrintUcharVector(const uint8_t* v, int len) { |
| 131 while (len-- > 0) printf(" %d", *v++); |
| 132 printf("\n"); |
| 133 } |
| 134 |
| 135 static int ReadHuffmanCodeLengths( |
| 136 const uint8_t* code_length_code_lengths, |
| 137 int num_symbols, uint8_t* code_lengths, |
| 138 BrotliBitReader* br) { |
| 139 int symbol = 0; |
| 140 uint8_t prev_code_len = kDefaultCodeLength; |
| 141 int repeat = 0; |
| 142 uint8_t repeat_code_len = 0; |
| 143 int space = 32768; |
| 144 HuffmanCode table[32]; |
| 145 |
| 146 if (!BrotliBuildHuffmanTable(table, 5, |
| 147 code_length_code_lengths, |
| 148 CODE_LENGTH_CODES)) { |
| 149 printf("[ReadHuffmanCodeLengths] Building code length tree failed: "); |
| 150 PrintUcharVector(code_length_code_lengths, CODE_LENGTH_CODES); |
| 151 return 0; |
| 152 } |
| 153 |
| 154 while (symbol < num_symbols && space > 0) { |
| 155 const HuffmanCode* p = table; |
| 156 uint8_t code_len; |
| 157 if (!BrotliReadMoreInput(br)) { |
| 158 printf("[ReadHuffmanCodeLengths] Unexpected end of input.\n"); |
| 159 return 0; |
| 160 } |
| 161 BrotliFillBitWindow(br); |
| 162 p += (br->val_ >> br->bit_pos_) & 31; |
| 163 br->bit_pos_ += p->bits; |
| 164 code_len = (uint8_t)p->value; |
| 165 if (code_len < kCodeLengthRepeatCode) { |
| 166 repeat = 0; |
| 167 code_lengths[symbol++] = code_len; |
| 168 if (code_len != 0) { |
| 169 prev_code_len = code_len; |
| 170 space -= 32768 >> code_len; |
| 171 } |
| 172 } else { |
| 173 const int extra_bits = code_len - 14; |
| 174 int old_repeat; |
| 175 int repeat_delta; |
| 176 uint8_t new_len = 0; |
| 177 if (code_len == kCodeLengthRepeatCode) { |
| 178 new_len = prev_code_len; |
| 179 } |
| 180 if (repeat_code_len != new_len) { |
| 181 repeat = 0; |
| 182 repeat_code_len = new_len; |
| 183 } |
| 184 old_repeat = repeat; |
| 185 if (repeat > 0) { |
| 186 repeat -= 2; |
| 187 repeat <<= extra_bits; |
| 188 } |
| 189 repeat += (int)BrotliReadBits(br, extra_bits) + 3; |
| 190 repeat_delta = repeat - old_repeat; |
| 191 if (symbol + repeat_delta > num_symbols) { |
| 192 return 0; |
| 193 } |
| 194 memset(&code_lengths[symbol], repeat_code_len, (size_t)repeat_delta); |
| 195 symbol += repeat_delta; |
| 196 if (repeat_code_len != 0) { |
| 197 space -= repeat_delta << (15 - repeat_code_len); |
| 198 } |
| 199 } |
| 200 } |
| 201 if (space != 0) { |
| 202 printf("[ReadHuffmanCodeLengths] space = %d\n", space); |
| 203 return 0; |
| 204 } |
| 205 memset(&code_lengths[symbol], 0, (size_t)(num_symbols - symbol)); |
| 206 return 1; |
| 207 } |
| 208 |
| 209 static int ReadHuffmanCode(int alphabet_size, |
| 210 HuffmanCode* table, |
| 211 BrotliBitReader* br) { |
| 212 int ok = 1; |
| 213 int table_size = 0; |
| 214 int simple_code_or_skip; |
| 215 uint8_t* code_lengths = NULL; |
| 216 |
| 217 code_lengths = |
| 218 (uint8_t*)BrotliSafeMalloc((uint64_t)alphabet_size, |
| 219 sizeof(*code_lengths)); |
| 220 if (code_lengths == NULL) { |
| 221 return 0; |
| 222 } |
| 223 if (!BrotliReadMoreInput(br)) { |
| 224 printf("[ReadHuffmanCode] Unexpected end of input.\n"); |
| 225 return 0; |
| 226 } |
| 227 /* simple_code_or_skip is used as follows: |
| 228 1 for simple code; |
| 229 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ |
| 230 simple_code_or_skip = (int)BrotliReadBits(br, 2); |
| 231 BROTLI_LOG_UINT(simple_code_or_skip); |
| 232 if (simple_code_or_skip == 1) { |
| 233 /* Read symbols, codes & code lengths directly. */ |
| 234 int i; |
| 235 int max_bits_counter = alphabet_size - 1; |
| 236 int max_bits = 0; |
| 237 int symbols[4] = { 0 }; |
| 238 const int num_symbols = (int)BrotliReadBits(br, 2) + 1; |
| 239 while (max_bits_counter) { |
| 240 max_bits_counter >>= 1; |
| 241 ++max_bits; |
| 242 } |
| 243 memset(code_lengths, 0, (size_t)alphabet_size); |
| 244 for (i = 0; i < num_symbols; ++i) { |
| 245 symbols[i] = (int)BrotliReadBits(br, max_bits) % alphabet_size; |
| 246 code_lengths[symbols[i]] = 2; |
| 247 } |
| 248 code_lengths[symbols[0]] = 1; |
| 249 switch (num_symbols) { |
| 250 case 1: |
| 251 break; |
| 252 case 3: |
| 253 ok = ((symbols[0] != symbols[1]) && |
| 254 (symbols[0] != symbols[2]) && |
| 255 (symbols[1] != symbols[2])); |
| 256 break; |
| 257 case 2: |
| 258 ok = (symbols[0] != symbols[1]); |
| 259 code_lengths[symbols[1]] = 1; |
| 260 break; |
| 261 case 4: |
| 262 ok = ((symbols[0] != symbols[1]) && |
| 263 (symbols[0] != symbols[2]) && |
| 264 (symbols[0] != symbols[3]) && |
| 265 (symbols[1] != symbols[2]) && |
| 266 (symbols[1] != symbols[3]) && |
| 267 (symbols[2] != symbols[3])); |
| 268 if (BrotliReadBits(br, 1)) { |
| 269 code_lengths[symbols[2]] = 3; |
| 270 code_lengths[symbols[3]] = 3; |
| 271 } else { |
| 272 code_lengths[symbols[0]] = 2; |
| 273 } |
| 274 break; |
| 275 } |
| 276 BROTLI_LOG_UINT(num_symbols); |
| 277 } else { /* Decode Huffman-coded code lengths. */ |
| 278 int i; |
| 279 uint8_t code_length_code_lengths[CODE_LENGTH_CODES] = { 0 }; |
| 280 int space = 32; |
| 281 int num_codes = 0; |
| 282 /* Static Huffman code for the code length code lengths */ |
| 283 static const HuffmanCode huff[16] = { |
| 284 {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 1}, |
| 285 {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 5}, |
| 286 }; |
| 287 for (i = simple_code_or_skip; i < CODE_LENGTH_CODES && space > 0; ++i) { |
| 288 const int code_len_idx = kCodeLengthCodeOrder[i]; |
| 289 const HuffmanCode* p = huff; |
| 290 uint8_t v; |
| 291 BrotliFillBitWindow(br); |
| 292 p += (br->val_ >> br->bit_pos_) & 15; |
| 293 br->bit_pos_ += p->bits; |
| 294 v = (uint8_t)p->value; |
| 295 code_length_code_lengths[code_len_idx] = v; |
| 296 BROTLI_LOG_ARRAY_INDEX(code_length_code_lengths, code_len_idx); |
| 297 if (v != 0) { |
| 298 space -= (32 >> v); |
| 299 ++num_codes; |
| 300 } |
| 301 } |
| 302 ok = (num_codes == 1 || space == 0) && |
| 303 ReadHuffmanCodeLengths(code_length_code_lengths, |
| 304 alphabet_size, code_lengths, br); |
| 305 } |
| 306 if (ok) { |
| 307 table_size = BrotliBuildHuffmanTable(table, HUFFMAN_TABLE_BITS, |
| 308 code_lengths, alphabet_size); |
| 309 if (table_size == 0) { |
| 310 printf("[ReadHuffmanCode] BuildHuffmanTable failed: "); |
| 311 PrintUcharVector(code_lengths, alphabet_size); |
| 312 } |
| 313 } |
| 314 free(code_lengths); |
| 315 return table_size; |
| 316 } |
| 317 |
| 318 static BROTLI_INLINE int ReadBlockLength(const HuffmanCode* table, |
| 319 BrotliBitReader* br) { |
| 320 int code; |
| 321 int nbits; |
| 322 code = ReadSymbol(table, br); |
| 323 nbits = kBlockLengthPrefixCode[code].nbits; |
| 324 return kBlockLengthPrefixCode[code].offset + (int)BrotliReadBits(br, nbits); |
| 325 } |
| 326 |
| 327 static int TranslateShortCodes(int code, int* ringbuffer, int index) { |
| 328 int val; |
| 329 if (code < NUM_DISTANCE_SHORT_CODES) { |
| 330 index += kDistanceShortCodeIndexOffset[code]; |
| 331 index &= 3; |
| 332 val = ringbuffer[index] + kDistanceShortCodeValueOffset[code]; |
| 333 } else { |
| 334 val = code - NUM_DISTANCE_SHORT_CODES + 1; |
| 335 } |
| 336 return val; |
| 337 } |
| 338 |
| 339 static void MoveToFront(uint8_t* v, uint8_t index) { |
| 340 uint8_t value = v[index]; |
| 341 uint8_t i = index; |
| 342 for (; i; --i) v[i] = v[i - 1]; |
| 343 v[0] = value; |
| 344 } |
| 345 |
| 346 static void InverseMoveToFrontTransform(uint8_t* v, int v_len) { |
| 347 uint8_t mtf[256]; |
| 348 int i; |
| 349 for (i = 0; i < 256; ++i) { |
| 350 mtf[i] = (uint8_t)i; |
| 351 } |
| 352 for (i = 0; i < v_len; ++i) { |
| 353 uint8_t index = v[i]; |
| 354 v[i] = mtf[index]; |
| 355 if (index) MoveToFront(mtf, index); |
| 356 } |
| 357 } |
| 358 |
| 359 /* Contains a collection of huffman trees with the same alphabet size. */ |
| 360 typedef struct { |
| 361 int alphabet_size; |
| 362 int num_htrees; |
| 363 HuffmanCode* codes; |
| 364 HuffmanCode** htrees; |
| 365 } HuffmanTreeGroup; |
| 366 |
| 367 static void HuffmanTreeGroupInit(HuffmanTreeGroup* group, int alphabet_size, |
| 368 int ntrees) { |
| 369 group->alphabet_size = alphabet_size; |
| 370 group->num_htrees = ntrees; |
| 371 group->codes = (HuffmanCode*)malloc( |
| 372 sizeof(HuffmanCode) * (size_t)(ntrees * HUFFMAN_MAX_TABLE_SIZE)); |
| 373 group->htrees = (HuffmanCode**)malloc(sizeof(HuffmanCode*) * (size_t)ntrees); |
| 374 } |
| 375 |
| 376 static void HuffmanTreeGroupRelease(HuffmanTreeGroup* group) { |
| 377 if (group->codes) { |
| 378 free(group->codes); |
| 379 } |
| 380 if (group->htrees) { |
| 381 free(group->htrees); |
| 382 } |
| 383 } |
| 384 |
| 385 static int HuffmanTreeGroupDecode(HuffmanTreeGroup* group, |
| 386 BrotliBitReader* br) { |
| 387 int i; |
| 388 int table_size; |
| 389 HuffmanCode* next = group->codes; |
| 390 for (i = 0; i < group->num_htrees; ++i) { |
| 391 group->htrees[i] = next; |
| 392 table_size = ReadHuffmanCode(group->alphabet_size, next, br); |
| 393 next += table_size; |
| 394 if (table_size == 0) { |
| 395 return 0; |
| 396 } |
| 397 } |
| 398 return 1; |
| 399 } |
| 400 |
| 401 static int DecodeContextMap(int context_map_size, |
| 402 int* num_htrees, |
| 403 uint8_t** context_map, |
| 404 BrotliBitReader* br) { |
| 405 int ok = 1; |
| 406 int use_rle_for_zeros; |
| 407 int max_run_length_prefix = 0; |
| 408 HuffmanCode* table; |
| 409 int i; |
| 410 if (!BrotliReadMoreInput(br)) { |
| 411 printf("[DecodeContextMap] Unexpected end of input.\n"); |
| 412 return 0; |
| 413 } |
| 414 *num_htrees = DecodeVarLenUint8(br) + 1; |
| 415 |
| 416 BROTLI_LOG_UINT(context_map_size); |
| 417 BROTLI_LOG_UINT(*num_htrees); |
| 418 |
| 419 *context_map = (uint8_t*)malloc((size_t)context_map_size); |
| 420 if (*context_map == 0) { |
| 421 return 0; |
| 422 } |
| 423 if (*num_htrees <= 1) { |
| 424 memset(*context_map, 0, (size_t)context_map_size); |
| 425 return 1; |
| 426 } |
| 427 |
| 428 use_rle_for_zeros = (int)BrotliReadBits(br, 1); |
| 429 if (use_rle_for_zeros) { |
| 430 max_run_length_prefix = (int)BrotliReadBits(br, 4) + 1; |
| 431 } |
| 432 table = (HuffmanCode*)malloc(HUFFMAN_MAX_TABLE_SIZE * sizeof(*table)); |
| 433 if (table == NULL) { |
| 434 return 0; |
| 435 } |
| 436 if (!ReadHuffmanCode(*num_htrees + max_run_length_prefix, table, br)) { |
| 437 ok = 0; |
| 438 goto End; |
| 439 } |
| 440 for (i = 0; i < context_map_size;) { |
| 441 int code; |
| 442 if (!BrotliReadMoreInput(br)) { |
| 443 printf("[DecodeContextMap] Unexpected end of input.\n"); |
| 444 ok = 0; |
| 445 goto End; |
| 446 } |
| 447 code = ReadSymbol(table, br); |
| 448 if (code == 0) { |
| 449 (*context_map)[i] = 0; |
| 450 ++i; |
| 451 } else if (code <= max_run_length_prefix) { |
| 452 int reps = 1 + (1 << code) + (int)BrotliReadBits(br, code); |
| 453 while (--reps) { |
| 454 if (i >= context_map_size) { |
| 455 ok = 0; |
| 456 goto End; |
| 457 } |
| 458 (*context_map)[i] = 0; |
| 459 ++i; |
| 460 } |
| 461 } else { |
| 462 (*context_map)[i] = (uint8_t)(code - max_run_length_prefix); |
| 463 ++i; |
| 464 } |
| 465 } |
| 466 if (BrotliReadBits(br, 1)) { |
| 467 InverseMoveToFrontTransform(*context_map, context_map_size); |
| 468 } |
| 469 End: |
| 470 free(table); |
| 471 return ok; |
| 472 } |
| 473 |
| 474 static BROTLI_INLINE void DecodeBlockType(const int max_block_type, |
| 475 const HuffmanCode* trees, |
| 476 int tree_type, |
| 477 int* block_types, |
| 478 int* ringbuffers, |
| 479 int* indexes, |
| 480 BrotliBitReader* br) { |
| 481 int* ringbuffer = ringbuffers + tree_type * 2; |
| 482 int* index = indexes + tree_type; |
| 483 int type_code = ReadSymbol(&trees[tree_type * HUFFMAN_MAX_TABLE_SIZE], br); |
| 484 int block_type; |
| 485 if (type_code == 0) { |
| 486 block_type = ringbuffer[*index & 1]; |
| 487 } else if (type_code == 1) { |
| 488 block_type = ringbuffer[(*index - 1) & 1] + 1; |
| 489 } else { |
| 490 block_type = type_code - 2; |
| 491 } |
| 492 if (block_type >= max_block_type) { |
| 493 block_type -= max_block_type; |
| 494 } |
| 495 block_types[tree_type] = block_type; |
| 496 ringbuffer[(*index) & 1] = block_type; |
| 497 ++(*index); |
| 498 } |
| 499 |
| 500 /* Copy len bytes from src to dst. It can write up to ten extra bytes |
| 501 after the end of the copy. |
| 502 |
| 503 The main part of this loop is a simple copy of eight bytes at a time until |
| 504 we've copied (at least) the requested amount of bytes. However, if dst and |
| 505 src are less than eight bytes apart (indicating a repeating pattern of |
| 506 length < 8), we first need to expand the pattern in order to get the correct |
| 507 results. For instance, if the buffer looks like this, with the eight-byte |
| 508 <src> and <dst> patterns marked as intervals: |
| 509 |
| 510 abxxxxxxxxxxxx |
| 511 [------] src |
| 512 [------] dst |
| 513 |
| 514 a single eight-byte copy from <src> to <dst> will repeat the pattern once, |
| 515 after which we can move <dst> two bytes without moving <src>: |
| 516 |
| 517 ababxxxxxxxxxx |
| 518 [------] src |
| 519 [------] dst |
| 520 |
| 521 and repeat the exercise until the two no longer overlap. |
| 522 |
| 523 This allows us to do very well in the special case of one single byte |
| 524 repeated many times, without taking a big hit for more general cases. |
| 525 |
| 526 The worst case of extra writing past the end of the match occurs when |
| 527 dst - src == 1 and len == 1; the last copy will read from byte positions |
| 528 [0..7] and write to [4..11], whereas it was only supposed to write to |
| 529 position 1. Thus, ten excess bytes. |
| 530 */ |
| 531 static BROTLI_INLINE void IncrementalCopyFastPath( |
| 532 uint8_t* dst, const uint8_t* src, int len) { |
| 533 if (src < dst) { |
| 534 while (dst - src < 8) { |
| 535 UNALIGNED_MOVE64(dst, src); |
| 536 len -= (int)(dst - src); |
| 537 dst += dst - src; |
| 538 } |
| 539 } |
| 540 while (len > 0) { |
| 541 UNALIGNED_COPY64(dst, src); |
| 542 src += 8; |
| 543 dst += 8; |
| 544 len -= 8; |
| 545 } |
| 546 } |
| 547 |
| 548 int CopyUncompressedBlockToOutput(BrotliOutput output, int len, int pos, |
| 549 uint8_t* ringbuffer, int ringbuffer_mask, |
| 550 BrotliBitReader* br) { |
| 551 const int rb_size = ringbuffer_mask + 1; |
| 552 uint8_t* ringbuffer_end = ringbuffer + rb_size; |
| 553 int rb_pos = pos & ringbuffer_mask; |
| 554 int br_pos = br->pos_ & BROTLI_IBUF_MASK; |
| 555 int nbytes; |
| 556 |
| 557 /* For short lengths copy byte-by-byte */ |
| 558 if (len < 8 || br->bit_pos_ + (uint32_t)(len << 3) < br->bit_end_pos_) { |
| 559 while (len-- > 0) { |
| 560 if (!BrotliReadMoreInput(br)) { |
| 561 return 0; |
| 562 } |
| 563 ringbuffer[rb_pos++]= (uint8_t)BrotliReadBits(br, 8); |
| 564 if (rb_pos == rb_size) { |
| 565 if (BrotliWrite(output, ringbuffer, (size_t)rb_size) < rb_size) { |
| 566 return 0; |
| 567 } |
| 568 rb_pos = 0; |
| 569 } |
| 570 } |
| 571 return 1; |
| 572 } |
| 573 |
| 574 if (br->bit_end_pos_ < 64) { |
| 575 return 0; |
| 576 } |
| 577 |
| 578 /* Copy remaining 0-8 bytes from br->val_ to ringbuffer. */ |
| 579 while (br->bit_pos_ < 64) { |
| 580 ringbuffer[rb_pos] = (uint8_t)(br->val_ >> br->bit_pos_); |
| 581 br->bit_pos_ += 8; |
| 582 ++rb_pos; |
| 583 --len; |
| 584 } |
| 585 |
| 586 /* Copy remaining bytes from br->buf_ to ringbuffer. */ |
| 587 nbytes = (int)(br->bit_end_pos_ - br->bit_pos_) >> 3; |
| 588 if (br_pos + nbytes > BROTLI_IBUF_MASK) { |
| 589 int tail = BROTLI_IBUF_MASK + 1 - br_pos; |
| 590 memcpy(&ringbuffer[rb_pos], &br->buf_[br_pos], (size_t)tail); |
| 591 nbytes -= tail; |
| 592 rb_pos += tail; |
| 593 len -= tail; |
| 594 br_pos = 0; |
| 595 } |
| 596 memcpy(&ringbuffer[rb_pos], &br->buf_[br_pos], (size_t)nbytes); |
| 597 rb_pos += nbytes; |
| 598 len -= nbytes; |
| 599 |
| 600 /* If we wrote past the logical end of the ringbuffer, copy the tail of the |
| 601 ringbuffer to its beginning and flush the ringbuffer to the output. */ |
| 602 if (rb_pos >= rb_size) { |
| 603 if (BrotliWrite(output, ringbuffer, (size_t)rb_size) < rb_size) { |
| 604 return 0; |
| 605 } |
| 606 rb_pos -= rb_size; |
| 607 memcpy(ringbuffer, ringbuffer_end, (size_t)rb_pos); |
| 608 } |
| 609 |
| 610 /* If we have more to copy than the remaining size of the ringbuffer, then we |
| 611 first fill the ringbuffer from the input and then flush the ringbuffer to |
| 612 the output */ |
| 613 while (rb_pos + len >= rb_size) { |
| 614 nbytes = rb_size - rb_pos; |
| 615 if (BrotliRead(br->input_, &ringbuffer[rb_pos], (size_t)nbytes) < nbytes || |
| 616 BrotliWrite(output, ringbuffer, (size_t)rb_size) < nbytes) { |
| 617 return 0; |
| 618 } |
| 619 len -= nbytes; |
| 620 rb_pos = 0; |
| 621 } |
| 622 |
| 623 /* Copy straight from the input onto the ringbuffer. The ringbuffer will be |
| 624 flushed to the output at a later time. */ |
| 625 if (BrotliRead(br->input_, &ringbuffer[rb_pos], (size_t)len) < len) { |
| 626 return 0; |
| 627 } |
| 628 |
| 629 /* Restore the state of the bit reader. */ |
| 630 BrotliInitBitReader(br, br->input_); |
| 631 return 1; |
| 632 } |
| 633 |
| 634 int BrotliDecompressedSize(size_t encoded_size, |
| 635 const uint8_t* encoded_buffer, |
| 636 size_t* decoded_size) { |
| 637 int i; |
| 638 uint64_t val = 0; |
| 639 int bit_pos = 0; |
| 640 int is_last; |
| 641 int is_uncompressed = 0; |
| 642 int size_nibbles; |
| 643 int meta_block_len = 0; |
| 644 if (encoded_size == 0) { |
| 645 return 0; |
| 646 } |
| 647 /* Look at the first 8 bytes, it is enough to decode the length of the first |
| 648 meta-block. */ |
| 649 for (i = 0; (size_t)i < encoded_size && i < 8; ++i) { |
| 650 val |= (uint64_t)encoded_buffer[i] << (8 * i); |
| 651 } |
| 652 /* Skip the window bits. */ |
| 653 bit_pos += (val & 1) ? 4 : 1; |
| 654 /* Decode the ISLAST bit. */ |
| 655 is_last = (val >> bit_pos) & 1; |
| 656 ++bit_pos; |
| 657 if (is_last) { |
| 658 /* Decode the ISEMPTY bit, if it is set to 1, we are done. */ |
| 659 if ((val >> bit_pos) & 1) { |
| 660 *decoded_size = 0; |
| 661 return 1; |
| 662 } |
| 663 ++bit_pos; |
| 664 } |
| 665 /* Decode the length of the first meta-block. */ |
| 666 size_nibbles = (int)((val >> bit_pos) & 3) + 4; |
| 667 bit_pos += 2; |
| 668 for (i = 0; i < size_nibbles; ++i) { |
| 669 meta_block_len |= (int)((val >> bit_pos) & 0xf) << (4 * i); |
| 670 bit_pos += 4; |
| 671 } |
| 672 ++meta_block_len; |
| 673 if (is_last) { |
| 674 /* If this meta-block is the only one, we are done. */ |
| 675 *decoded_size = (size_t)meta_block_len; |
| 676 return 1; |
| 677 } |
| 678 is_uncompressed = (val >> bit_pos) & 1; |
| 679 ++bit_pos; |
| 680 if (is_uncompressed) { |
| 681 /* If the first meta-block is uncompressed, we skip it and look at the |
| 682 first two bits (ISLAST and ISEMPTY) of the next meta-block, and if |
| 683 both are set to 1, we have a stream with an uncompressed meta-block |
| 684 followed by an empty one, so the decompressed size is the size of the |
| 685 first meta-block. */ |
| 686 size_t offset = ((bit_pos + 7) >> 3) + meta_block_len; |
| 687 if (offset < encoded_size && ((encoded_buffer[offset] & 3) == 3)) { |
| 688 *decoded_size = (size_t)meta_block_len; |
| 689 return 1; |
| 690 } |
| 691 } |
| 692 return 0; |
| 693 } |
| 694 |
| 695 int BrotliDecompressBuffer(size_t encoded_size, |
| 696 const uint8_t* encoded_buffer, |
| 697 size_t* decoded_size, |
| 698 uint8_t* decoded_buffer) { |
| 699 BrotliMemInput memin; |
| 700 BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin); |
| 701 BrotliMemOutput mout; |
| 702 BrotliOutput out = BrotliInitMemOutput(decoded_buffer, *decoded_size, &mout); |
| 703 int success = BrotliDecompress(in, out); |
| 704 *decoded_size = mout.pos; |
| 705 return success; |
| 706 } |
| 707 |
| 708 int BrotliDecompress(BrotliInput input, BrotliOutput output) { |
| 709 int ok = 1; |
| 710 int i; |
| 711 int pos = 0; |
| 712 int input_end = 0; |
| 713 int window_bits = 0; |
| 714 int max_backward_distance; |
| 715 int max_distance = 0; |
| 716 int ringbuffer_size; |
| 717 int ringbuffer_mask; |
| 718 uint8_t* ringbuffer; |
| 719 uint8_t* ringbuffer_end; |
| 720 /* This ring buffer holds a few past copy distances that will be used by */ |
| 721 /* some special distance codes. */ |
| 722 int dist_rb[4] = { 16, 15, 11, 4 }; |
| 723 int dist_rb_idx = 0; |
| 724 /* The previous 2 bytes used for context. */ |
| 725 uint8_t prev_byte1 = 0; |
| 726 uint8_t prev_byte2 = 0; |
| 727 HuffmanTreeGroup hgroup[3]; |
| 728 HuffmanCode* block_type_trees = NULL; |
| 729 HuffmanCode* block_len_trees = NULL; |
| 730 BrotliBitReader br; |
| 731 |
| 732 /* We need the slack region for the following reasons: |
| 733 - always doing two 8-byte copies for fast backward copying |
| 734 - transforms |
| 735 - flushing the input ringbuffer when decoding uncompressed blocks */ |
| 736 static const int kRingBufferWriteAheadSlack = 128 + BROTLI_READ_SIZE; |
| 737 |
| 738 if (!BrotliInitBitReader(&br, input)) { |
| 739 return 0; |
| 740 } |
| 741 |
| 742 /* Decode window size. */ |
| 743 window_bits = DecodeWindowBits(&br); |
| 744 max_backward_distance = (1 << window_bits) - 16; |
| 745 |
| 746 ringbuffer_size = 1 << window_bits; |
| 747 ringbuffer_mask = ringbuffer_size - 1; |
| 748 ringbuffer = (uint8_t*)malloc((size_t)(ringbuffer_size + |
| 749 kRingBufferWriteAheadSlack + |
| 750 kMaxDictionaryWordLength)); |
| 751 if (!ringbuffer) { |
| 752 ok = 0; |
| 753 } |
| 754 ringbuffer_end = ringbuffer + ringbuffer_size; |
| 755 |
| 756 if (ok) { |
| 757 block_type_trees = (HuffmanCode*)malloc( |
| 758 3 * HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode)); |
| 759 block_len_trees = (HuffmanCode*)malloc( |
| 760 3 * HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode)); |
| 761 if (block_type_trees == NULL || block_len_trees == NULL) { |
| 762 ok = 0; |
| 763 } |
| 764 } |
| 765 |
| 766 while (!input_end && ok) { |
| 767 int meta_block_remaining_len = 0; |
| 768 int is_uncompressed; |
| 769 int block_length[3] = { 1 << 28, 1 << 28, 1 << 28 }; |
| 770 int block_type[3] = { 0 }; |
| 771 int num_block_types[3] = { 1, 1, 1 }; |
| 772 int block_type_rb[6] = { 0, 1, 0, 1, 0, 1 }; |
| 773 int block_type_rb_index[3] = { 0 }; |
| 774 int distance_postfix_bits; |
| 775 int num_direct_distance_codes; |
| 776 int distance_postfix_mask; |
| 777 int num_distance_codes; |
| 778 uint8_t* context_map = NULL; |
| 779 uint8_t* context_modes = NULL; |
| 780 int num_literal_htrees; |
| 781 uint8_t* dist_context_map = NULL; |
| 782 int num_dist_htrees; |
| 783 int context_offset = 0; |
| 784 uint8_t* context_map_slice = NULL; |
| 785 uint8_t literal_htree_index = 0; |
| 786 int dist_context_offset = 0; |
| 787 uint8_t* dist_context_map_slice = NULL; |
| 788 uint8_t dist_htree_index = 0; |
| 789 int context_lookup_offset1 = 0; |
| 790 int context_lookup_offset2 = 0; |
| 791 uint8_t context_mode; |
| 792 HuffmanCode* htree_command; |
| 793 |
| 794 for (i = 0; i < 3; ++i) { |
| 795 hgroup[i].codes = NULL; |
| 796 hgroup[i].htrees = NULL; |
| 797 } |
| 798 |
| 799 if (!BrotliReadMoreInput(&br)) { |
| 800 printf("[BrotliDecompress] Unexpected end of input.\n"); |
| 801 ok = 0; |
| 802 goto End; |
| 803 } |
| 804 BROTLI_LOG_UINT(pos); |
| 805 DecodeMetaBlockLength(&br, &meta_block_remaining_len, |
| 806 &input_end, &is_uncompressed); |
| 807 BROTLI_LOG_UINT(meta_block_remaining_len); |
| 808 if (meta_block_remaining_len == 0) { |
| 809 goto End; |
| 810 } |
| 811 if (is_uncompressed) { |
| 812 BrotliSetBitPos(&br, (br.bit_pos_ + 7) & (uint32_t)(~7UL)); |
| 813 ok = CopyUncompressedBlockToOutput(output, meta_block_remaining_len, pos, |
| 814 ringbuffer, ringbuffer_mask, &br); |
| 815 pos += meta_block_remaining_len; |
| 816 goto End; |
| 817 } |
| 818 for (i = 0; i < 3; ++i) { |
| 819 num_block_types[i] = DecodeVarLenUint8(&br) + 1; |
| 820 if (num_block_types[i] >= 2) { |
| 821 if (!ReadHuffmanCode(num_block_types[i] + 2, |
| 822 &block_type_trees[i * HUFFMAN_MAX_TABLE_SIZE], |
| 823 &br) || |
| 824 !ReadHuffmanCode(kNumBlockLengthCodes, |
| 825 &block_len_trees[i * HUFFMAN_MAX_TABLE_SIZE], |
| 826 &br)) { |
| 827 ok = 0; |
| 828 goto End; |
| 829 } |
| 830 block_length[i] = ReadBlockLength( |
| 831 &block_len_trees[i * HUFFMAN_MAX_TABLE_SIZE], &br); |
| 832 block_type_rb_index[i] = 1; |
| 833 } |
| 834 } |
| 835 |
| 836 BROTLI_LOG_UINT(num_block_types[0]); |
| 837 BROTLI_LOG_UINT(num_block_types[1]); |
| 838 BROTLI_LOG_UINT(num_block_types[2]); |
| 839 BROTLI_LOG_UINT(block_length[0]); |
| 840 BROTLI_LOG_UINT(block_length[1]); |
| 841 BROTLI_LOG_UINT(block_length[2]); |
| 842 |
| 843 if (!BrotliReadMoreInput(&br)) { |
| 844 printf("[BrotliDecompress] Unexpected end of input.\n"); |
| 845 ok = 0; |
| 846 goto End; |
| 847 } |
| 848 distance_postfix_bits = (int)BrotliReadBits(&br, 2); |
| 849 num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + |
| 850 ((int)BrotliReadBits(&br, 4) << distance_postfix_bits); |
| 851 distance_postfix_mask = (1 << distance_postfix_bits) - 1; |
| 852 num_distance_codes = (num_direct_distance_codes + |
| 853 (48 << distance_postfix_bits)); |
| 854 context_modes = (uint8_t*)malloc((size_t)num_block_types[0]); |
| 855 if (context_modes == 0) { |
| 856 ok = 0; |
| 857 goto End; |
| 858 } |
| 859 for (i = 0; i < num_block_types[0]; ++i) { |
| 860 context_modes[i] = (uint8_t)(BrotliReadBits(&br, 2) << 1); |
| 861 BROTLI_LOG_ARRAY_INDEX(context_modes, i); |
| 862 } |
| 863 BROTLI_LOG_UINT(num_direct_distance_codes); |
| 864 BROTLI_LOG_UINT(distance_postfix_bits); |
| 865 |
| 866 if (!DecodeContextMap(num_block_types[0] << kLiteralContextBits, |
| 867 &num_literal_htrees, &context_map, &br) || |
| 868 !DecodeContextMap(num_block_types[2] << kDistanceContextBits, |
| 869 &num_dist_htrees, &dist_context_map, &br)) { |
| 870 ok = 0; |
| 871 goto End; |
| 872 } |
| 873 |
| 874 HuffmanTreeGroupInit(&hgroup[0], kNumLiteralCodes, num_literal_htrees); |
| 875 HuffmanTreeGroupInit(&hgroup[1], kNumInsertAndCopyCodes, |
| 876 num_block_types[1]); |
| 877 HuffmanTreeGroupInit(&hgroup[2], num_distance_codes, num_dist_htrees); |
| 878 |
| 879 for (i = 0; i < 3; ++i) { |
| 880 if (!HuffmanTreeGroupDecode(&hgroup[i], &br)) { |
| 881 ok = 0; |
| 882 goto End; |
| 883 } |
| 884 } |
| 885 |
| 886 context_map_slice = context_map; |
| 887 dist_context_map_slice = dist_context_map; |
| 888 context_mode = context_modes[block_type[0]]; |
| 889 context_lookup_offset1 = kContextLookupOffsets[context_mode]; |
| 890 context_lookup_offset2 = kContextLookupOffsets[context_mode + 1]; |
| 891 htree_command = hgroup[1].htrees[0]; |
| 892 |
| 893 while (meta_block_remaining_len > 0) { |
| 894 int cmd_code; |
| 895 int range_idx; |
| 896 int insert_code; |
| 897 int copy_code; |
| 898 int insert_length; |
| 899 int copy_length; |
| 900 int distance_code; |
| 901 int distance; |
| 902 uint8_t context; |
| 903 int j; |
| 904 const uint8_t* copy_src; |
| 905 uint8_t* copy_dst; |
| 906 if (!BrotliReadMoreInput(&br)) { |
| 907 printf("[BrotliDecompress] Unexpected end of input.\n"); |
| 908 ok = 0; |
| 909 goto End; |
| 910 } |
| 911 if (block_length[1] == 0) { |
| 912 DecodeBlockType(num_block_types[1], |
| 913 block_type_trees, 1, block_type, block_type_rb, |
| 914 block_type_rb_index, &br); |
| 915 block_length[1] = ReadBlockLength( |
| 916 &block_len_trees[HUFFMAN_MAX_TABLE_SIZE], &br); |
| 917 htree_command = hgroup[1].htrees[block_type[1]]; |
| 918 } |
| 919 --block_length[1]; |
| 920 cmd_code = ReadSymbol(htree_command, &br); |
| 921 range_idx = cmd_code >> 6; |
| 922 if (range_idx >= 2) { |
| 923 range_idx -= 2; |
| 924 distance_code = -1; |
| 925 } else { |
| 926 distance_code = 0; |
| 927 } |
| 928 insert_code = kInsertRangeLut[range_idx] + ((cmd_code >> 3) & 7); |
| 929 copy_code = kCopyRangeLut[range_idx] + (cmd_code & 7); |
| 930 insert_length = kInsertLengthPrefixCode[insert_code].offset + |
| 931 (int)BrotliReadBits(&br, kInsertLengthPrefixCode[insert_code].nbits); |
| 932 copy_length = kCopyLengthPrefixCode[copy_code].offset + |
| 933 (int)BrotliReadBits(&br, kCopyLengthPrefixCode[copy_code].nbits); |
| 934 BROTLI_LOG_UINT(insert_length); |
| 935 BROTLI_LOG_UINT(copy_length); |
| 936 BROTLI_LOG_UINT(distance_code); |
| 937 for (j = 0; j < insert_length; ++j) { |
| 938 if (!BrotliReadMoreInput(&br)) { |
| 939 printf("[BrotliDecompress] Unexpected end of input.\n"); |
| 940 ok = 0; |
| 941 goto End; |
| 942 } |
| 943 if (block_length[0] == 0) { |
| 944 DecodeBlockType(num_block_types[0], |
| 945 block_type_trees, 0, block_type, block_type_rb, |
| 946 block_type_rb_index, &br); |
| 947 block_length[0] = ReadBlockLength(block_len_trees, &br); |
| 948 context_offset = block_type[0] << kLiteralContextBits; |
| 949 context_map_slice = context_map + context_offset; |
| 950 context_mode = context_modes[block_type[0]]; |
| 951 context_lookup_offset1 = kContextLookupOffsets[context_mode]; |
| 952 context_lookup_offset2 = kContextLookupOffsets[context_mode + 1]; |
| 953 } |
| 954 context = (kContextLookup[context_lookup_offset1 + prev_byte1] | |
| 955 kContextLookup[context_lookup_offset2 + prev_byte2]); |
| 956 BROTLI_LOG_UINT(context); |
| 957 literal_htree_index = context_map_slice[context]; |
| 958 --block_length[0]; |
| 959 prev_byte2 = prev_byte1; |
| 960 prev_byte1 = (uint8_t)ReadSymbol(hgroup[0].htrees[literal_htree_index], |
| 961 &br); |
| 962 ringbuffer[pos & ringbuffer_mask] = prev_byte1; |
| 963 BROTLI_LOG_UINT(literal_htree_index); |
| 964 BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos & ringbuffer_mask); |
| 965 if ((pos & ringbuffer_mask) == ringbuffer_mask) { |
| 966 if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) { |
| 967 ok = 0; |
| 968 goto End; |
| 969 } |
| 970 } |
| 971 ++pos; |
| 972 } |
| 973 meta_block_remaining_len -= insert_length; |
| 974 if (meta_block_remaining_len <= 0) break; |
| 975 |
| 976 if (distance_code < 0) { |
| 977 uint8_t context; |
| 978 if (!BrotliReadMoreInput(&br)) { |
| 979 printf("[BrotliDecompress] Unexpected end of input.\n"); |
| 980 ok = 0; |
| 981 goto End; |
| 982 } |
| 983 if (block_length[2] == 0) { |
| 984 DecodeBlockType(num_block_types[2], |
| 985 block_type_trees, 2, block_type, block_type_rb, |
| 986 block_type_rb_index, &br); |
| 987 block_length[2] = ReadBlockLength( |
| 988 &block_len_trees[2 * HUFFMAN_MAX_TABLE_SIZE], &br); |
| 989 dist_context_offset = block_type[2] << kDistanceContextBits; |
| 990 dist_context_map_slice = dist_context_map + dist_context_offset; |
| 991 } |
| 992 --block_length[2]; |
| 993 context = (uint8_t)(copy_length > 4 ? 3 : copy_length - 2); |
| 994 dist_htree_index = dist_context_map_slice[context]; |
| 995 distance_code = ReadSymbol(hgroup[2].htrees[dist_htree_index], &br); |
| 996 if (distance_code >= num_direct_distance_codes) { |
| 997 int nbits; |
| 998 int postfix; |
| 999 int offset; |
| 1000 distance_code -= num_direct_distance_codes; |
| 1001 postfix = distance_code & distance_postfix_mask; |
| 1002 distance_code >>= distance_postfix_bits; |
| 1003 nbits = (distance_code >> 1) + 1; |
| 1004 offset = ((2 + (distance_code & 1)) << nbits) - 4; |
| 1005 distance_code = num_direct_distance_codes + |
| 1006 ((offset + (int)BrotliReadBits(&br, nbits)) << |
| 1007 distance_postfix_bits) + postfix; |
| 1008 } |
| 1009 } |
| 1010 |
| 1011 /* Convert the distance code to the actual distance by possibly looking */ |
| 1012 /* up past distnaces from the ringbuffer. */ |
| 1013 distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx); |
| 1014 if (distance < 0) { |
| 1015 ok = 0; |
| 1016 goto End; |
| 1017 } |
| 1018 BROTLI_LOG_UINT(distance); |
| 1019 |
| 1020 if (pos < max_backward_distance && |
| 1021 max_distance != max_backward_distance) { |
| 1022 max_distance = pos; |
| 1023 } else { |
| 1024 max_distance = max_backward_distance; |
| 1025 } |
| 1026 |
| 1027 copy_dst = &ringbuffer[pos & ringbuffer_mask]; |
| 1028 |
| 1029 if (distance > max_distance) { |
| 1030 if (copy_length >= kMinDictionaryWordLength && |
| 1031 copy_length <= kMaxDictionaryWordLength) { |
| 1032 int offset = kBrotliDictionaryOffsetsByLength[copy_length]; |
| 1033 int word_id = distance - max_distance - 1; |
| 1034 int shift = kBrotliDictionarySizeBitsByLength[copy_length]; |
| 1035 int mask = (1 << shift) - 1; |
| 1036 int word_idx = word_id & mask; |
| 1037 int transform_idx = word_id >> shift; |
| 1038 offset += word_idx * copy_length; |
| 1039 if (transform_idx < kNumTransforms) { |
| 1040 const uint8_t* word = &kBrotliDictionary[offset]; |
| 1041 int len = TransformDictionaryWord( |
| 1042 copy_dst, word, copy_length, transform_idx); |
| 1043 copy_dst += len; |
| 1044 pos += len; |
| 1045 meta_block_remaining_len -= len; |
| 1046 if (copy_dst >= ringbuffer_end) { |
| 1047 if (BrotliWrite(output, ringbuffer, |
| 1048 (size_t)ringbuffer_size) < 0) { |
| 1049 ok = 0; |
| 1050 goto End; |
| 1051 } |
| 1052 memcpy(ringbuffer, ringbuffer_end, |
| 1053 (size_t)(copy_dst - ringbuffer_end)); |
| 1054 } |
| 1055 } else { |
| 1056 printf("Invalid backward reference. pos: %d distance: %d " |
| 1057 "len: %d bytes left: %d\n", pos, distance, copy_length, |
| 1058 meta_block_remaining_len); |
| 1059 ok = 0; |
| 1060 goto End; |
| 1061 } |
| 1062 } else { |
| 1063 printf("Invalid backward reference. pos: %d distance: %d " |
| 1064 "len: %d bytes left: %d\n", pos, distance, copy_length, |
| 1065 meta_block_remaining_len); |
| 1066 ok = 0; |
| 1067 goto End; |
| 1068 } |
| 1069 } else { |
| 1070 if (distance_code > 0) { |
| 1071 dist_rb[dist_rb_idx & 3] = distance; |
| 1072 ++dist_rb_idx; |
| 1073 } |
| 1074 |
| 1075 if (copy_length > meta_block_remaining_len) { |
| 1076 printf("Invalid backward reference. pos: %d distance: %d " |
| 1077 "len: %d bytes left: %d\n", pos, distance, copy_length, |
| 1078 meta_block_remaining_len); |
| 1079 ok = 0; |
| 1080 goto End; |
| 1081 } |
| 1082 |
| 1083 copy_src = &ringbuffer[(pos - distance) & ringbuffer_mask]; |
| 1084 |
| 1085 #if (defined(__x86_64__) || defined(_M_X64)) |
| 1086 if (copy_src + copy_length <= ringbuffer_end && |
| 1087 copy_dst + copy_length < ringbuffer_end) { |
| 1088 if (copy_length <= 16 && distance >= 8) { |
| 1089 UNALIGNED_COPY64(copy_dst, copy_src); |
| 1090 UNALIGNED_COPY64(copy_dst + 8, copy_src + 8); |
| 1091 } else { |
| 1092 IncrementalCopyFastPath(copy_dst, copy_src, copy_length); |
| 1093 } |
| 1094 pos += copy_length; |
| 1095 meta_block_remaining_len -= copy_length; |
| 1096 copy_length = 0; |
| 1097 } |
| 1098 #endif |
| 1099 |
| 1100 for (j = 0; j < copy_length; ++j) { |
| 1101 ringbuffer[pos & ringbuffer_mask] = |
| 1102 ringbuffer[(pos - distance) & ringbuffer_mask]; |
| 1103 if ((pos & ringbuffer_mask) == ringbuffer_mask) { |
| 1104 if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) { |
| 1105 ok = 0; |
| 1106 goto End; |
| 1107 } |
| 1108 } |
| 1109 ++pos; |
| 1110 --meta_block_remaining_len; |
| 1111 } |
| 1112 } |
| 1113 |
| 1114 /* When we get here, we must have inserted at least one literal and */ |
| 1115 /* made a copy of at least length two, therefore accessing the last 2 */ |
| 1116 /* bytes is valid. */ |
| 1117 prev_byte1 = ringbuffer[(pos - 1) & ringbuffer_mask]; |
| 1118 prev_byte2 = ringbuffer[(pos - 2) & ringbuffer_mask]; |
| 1119 } |
| 1120 |
| 1121 /* Protect pos from overflow, wrap it around at every GB of input data */ |
| 1122 pos &= 0x3fffffff; |
| 1123 |
| 1124 End: |
| 1125 if (context_modes != 0) { |
| 1126 free(context_modes); |
| 1127 } |
| 1128 if (context_map != 0) { |
| 1129 free(context_map); |
| 1130 } |
| 1131 if (dist_context_map != 0) { |
| 1132 free(dist_context_map); |
| 1133 } |
| 1134 for (i = 0; i < 3; ++i) { |
| 1135 HuffmanTreeGroupRelease(&hgroup[i]); |
| 1136 } |
| 1137 } |
| 1138 |
| 1139 if (ringbuffer != 0) { |
| 1140 if (BrotliWrite(output, ringbuffer, (size_t)(pos & ringbuffer_mask)) < 0) { |
| 1141 ok = 0; |
| 1142 } |
| 1143 free(ringbuffer); |
| 1144 } |
| 1145 if (block_type_trees != 0) { |
| 1146 free(block_type_trees); |
| 1147 } |
| 1148 if (block_len_trees != 0) { |
| 1149 free(block_len_trees); |
| 1150 } |
| 1151 return ok; |
| 1152 } |
| 1153 |
| 1154 #if defined(__cplusplus) || defined(c_plusplus) |
| 1155 } /* extern "C" */ |
| 1156 #endif |
OLD | NEW |