| 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> |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 of Y values, and reinitialize only first elements in L. | 828 of Y values, and reinitialize only first elements in L. |
| 829 | 829 |
| 830 Most of input values are 0 and 1. To reduce number of branches, we replace | 830 Most of input values are 0 and 1. To reduce number of branches, we replace |
| 831 inner for loop with do-while. | 831 inner for loop with do-while. |
| 832 */ | 832 */ |
| 833 static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v, | 833 static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v, |
| 834 uint32_t v_len, BrotliState* state) { | 834 uint32_t v_len, BrotliState* state) { |
| 835 /* Reinitialize elements that could have been changed. */ | 835 /* Reinitialize elements that could have been changed. */ |
| 836 uint32_t i = 4; | 836 uint32_t i = 4; |
| 837 uint32_t upper_bound = state->mtf_upper_bound; | 837 uint32_t upper_bound = state->mtf_upper_bound; |
| 838 uint8_t* mtf = state->mtf; | 838 uint8_t* mtf = &state->mtf[4]; /* Make mtf[-1] addressable. */ |
| 839 /* Load endian-aware constant. */ | 839 /* Load endian-aware constant. */ |
| 840 const uint8_t b0123[4] = {0, 1, 2, 3}; | 840 const uint8_t b0123[4] = {0, 1, 2, 3}; |
| 841 uint32_t pattern; | 841 uint32_t pattern; |
| 842 memcpy(&pattern, &b0123, 4); | 842 memcpy(&pattern, &b0123, 4); |
| 843 | 843 |
| 844 /* Initialize list using 4 consequent values pattern. */ | 844 /* Initialize list using 4 consequent values pattern. */ |
| 845 *(uint32_t*)mtf = pattern; | 845 *(uint32_t*)mtf = pattern; |
| 846 do { | 846 do { |
| 847 pattern += 0x04040404; /* Advance all 4 values by 4. */ | 847 pattern += 0x04040404; /* Advance all 4 values by 4. */ |
| 848 *(uint32_t*)(mtf + i) = pattern; | 848 *(uint32_t*)(mtf + i) = pattern; |
| 849 i += 4; | 849 i += 4; |
| 850 } while (i <= upper_bound); | 850 } while (i <= upper_bound); |
| 851 | 851 |
| 852 /* Transform the input. */ | 852 /* Transform the input. */ |
| 853 upper_bound = 0; | 853 upper_bound = 0; |
| 854 for (i = 0; i < v_len; ++i) { | 854 for (i = 0; i < v_len; ++i) { |
| 855 int index = v[i]; | 855 int index = v[i]; |
| 856 uint8_t value = mtf[index]; | 856 uint8_t value = mtf[index]; |
| 857 upper_bound |= v[i]; | 857 upper_bound |= v[i]; |
| 858 v[i] = value; | 858 v[i] = value; |
| 859 mtf[-1] = value; |
| 859 do { | 860 do { |
| 860 index--; | 861 index--; |
| 861 mtf[index + 1] = mtf[index]; | 862 mtf[index + 1] = mtf[index]; |
| 862 } while (index > 0); | 863 } while (index >= 0); |
| 863 mtf[0] = value; | |
| 864 } | 864 } |
| 865 /* Remember amount of elements to be reinitialized. */ | 865 /* Remember amount of elements to be reinitialized. */ |
| 866 state->mtf_upper_bound = upper_bound; | 866 state->mtf_upper_bound = upper_bound; |
| 867 } | 867 } |
| 868 | 868 |
| 869 /* Decodes a series of Huffman table using ReadHuffmanCode function. */ | 869 /* Decodes a series of Huffman table using ReadHuffmanCode function. */ |
| 870 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, | 870 static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group, |
| 871 BrotliState* s) { | 871 BrotliState* s) { |
| 872 if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) { | 872 if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) { |
| 873 s->next = group->codes; | 873 s->next = group->codes; |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 if (s->is_uncompressed) { | 1272 if (s->is_uncompressed) { |
| 1273 int next_block_header = | 1273 int next_block_header = |
| 1274 BrotliPeekByte(br, (size_t)s->meta_block_remaining_len); | 1274 BrotliPeekByte(br, (size_t)s->meta_block_remaining_len); |
| 1275 if (next_block_header != -1) { /* Peek succeeded */ | 1275 if (next_block_header != -1) { /* Peek succeeded */ |
| 1276 if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */ | 1276 if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */ |
| 1277 is_last = 1; | 1277 is_last = 1; |
| 1278 } | 1278 } |
| 1279 } | 1279 } |
| 1280 } | 1280 } |
| 1281 | 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 | |
| 1288 /* We need at least 2 bytes of ring buffer size to get the last two | 1282 /* We need at least 2 bytes of ring buffer size to get the last two |
| 1289 bytes for context from there */ | 1283 bytes for context from there */ |
| 1290 if (is_last) { | 1284 if (is_last) { |
| 1291 int min_size_x2 = (s->meta_block_remaining_len + s->custom_dict_size) * 2; | 1285 int min_size_x2 = (s->meta_block_remaining_len + s->custom_dict_size) * 2; |
| 1292 while (s->ringbuffer_size >= min_size_x2 && s->ringbuffer_size > 32) { | 1286 while (s->ringbuffer_size >= min_size_x2 && s->ringbuffer_size > 32) { |
| 1293 s->ringbuffer_size >>= 1; | 1287 s->ringbuffer_size >>= 1; |
| 1294 } | 1288 } |
| 1295 } | 1289 } |
| 1296 | 1290 |
| 1297 s->ringbuffer_mask = s->ringbuffer_size - 1; | 1291 s->ringbuffer_mask = s->ringbuffer_size - 1; |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1893 break; | 1887 break; |
| 1894 } | 1888 } |
| 1895 /* Decode window size. */ | 1889 /* Decode window size. */ |
| 1896 s->window_bits = DecodeWindowBits(br); /* Reads 1..7 bits. */ | 1890 s->window_bits = DecodeWindowBits(br); /* Reads 1..7 bits. */ |
| 1897 BROTLI_LOG_UINT(s->window_bits); | 1891 BROTLI_LOG_UINT(s->window_bits); |
| 1898 if (s->window_bits == 9) { | 1892 if (s->window_bits == 9) { |
| 1899 /* Value 9 is reserved for future use. */ | 1893 /* Value 9 is reserved for future use. */ |
| 1900 result = BROTLI_FAILURE(); | 1894 result = BROTLI_FAILURE(); |
| 1901 break; | 1895 break; |
| 1902 } | 1896 } |
| 1897 /* Maximum distance, see section 9.1. of the spec. */ |
| 1903 s->max_backward_distance = (1 << s->window_bits) - 16; | 1898 s->max_backward_distance = (1 << s->window_bits) - 16; |
| 1899 /* Limit custom dictionary size. */ |
| 1900 if (s->custom_dict_size >= s->max_backward_distance) { |
| 1901 s->custom_dict += s->custom_dict_size - s->max_backward_distance; |
| 1902 s->custom_dict_size = s->max_backward_distance; |
| 1903 } |
| 1904 s->max_backward_distance_minus_custom_dict_size = | 1904 s->max_backward_distance_minus_custom_dict_size = |
| 1905 s->max_backward_distance - s->custom_dict_size; | 1905 s->max_backward_distance - s->custom_dict_size; |
| 1906 | 1906 |
| 1907 /* Allocate memory for both block_type_trees and block_len_trees. */ | 1907 /* Allocate memory for both block_type_trees and block_len_trees. */ |
| 1908 s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s, | 1908 s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s, |
| 1909 sizeof(HuffmanCode) * 3 * | 1909 sizeof(HuffmanCode) * 3 * |
| 1910 (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26)); | 1910 (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26)); |
| 1911 if (s->block_type_trees == 0) { | 1911 if (s->block_type_trees == 0) { |
| 1912 result = BROTLI_FAILURE(); | 1912 result = BROTLI_FAILURE(); |
| 1913 break; | 1913 break; |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2201 } | 2201 } |
| 2202 } | 2202 } |
| 2203 return result; | 2203 return result; |
| 2204 } | 2204 } |
| 2205 } | 2205 } |
| 2206 return result; | 2206 return result; |
| 2207 } | 2207 } |
| 2208 | 2208 |
| 2209 void BrotliSetCustomDictionary( | 2209 void BrotliSetCustomDictionary( |
| 2210 size_t size, const uint8_t* dict, BrotliState* s) { | 2210 size_t size, const uint8_t* dict, BrotliState* s) { |
| 2211 if (size > (1u << 24)) { |
| 2212 return; |
| 2213 } |
| 2211 s->custom_dict = dict; | 2214 s->custom_dict = dict; |
| 2212 s->custom_dict_size = (int)size; | 2215 s->custom_dict_size = (int)size; |
| 2213 } | 2216 } |
| 2214 | 2217 |
| 2215 | 2218 |
| 2216 #if defined(__cplusplus) || defined(c_plusplus) | 2219 #if defined(__cplusplus) || defined(c_plusplus) |
| 2217 } /* extern "C" */ | 2220 } /* extern "C" */ |
| 2218 #endif | 2221 #endif |
| OLD | NEW |