| OLD | NEW |
| 1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Use of this source code is governed by a BSD-style license | 3 // Use of this source code is governed by a BSD-style license |
| 4 // that can be found in the COPYING file in the root of the source | 4 // that can be found in the COPYING file in the root of the source |
| 5 // tree. An additional intellectual property rights grant can be found | 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 // | 9 // |
| 10 // Utilities for building and looking up Huffman trees. | 10 // Utilities for building and looking up Huffman trees. |
| 11 // | 11 // |
| 12 // Author: Urvang Joshi (urvang@google.com) | 12 // Author: Urvang Joshi (urvang@google.com) |
| 13 | 13 |
| 14 #include <assert.h> | 14 #include <assert.h> |
| 15 #include <stdlib.h> | 15 #include <stdlib.h> |
| 16 #include <string.h> | 16 #include <string.h> |
| 17 #include "./huffman.h" | 17 #include "./huffman_utils.h" |
| 18 #include "./utils.h" | 18 #include "./utils.h" |
| 19 #include "../webp/format_constants.h" | 19 #include "../webp/format_constants.h" |
| 20 | 20 |
| 21 // Huffman data read via DecodeImageStream is represented in two (red and green) | 21 // Huffman data read via DecodeImageStream is represented in two (red and green) |
| 22 // bytes. | 22 // bytes. |
| 23 #define MAX_HTREE_GROUPS 0x10000 | 23 #define MAX_HTREE_GROUPS 0x10000 |
| 24 | 24 |
| 25 HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups) { | 25 HTreeGroup* VP8LHtreeGroupsNew(int num_htree_groups) { |
| 26 HTreeGroup* const htree_groups = | 26 HTreeGroup* const htree_groups = |
| 27 (HTreeGroup*)WebPSafeMalloc(num_htree_groups, sizeof(*htree_groups)); | 27 (HTreeGroup*)WebPSafeMalloc(num_htree_groups, sizeof(*htree_groups)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 38 } | 38 } |
| 39 } | 39 } |
| 40 | 40 |
| 41 // Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the | 41 // Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the |
| 42 // bit-wise reversal of the len least significant bits of key. | 42 // bit-wise reversal of the len least significant bits of key. |
| 43 static WEBP_INLINE uint32_t GetNextKey(uint32_t key, int len) { | 43 static WEBP_INLINE uint32_t GetNextKey(uint32_t key, int len) { |
| 44 uint32_t step = 1 << (len - 1); | 44 uint32_t step = 1 << (len - 1); |
| 45 while (key & step) { | 45 while (key & step) { |
| 46 step >>= 1; | 46 step >>= 1; |
| 47 } | 47 } |
| 48 return (key & (step - 1)) + step; | 48 return step ? (key & (step - 1)) + step : key; |
| 49 } | 49 } |
| 50 | 50 |
| 51 // Stores code in table[0], table[step], table[2*step], ..., table[end]. | 51 // Stores code in table[0], table[step], table[2*step], ..., table[end]. |
| 52 // Assumes that end is an integer multiple of step. | 52 // Assumes that end is an integer multiple of step. |
| 53 static WEBP_INLINE void ReplicateValue(HuffmanCode* table, | 53 static WEBP_INLINE void ReplicateValue(HuffmanCode* table, |
| 54 int step, int end, | 54 int step, int end, |
| 55 HuffmanCode code) { | 55 HuffmanCode code) { |
| 56 assert(end % step == 0); | 56 assert(end % step == 0); |
| 57 do { | 57 do { |
| 58 end -= step; | 58 end -= step; |
| 59 table[end] = code; | 59 table[end] = code; |
| 60 } while (end > 0); | 60 } while (end > 0); |
| 61 } | 61 } |
| 62 | 62 |
| 63 // Returns the table width of the next 2nd level table. count is the histogram | 63 // Returns the table width of the next 2nd level table. count is the histogram |
| 64 // of bit lengths for the remaining symbols, len is the code length of the next | 64 // of bit lengths for the remaining symbols, len is the code length of the next |
| 65 // processed symbol | 65 // processed symbol |
| 66 static WEBP_INLINE int NextTableBitSize(const int* const count, | 66 static WEBP_INLINE int NextTableBitSize(const int* const count, |
| 67 int len, int root_bits) { | 67 int len, int root_bits) { |
| 68 int left = 1 << (len - root_bits); | 68 int left = 1 << (len - root_bits); |
| 69 while (len < MAX_ALLOWED_CODE_LENGTH) { | 69 while (len < MAX_ALLOWED_CODE_LENGTH) { |
| 70 left -= count[len]; | 70 left -= count[len]; |
| 71 if (left <= 0) break; | 71 if (left <= 0) break; |
| 72 ++len; | 72 ++len; |
| 73 left <<= 1; | 73 left <<= 1; |
| 74 } | 74 } |
| 75 return len - root_bits; | 75 return len - root_bits; |
| 76 } | 76 } |
| 77 | 77 |
| 78 int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, | 78 // sorted[code_lengths_size] is a pre-allocated array for sorting symbols |
| 79 const int code_lengths[], int code_lengths_size) { | 79 // by code length. |
| 80 static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits, |
| 81 const int code_lengths[], int code_lengths_size, |
| 82 uint16_t sorted[]) { |
| 80 HuffmanCode* table = root_table; // next available space in table | 83 HuffmanCode* table = root_table; // next available space in table |
| 81 int total_size = 1 << root_bits; // total size root table + 2nd level table | 84 int total_size = 1 << root_bits; // total size root table + 2nd level table |
| 82 int* sorted = NULL; // symbols sorted by code length | |
| 83 int len; // current code length | 85 int len; // current code length |
| 84 int symbol; // symbol index in original or sorted table | 86 int symbol; // symbol index in original or sorted table |
| 85 // number of codes of each length: | 87 // number of codes of each length: |
| 86 int count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 }; | 88 int count[MAX_ALLOWED_CODE_LENGTH + 1] = { 0 }; |
| 87 // offsets in sorted table for each length: | 89 // offsets in sorted table for each length: |
| 88 int offset[MAX_ALLOWED_CODE_LENGTH + 1]; | 90 int offset[MAX_ALLOWED_CODE_LENGTH + 1]; |
| 89 | 91 |
| 90 assert(code_lengths_size != 0); | 92 assert(code_lengths_size != 0); |
| 91 assert(code_lengths != NULL); | 93 assert(code_lengths != NULL); |
| 92 assert(root_table != NULL); | 94 assert(root_table != NULL); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 107 | 109 |
| 108 // Generate offsets into sorted symbol table by code length. | 110 // Generate offsets into sorted symbol table by code length. |
| 109 offset[1] = 0; | 111 offset[1] = 0; |
| 110 for (len = 1; len < MAX_ALLOWED_CODE_LENGTH; ++len) { | 112 for (len = 1; len < MAX_ALLOWED_CODE_LENGTH; ++len) { |
| 111 if (count[len] > (1 << len)) { | 113 if (count[len] > (1 << len)) { |
| 112 return 0; | 114 return 0; |
| 113 } | 115 } |
| 114 offset[len + 1] = offset[len] + count[len]; | 116 offset[len + 1] = offset[len] + count[len]; |
| 115 } | 117 } |
| 116 | 118 |
| 117 sorted = (int*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted)); | |
| 118 if (sorted == NULL) { | |
| 119 return 0; | |
| 120 } | |
| 121 | |
| 122 // Sort symbols by length, by symbol order within each length. | 119 // Sort symbols by length, by symbol order within each length. |
| 123 for (symbol = 0; symbol < code_lengths_size; ++symbol) { | 120 for (symbol = 0; symbol < code_lengths_size; ++symbol) { |
| 124 const int symbol_code_length = code_lengths[symbol]; | 121 const int symbol_code_length = code_lengths[symbol]; |
| 125 if (code_lengths[symbol] > 0) { | 122 if (code_lengths[symbol] > 0) { |
| 126 sorted[offset[symbol_code_length]++] = symbol; | 123 sorted[offset[symbol_code_length]++] = symbol; |
| 127 } | 124 } |
| 128 } | 125 } |
| 129 | 126 |
| 130 // Special case code with only one value. | 127 // Special case code with only one value. |
| 131 if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) { | 128 if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) { |
| 132 HuffmanCode code; | 129 HuffmanCode code; |
| 133 code.bits = 0; | 130 code.bits = 0; |
| 134 code.value = (uint16_t)sorted[0]; | 131 code.value = (uint16_t)sorted[0]; |
| 135 ReplicateValue(table, 1, total_size, code); | 132 ReplicateValue(table, 1, total_size, code); |
| 136 WebPSafeFree(sorted); | |
| 137 return total_size; | 133 return total_size; |
| 138 } | 134 } |
| 139 | 135 |
| 140 { | 136 { |
| 141 int step; // step size to replicate values in current table | 137 int step; // step size to replicate values in current table |
| 142 uint32_t low = -1; // low bits for current root entry | 138 uint32_t low = -1; // low bits for current root entry |
| 143 uint32_t mask = total_size - 1; // mask for low bits | 139 uint32_t mask = total_size - 1; // mask for low bits |
| 144 uint32_t key = 0; // reversed prefix code | 140 uint32_t key = 0; // reversed prefix code |
| 145 int num_nodes = 1; // number of Huffman tree nodes | 141 int num_nodes = 1; // number of Huffman tree nodes |
| 146 int num_open = 1; // number of open branches in current tree level | 142 int num_open = 1; // number of open branches in current tree level |
| 147 int table_bits = root_bits; // key length of current table | 143 int table_bits = root_bits; // key length of current table |
| 148 int table_size = 1 << table_bits; // size of current table | 144 int table_size = 1 << table_bits; // size of current table |
| 149 symbol = 0; | 145 symbol = 0; |
| 150 // Fill in root table. | 146 // Fill in root table. |
| 151 for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) { | 147 for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) { |
| 152 num_open <<= 1; | 148 num_open <<= 1; |
| 153 num_nodes += num_open; | 149 num_nodes += num_open; |
| 154 num_open -= count[len]; | 150 num_open -= count[len]; |
| 155 if (num_open < 0) { | 151 if (num_open < 0) { |
| 156 WebPSafeFree(sorted); | |
| 157 return 0; | 152 return 0; |
| 158 } | 153 } |
| 159 for (; count[len] > 0; --count[len]) { | 154 for (; count[len] > 0; --count[len]) { |
| 160 HuffmanCode code; | 155 HuffmanCode code; |
| 161 code.bits = (uint8_t)len; | 156 code.bits = (uint8_t)len; |
| 162 code.value = (uint16_t)sorted[symbol++]; | 157 code.value = (uint16_t)sorted[symbol++]; |
| 163 ReplicateValue(&table[key], step, table_size, code); | 158 ReplicateValue(&table[key], step, table_size, code); |
| 164 key = GetNextKey(key, len); | 159 key = GetNextKey(key, len); |
| 165 } | 160 } |
| 166 } | 161 } |
| 167 | 162 |
| 168 // Fill in 2nd level tables and add pointers to root table. | 163 // Fill in 2nd level tables and add pointers to root table. |
| 169 for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH; | 164 for (len = root_bits + 1, step = 2; len <= MAX_ALLOWED_CODE_LENGTH; |
| 170 ++len, step <<= 1) { | 165 ++len, step <<= 1) { |
| 171 num_open <<= 1; | 166 num_open <<= 1; |
| 172 num_nodes += num_open; | 167 num_nodes += num_open; |
| 173 num_open -= count[len]; | 168 num_open -= count[len]; |
| 174 if (num_open < 0) { | 169 if (num_open < 0) { |
| 175 WebPSafeFree(sorted); | |
| 176 return 0; | 170 return 0; |
| 177 } | 171 } |
| 178 for (; count[len] > 0; --count[len]) { | 172 for (; count[len] > 0; --count[len]) { |
| 179 HuffmanCode code; | 173 HuffmanCode code; |
| 180 if ((key & mask) != low) { | 174 if ((key & mask) != low) { |
| 181 table += table_size; | 175 table += table_size; |
| 182 table_bits = NextTableBitSize(count, len, root_bits); | 176 table_bits = NextTableBitSize(count, len, root_bits); |
| 183 table_size = 1 << table_bits; | 177 table_size = 1 << table_bits; |
| 184 total_size += table_size; | 178 total_size += table_size; |
| 185 low = key & mask; | 179 low = key & mask; |
| 186 root_table[low].bits = (uint8_t)(table_bits + root_bits); | 180 root_table[low].bits = (uint8_t)(table_bits + root_bits); |
| 187 root_table[low].value = (uint16_t)((table - root_table) - low); | 181 root_table[low].value = (uint16_t)((table - root_table) - low); |
| 188 } | 182 } |
| 189 code.bits = (uint8_t)(len - root_bits); | 183 code.bits = (uint8_t)(len - root_bits); |
| 190 code.value = (uint16_t)sorted[symbol++]; | 184 code.value = (uint16_t)sorted[symbol++]; |
| 191 ReplicateValue(&table[key >> root_bits], step, table_size, code); | 185 ReplicateValue(&table[key >> root_bits], step, table_size, code); |
| 192 key = GetNextKey(key, len); | 186 key = GetNextKey(key, len); |
| 193 } | 187 } |
| 194 } | 188 } |
| 195 | 189 |
| 196 // Check if tree is full. | 190 // Check if tree is full. |
| 197 if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) { | 191 if (num_nodes != 2 * offset[MAX_ALLOWED_CODE_LENGTH] - 1) { |
| 198 WebPSafeFree(sorted); | |
| 199 return 0; | 192 return 0; |
| 200 } | 193 } |
| 201 } | 194 } |
| 202 | 195 |
| 203 WebPSafeFree(sorted); | |
| 204 return total_size; | 196 return total_size; |
| 205 } | 197 } |
| 198 |
| 199 // Maximum code_lengths_size is 2328 (reached for 11-bit color_cache_bits). |
| 200 // More commonly, the value is around ~280. |
| 201 #define MAX_CODE_LENGTHS_SIZE \ |
| 202 ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES) |
| 203 // Cut-off value for switching between heap and stack allocation. |
| 204 #define SORTED_SIZE_CUTOFF 512 |
| 205 int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, |
| 206 const int code_lengths[], int code_lengths_size) { |
| 207 int total_size; |
| 208 assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE); |
| 209 if (code_lengths_size <= SORTED_SIZE_CUTOFF) { |
| 210 // use local stack-allocated array. |
| 211 uint16_t sorted[SORTED_SIZE_CUTOFF]; |
| 212 total_size = BuildHuffmanTable(root_table, root_bits, |
| 213 code_lengths, code_lengths_size, sorted); |
| 214 } else { // rare case. Use heap allocation. |
| 215 uint16_t* const sorted = |
| 216 (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted)); |
| 217 if (sorted == NULL) return 0; |
| 218 total_size = BuildHuffmanTable(root_table, root_bits, |
| 219 code_lengths, code_lengths_size, sorted); |
| 220 WebPSafeFree(sorted); |
| 221 } |
| 222 return total_size; |
| 223 } |
| OLD | NEW |