| OLD | NEW |
| 1 /* Copyright 2013 Google Inc. All Rights Reserved. | 1 /* Copyright 2013 Google Inc. All Rights Reserved. |
| 2 | 2 |
| 3 Distributed under MIT license. | 3 Distributed under MIT license. |
| 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "./decode.h" | 7 #include "./decode.h" |
| 8 | 8 |
| 9 #ifdef __ARM_NEON__ | 9 #ifdef __ARM_NEON__ |
| 10 #include <arm_neon.h> | 10 #include <arm_neon.h> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include <stdio.h> /* printf (debug output) */ | |
| 14 #include <stdlib.h> /* free, malloc */ | 13 #include <stdlib.h> /* free, malloc */ |
| 15 #include <string.h> /* memcpy, memset */ | 14 #include <string.h> /* memcpy, memset */ |
| 16 | 15 |
| 17 #include "./bit_reader.h" | 16 #include "./bit_reader.h" |
| 18 #include "./context.h" | 17 #include "./context.h" |
| 19 #include "./dictionary.h" | 18 #include "./dictionary.h" |
| 20 #include "./huffman.h" | 19 #include "./huffman.h" |
| 21 #include "./port.h" | 20 #include "./port.h" |
| 22 #include "./prefix.h" | 21 #include "./prefix.h" |
| 22 #include "./state.h" |
| 23 #include "./transform.h" | 23 #include "./transform.h" |
| 24 | 24 |
| 25 #if defined(__cplusplus) || defined(c_plusplus) | 25 #if defined(__cplusplus) || defined(c_plusplus) |
| 26 extern "C" { | 26 extern "C" { |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 /* BROTLI_FAILURE macro unwraps to BROTLI_RESULT_ERROR in non-debug build. */ | 29 #define BROTLI_FAILURE() (BROTLI_DUMP(), BROTLI_RESULT_ERROR) |
| 30 /* In debug build it dumps file name, line and pretty function name. */ | |
| 31 #if defined(_MSC_VER) || \ | |
| 32 (!defined(BROTLI_DEBUG) && !defined(BROTLI_DECODE_DEBUG)) | |
| 33 #define BROTLI_FAILURE() BROTLI_RESULT_ERROR | |
| 34 #else | |
| 35 #define BROTLI_FAILURE() BrotliFailure(__FILE__, __LINE__, __PRETTY_FUNCTION__) | |
| 36 static inline BrotliResult BrotliFailure(const char* f, int l, const char* fn) { | |
| 37 fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn); | |
| 38 fflush(stderr); | |
| 39 return BROTLI_RESULT_ERROR; | |
| 40 } | |
| 41 #endif | |
| 42 | 30 |
| 43 #ifdef BROTLI_DECODE_DEBUG | |
| 44 #define BROTLI_LOG_UINT(name) \ | 31 #define BROTLI_LOG_UINT(name) \ |
| 45 printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)) | 32 BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))) |
| 46 #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \ | 33 #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \ |
| 47 printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \ | 34 BROTLI_LOG(("[%s] %s[%lu] = %lu\n", __func__, #array_name, \ |
| 48 (unsigned long)(idx), (unsigned long)array_name[idx]) | 35 (unsigned long)(idx), (unsigned long)array_name[idx])) |
| 49 #define BROTLI_LOG(x) printf x | |
| 50 #else | |
| 51 #define BROTLI_LOG_UINT(name) | |
| 52 #define BROTLI_LOG_ARRAY_INDEX(array_name, idx) | |
| 53 #define BROTLI_LOG(x) | |
| 54 #endif | |
| 55 | 36 |
| 56 static const uint32_t kDefaultCodeLength = 8; | 37 static const uint32_t kDefaultCodeLength = 8; |
| 57 static const uint32_t kCodeLengthRepeatCode = 16; | 38 static const uint32_t kCodeLengthRepeatCode = 16; |
| 58 static const uint32_t kNumLiteralCodes = 256; | 39 static const uint32_t kNumLiteralCodes = 256; |
| 59 static const uint32_t kNumInsertAndCopyCodes = 704; | 40 static const uint32_t kNumInsertAndCopyCodes = 704; |
| 60 static const uint32_t kNumBlockLengthCodes = 26; | 41 static const uint32_t kNumBlockLengthCodes = 26; |
| 61 static const int kLiteralContextBits = 6; | 42 static const int kLiteralContextBits = 6; |
| 62 static const int kDistanceContextBits = 2; | 43 static const int kDistanceContextBits = 2; |
| 63 | 44 |
| 64 #define HUFFMAN_TABLE_BITS 8U | 45 #define HUFFMAN_TABLE_BITS 8U |
| (...skipping 17 matching lines...) Expand all Loading... |
| 82 | 63 |
| 83 BrotliState* BrotliCreateState( | 64 BrotliState* BrotliCreateState( |
| 84 brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { | 65 brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { |
| 85 BrotliState* state = 0; | 66 BrotliState* state = 0; |
| 86 if (!alloc_func && !free_func) { | 67 if (!alloc_func && !free_func) { |
| 87 state = (BrotliState*)malloc(sizeof(BrotliState)); | 68 state = (BrotliState*)malloc(sizeof(BrotliState)); |
| 88 } else if (alloc_func && free_func) { | 69 } else if (alloc_func && free_func) { |
| 89 state = (BrotliState*)alloc_func(opaque, sizeof(BrotliState)); | 70 state = (BrotliState*)alloc_func(opaque, sizeof(BrotliState)); |
| 90 } | 71 } |
| 91 if (state == 0) { | 72 if (state == 0) { |
| 92 (void)BROTLI_FAILURE(); | 73 BROTLI_DUMP(); |
| 93 return 0; | 74 return 0; |
| 94 } | 75 } |
| 95 BrotliStateInitWithCustomAllocators(state, alloc_func, free_func, opaque); | 76 BrotliStateInitWithCustomAllocators(state, alloc_func, free_func, opaque); |
| 96 return state; | 77 return state; |
| 97 } | 78 } |
| 98 | 79 |
| 99 /* Deinitializes and frees BrotliState instance. */ | 80 /* Deinitializes and frees BrotliState instance. */ |
| 100 void BrotliDestroyState(BrotliState* state) { | 81 void BrotliDestroyState(BrotliState* state) { |
| 101 if (!state) { | 82 if (!state) { |
| 102 return; | 83 return; |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 BrotliBitReader* br, | 350 BrotliBitReader* br, |
| 370 uint32_t* result) { | 351 uint32_t* result) { |
| 371 uint32_t val; | 352 uint32_t val; |
| 372 if (PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) { | 353 if (PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) { |
| 373 *result = DecodeSymbol(val, table, br); | 354 *result = DecodeSymbol(val, table, br); |
| 374 return 1; | 355 return 1; |
| 375 } | 356 } |
| 376 return SafeDecodeSymbol(table, br, result); | 357 return SafeDecodeSymbol(table, br, result); |
| 377 } | 358 } |
| 378 | 359 |
| 379 | |
| 380 /* Makes a look-up in first level Huffman table. Peeks 8 bits. */ | 360 /* Makes a look-up in first level Huffman table. Peeks 8 bits. */ |
| 381 static BROTLI_INLINE void PreloadSymbol(int safe, | 361 static BROTLI_INLINE void PreloadSymbol(int safe, |
| 382 const HuffmanCode* table, | 362 const HuffmanCode* table, |
| 383 BrotliBitReader* br, | 363 BrotliBitReader* br, |
| 384 uint32_t* bits, | 364 uint32_t* bits, |
| 385 uint32_t* value) { | 365 uint32_t* value) { |
| 386 if (safe) { | 366 if (safe) { |
| 387 return; | 367 return; |
| 388 } | 368 } |
| 389 table += BrotliGetBits(br, HUFFMAN_TABLE_BITS); | 369 table += BrotliGetBits(br, HUFFMAN_TABLE_BITS); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 *repeat_code_len = new_len; | 487 *repeat_code_len = new_len; |
| 508 } | 488 } |
| 509 old_repeat = *repeat; | 489 old_repeat = *repeat; |
| 510 if (*repeat > 0) { | 490 if (*repeat > 0) { |
| 511 *repeat -= 2; | 491 *repeat -= 2; |
| 512 *repeat <<= code_len - 14U; | 492 *repeat <<= code_len - 14U; |
| 513 } | 493 } |
| 514 *repeat += repeat_delta + 3U; | 494 *repeat += repeat_delta + 3U; |
| 515 repeat_delta = *repeat - old_repeat; | 495 repeat_delta = *repeat - old_repeat; |
| 516 if (*symbol + repeat_delta > alphabet_size) { | 496 if (*symbol + repeat_delta > alphabet_size) { |
| 517 (void)BROTLI_FAILURE(); | 497 BROTLI_DUMP(); |
| 518 *symbol = alphabet_size; | 498 *symbol = alphabet_size; |
| 519 *space = 0xFFFFF; | 499 *space = 0xFFFFF; |
| 520 return; | 500 return; |
| 521 } | 501 } |
| 522 BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n", | 502 BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n", |
| 523 *symbol, *symbol + repeat_delta - 1, *repeat_code_len)); | 503 *symbol, *symbol + repeat_delta - 1, *repeat_code_len)); |
| 524 if (*repeat_code_len != 0) { | 504 if (*repeat_code_len != 0) { |
| 525 unsigned last = *symbol + repeat_delta; | 505 unsigned last = *symbol + repeat_delta; |
| 526 int next = next_symbol[*repeat_code_len]; | 506 int next = next_symbol[*repeat_code_len]; |
| 527 do { | 507 do { |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 do { | 859 do { |
| 880 index--; | 860 index--; |
| 881 mtf[index + 1] = mtf[index]; | 861 mtf[index + 1] = mtf[index]; |
| 882 } while (index > 0); | 862 } while (index > 0); |
| 883 mtf[0] = value; | 863 mtf[0] = value; |
| 884 } | 864 } |
| 885 /* Remember amount of elements to be reinitialized. */ | 865 /* Remember amount of elements to be reinitialized. */ |
| 886 state->mtf_upper_bound = upper_bound; | 866 state->mtf_upper_bound = upper_bound; |
| 887 } | 867 } |
| 888 | 868 |
| 889 | |
| 890 /* Decodes a series of Huffman table using ReadHuffmanCode function. */ | 869 /* Decodes a series of Huffman table using ReadHuffmanCode function. */ |
| 891 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, | 870 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, |
| 892 BrotliState* s) { | 871 BrotliState* s) { |
| 893 if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) { | 872 if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) { |
| 894 s->next = group->codes; | 873 s->next = group->codes; |
| 895 s->htree_index = 0; | 874 s->htree_index = 0; |
| 896 s->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP; | 875 s->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP; |
| 897 } | 876 } |
| 898 while (s->htree_index < group->num_htrees) { | 877 while (s->htree_index < group->num_htrees) { |
| 899 uint32_t table_size; | 878 uint32_t table_size; |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 return result; | 1220 return result; |
| 1242 } | 1221 } |
| 1243 s->pos = 0; | 1222 s->pos = 0; |
| 1244 s->rb_roundtrips++; | 1223 s->rb_roundtrips++; |
| 1245 s->max_distance = s->max_backward_distance; | 1224 s->max_distance = s->max_backward_distance; |
| 1246 s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE; | 1225 s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE; |
| 1247 break; | 1226 break; |
| 1248 } | 1227 } |
| 1249 } | 1228 } |
| 1250 } | 1229 } |
| 1251 return BROTLI_FAILURE(); | 1230 BROTLI_DCHECK(0); /* Unreachable */ |
| 1252 } | 1231 } |
| 1253 | 1232 |
| 1254 int BrotliDecompressedSize(size_t encoded_size, | 1233 int BrotliDecompressedSize(size_t encoded_size, |
| 1255 const uint8_t* encoded_buffer, | 1234 const uint8_t* encoded_buffer, |
| 1256 size_t* decoded_size) { | 1235 size_t* decoded_size) { |
| 1257 BrotliState s; | 1236 BrotliState s; |
| 1258 int next_block_header; | 1237 int next_block_header; |
| 1259 BrotliStateInit(&s); | 1238 BrotliStateInit(&s); |
| 1260 s.br.next_in = encoded_buffer; | 1239 s.br.next_in = encoded_buffer; |
| 1261 s.br.avail_in = encoded_size; | 1240 s.br.avail_in = encoded_size; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1280 /* Calculates the smallest feasible ring buffer. | 1259 /* Calculates the smallest feasible ring buffer. |
| 1281 | 1260 |
| 1282 If we know the data size is small, do not allocate more ringbuffer | 1261 If we know the data size is small, do not allocate more ringbuffer |
| 1283 size than needed to reduce memory usage. | 1262 size than needed to reduce memory usage. |
| 1284 | 1263 |
| 1285 When this method is called, metablock size and flags MUST be decoded. | 1264 When this method is called, metablock size and flags MUST be decoded. |
| 1286 */ | 1265 */ |
| 1287 static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s, | 1266 static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s, |
| 1288 BrotliBitReader* br) { | 1267 BrotliBitReader* br) { |
| 1289 int is_last = s->is_last_metablock; | 1268 int is_last = s->is_last_metablock; |
| 1290 s->ringbuffer_size = 1 << s->window_bits; | 1269 int window_size = 1 << s->window_bits; |
| 1270 s->ringbuffer_size = window_size; |
| 1291 | 1271 |
| 1292 if (s->is_uncompressed) { | 1272 if (s->is_uncompressed) { |
| 1293 int next_block_header = | 1273 int next_block_header = |
| 1294 BrotliPeekByte(br, (size_t)s->meta_block_remaining_len); | 1274 BrotliPeekByte(br, (size_t)s->meta_block_remaining_len); |
| 1295 if (next_block_header != -1) { /* Peek succeeded */ | 1275 if (next_block_header != -1) { /* Peek succeeded */ |
| 1296 if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */ | 1276 if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */ |
| 1297 is_last = 1; | 1277 is_last = 1; |
| 1298 } | 1278 } |
| 1299 } | 1279 } |
| 1300 } | 1280 } |
| 1301 | 1281 |
| 1282 /* Limit custom dictionary size to stream window size. */ |
| 1283 if (s->custom_dict_size >= window_size) { |
| 1284 s->custom_dict += s->custom_dict_size - window_size; |
| 1285 s->custom_dict_size = window_size; |
| 1286 } |
| 1287 |
| 1302 /* We need at least 2 bytes of ring buffer size to get the last two | 1288 /* We need at least 2 bytes of ring buffer size to get the last two |
| 1303 bytes for context from there */ | 1289 bytes for context from there */ |
| 1304 if (is_last) { | 1290 if (is_last) { |
| 1305 while (s->ringbuffer_size >= s->meta_block_remaining_len * 2 && | 1291 int min_size_x2 = (s->meta_block_remaining_len + s->custom_dict_size) * 2; |
| 1306 s->ringbuffer_size > 32) { | 1292 while (s->ringbuffer_size >= min_size_x2 && s->ringbuffer_size > 32) { |
| 1307 s->ringbuffer_size >>= 1; | 1293 s->ringbuffer_size >>= 1; |
| 1308 } | 1294 } |
| 1309 } | 1295 } |
| 1310 | 1296 |
| 1311 /* But make it fit the custom dictionary if there is one. */ | |
| 1312 while (s->ringbuffer_size < s->custom_dict_size) { | |
| 1313 s->ringbuffer_size <<= 1; | |
| 1314 } | |
| 1315 | |
| 1316 s->ringbuffer_mask = s->ringbuffer_size - 1; | 1297 s->ringbuffer_mask = s->ringbuffer_size - 1; |
| 1317 } | 1298 } |
| 1318 | 1299 |
| 1319 /* Reads 1..256 2-bit context modes. */ | 1300 /* Reads 1..256 2-bit context modes. */ |
| 1320 static BrotliResult ReadContextModes(BrotliState* s) { | 1301 static BrotliResult ReadContextModes(BrotliState* s) { |
| 1321 BrotliBitReader* br = &s->br; | 1302 BrotliBitReader* br = &s->br; |
| 1322 int i = s->loop_counter; | 1303 int i = s->loop_counter; |
| 1323 | 1304 |
| 1324 while (i < (int)s->num_block_types[0]) { | 1305 while (i < (int)s->num_block_types[0]) { |
| 1325 uint32_t bits; | 1306 uint32_t bits; |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 void BrotliSetCustomDictionary( | 2209 void BrotliSetCustomDictionary( |
| 2229 size_t size, const uint8_t* dict, BrotliState* s) { | 2210 size_t size, const uint8_t* dict, BrotliState* s) { |
| 2230 s->custom_dict = dict; | 2211 s->custom_dict = dict; |
| 2231 s->custom_dict_size = (int)size; | 2212 s->custom_dict_size = (int)size; |
| 2232 } | 2213 } |
| 2233 | 2214 |
| 2234 | 2215 |
| 2235 #if defined(__cplusplus) || defined(c_plusplus) | 2216 #if defined(__cplusplus) || defined(c_plusplus) |
| 2236 } /* extern "C" */ | 2217 } /* extern "C" */ |
| 2237 #endif | 2218 #endif |
| OLD | NEW |