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 // main entry for the decoder | 10 // main entry for the decoder |
11 // | 11 // |
12 // Authors: Vikas Arora (vikaas.arora@gmail.com) | 12 // Authors: Vikas Arora (vikaas.arora@gmail.com) |
13 // Jyrki Alakuijala (jyrki@google.com) | 13 // Jyrki Alakuijala (jyrki@google.com) |
14 | 14 |
15 #include <stdlib.h> | 15 #include <stdlib.h> |
16 | 16 |
17 #include "./alphai.h" | 17 #include "./alphai.h" |
18 #include "./vp8li.h" | 18 #include "./vp8li.h" |
19 #include "../dsp/dsp.h" | 19 #include "../dsp/dsp.h" |
20 #include "../dsp/lossless.h" | 20 #include "../dsp/lossless.h" |
21 #include "../dsp/yuv.h" | 21 #include "../dsp/yuv.h" |
| 22 #include "../utils/endian_inl.h" |
22 #include "../utils/huffman.h" | 23 #include "../utils/huffman.h" |
23 #include "../utils/utils.h" | 24 #include "../utils/utils.h" |
24 | 25 |
25 #define NUM_ARGB_CACHE_ROWS 16 | 26 #define NUM_ARGB_CACHE_ROWS 16 |
26 | 27 |
27 static const int kCodeLengthLiterals = 16; | 28 static const int kCodeLengthLiterals = 16; |
28 static const int kCodeLengthRepeatCode = 16; | 29 static const int kCodeLengthRepeatCode = 16; |
29 static const int kCodeLengthExtraBits[3] = { 2, 3, 7 }; | 30 static const int kCodeLengthExtraBits[3] = { 2, 3, 7 }; |
30 static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 }; | 31 static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 }; |
31 | 32 |
(...skipping 11 matching lines...) Expand all Loading... |
43 ALPHA = 3, | 44 ALPHA = 3, |
44 DIST = 4 | 45 DIST = 4 |
45 } HuffIndex; | 46 } HuffIndex; |
46 | 47 |
47 static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = { | 48 static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = { |
48 NUM_LITERAL_CODES + NUM_LENGTH_CODES, | 49 NUM_LITERAL_CODES + NUM_LENGTH_CODES, |
49 NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES, | 50 NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES, |
50 NUM_DISTANCE_CODES | 51 NUM_DISTANCE_CODES |
51 }; | 52 }; |
52 | 53 |
| 54 static const uint8_t kLiteralMap[HUFFMAN_CODES_PER_META_CODE] = { |
| 55 0, 1, 1, 1, 0 |
| 56 }; |
53 | 57 |
54 #define NUM_CODE_LENGTH_CODES 19 | 58 #define NUM_CODE_LENGTH_CODES 19 |
55 static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = { | 59 static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = { |
56 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 | 60 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 |
57 }; | 61 }; |
58 | 62 |
59 #define CODE_TO_PLANE_CODES 120 | 63 #define CODE_TO_PLANE_CODES 120 |
60 static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = { | 64 static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = { |
61 0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a, | 65 0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a, |
62 0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a, | 66 0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a, |
63 0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b, | 67 0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b, |
64 0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03, | 68 0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03, |
65 0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c, | 69 0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c, |
66 0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e, | 70 0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e, |
67 0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b, | 71 0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b, |
68 0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f, | 72 0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f, |
69 0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b, | 73 0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b, |
70 0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41, | 74 0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41, |
71 0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f, | 75 0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f, |
72 0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70 | 76 0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70 |
73 }; | 77 }; |
74 | 78 |
| 79 // Memory needed for lookup tables of one Huffman tree group. Red, blue, alpha |
| 80 // and distance alphabets are constant (256 for red, blue and alpha, 40 for |
| 81 // distance) and lookup table sizes for them in worst case are 630 and 410 |
| 82 // respectively. Size of green alphabet depends on color cache size and is equal |
| 83 // to 256 (green component values) + 24 (length prefix values) |
| 84 // + color_cache_size (between 0 and 2048). |
| 85 // All values computed for 8-bit first level lookup with Mark Adler's tool: |
| 86 // http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c |
| 87 #define FIXED_TABLE_SIZE (630 * 3 + 410) |
| 88 static const int kTableSize[12] = { |
| 89 FIXED_TABLE_SIZE + 654, |
| 90 FIXED_TABLE_SIZE + 656, |
| 91 FIXED_TABLE_SIZE + 658, |
| 92 FIXED_TABLE_SIZE + 662, |
| 93 FIXED_TABLE_SIZE + 670, |
| 94 FIXED_TABLE_SIZE + 686, |
| 95 FIXED_TABLE_SIZE + 718, |
| 96 FIXED_TABLE_SIZE + 782, |
| 97 FIXED_TABLE_SIZE + 912, |
| 98 FIXED_TABLE_SIZE + 1168, |
| 99 FIXED_TABLE_SIZE + 1680, |
| 100 FIXED_TABLE_SIZE + 2704 |
| 101 }; |
| 102 |
75 static int DecodeImageStream(int xsize, int ysize, | 103 static int DecodeImageStream(int xsize, int ysize, |
76 int is_level0, | 104 int is_level0, |
77 VP8LDecoder* const dec, | 105 VP8LDecoder* const dec, |
78 uint32_t** const decoded_data); | 106 uint32_t** const decoded_data); |
79 | 107 |
80 //------------------------------------------------------------------------------ | 108 //------------------------------------------------------------------------------ |
81 | 109 |
82 int VP8LCheckSignature(const uint8_t* const data, size_t size) { | 110 int VP8LCheckSignature(const uint8_t* const data, size_t size) { |
83 return (size >= VP8L_FRAME_HEADER_SIZE && | 111 return (size >= VP8L_FRAME_HEADER_SIZE && |
84 data[0] == VP8L_MAGIC_BYTE && | 112 data[0] == VP8L_MAGIC_BYTE && |
85 (data[4] >> 5) == 0); // version | 113 (data[4] >> 5) == 0); // version |
86 } | 114 } |
87 | 115 |
88 static int ReadImageInfo(VP8LBitReader* const br, | 116 static int ReadImageInfo(VP8LBitReader* const br, |
89 int* const width, int* const height, | 117 int* const width, int* const height, |
90 int* const has_alpha) { | 118 int* const has_alpha) { |
91 if (VP8LReadBits(br, 8) != VP8L_MAGIC_BYTE) return 0; | 119 if (VP8LReadBits(br, 8) != VP8L_MAGIC_BYTE) return 0; |
92 *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; | 120 *width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; |
93 *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; | 121 *height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1; |
94 *has_alpha = VP8LReadBits(br, 1); | 122 *has_alpha = VP8LReadBits(br, 1); |
95 if (VP8LReadBits(br, VP8L_VERSION_BITS) != 0) return 0; | 123 if (VP8LReadBits(br, VP8L_VERSION_BITS) != 0) return 0; |
96 return 1; | 124 return !br->eos_; |
97 } | 125 } |
98 | 126 |
99 int VP8LGetInfo(const uint8_t* data, size_t data_size, | 127 int VP8LGetInfo(const uint8_t* data, size_t data_size, |
100 int* const width, int* const height, int* const has_alpha) { | 128 int* const width, int* const height, int* const has_alpha) { |
101 if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) { | 129 if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) { |
102 return 0; // not enough data | 130 return 0; // not enough data |
103 } else if (!VP8LCheckSignature(data, data_size)) { | 131 } else if (!VP8LCheckSignature(data, data_size)) { |
104 return 0; // bad signature | 132 return 0; // bad signature |
105 } else { | 133 } else { |
106 int w, h, a; | 134 int w, h, a; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 const int xoffset = 8 - (dist_code & 0xf); | 172 const int xoffset = 8 - (dist_code & 0xf); |
145 const int dist = yoffset * xsize + xoffset; | 173 const int dist = yoffset * xsize + xoffset; |
146 return (dist >= 1) ? dist : 1; // dist<1 can happen if xsize is very small | 174 return (dist >= 1) ? dist : 1; // dist<1 can happen if xsize is very small |
147 } | 175 } |
148 } | 176 } |
149 | 177 |
150 //------------------------------------------------------------------------------ | 178 //------------------------------------------------------------------------------ |
151 // Decodes the next Huffman code from bit-stream. | 179 // Decodes the next Huffman code from bit-stream. |
152 // FillBitWindow(br) needs to be called at minimum every second call | 180 // FillBitWindow(br) needs to be called at minimum every second call |
153 // to ReadSymbol, in order to pre-fetch enough bits. | 181 // to ReadSymbol, in order to pre-fetch enough bits. |
154 static WEBP_INLINE int ReadSymbol(const HuffmanTree* tree, | 182 static WEBP_INLINE int ReadSymbol(const HuffmanCode* table, |
155 VP8LBitReader* const br) { | 183 VP8LBitReader* const br) { |
156 const HuffmanTreeNode* node = tree->root_; | 184 int nbits; |
157 uint32_t bits = VP8LPrefetchBits(br); | 185 uint32_t val = VP8LPrefetchBits(br); |
158 int bitpos = br->bit_pos_; | 186 table += val & HUFFMAN_TABLE_MASK; |
159 // Check if we find the bit combination from the Huffman lookup table. | 187 nbits = table->bits - HUFFMAN_TABLE_BITS; |
160 const int lut_ix = bits & (HUFF_LUT - 1); | 188 if (nbits > 0) { |
161 const int lut_bits = tree->lut_bits_[lut_ix]; | 189 VP8LSetBitPos(br, br->bit_pos_ + HUFFMAN_TABLE_BITS); |
162 if (lut_bits <= HUFF_LUT_BITS) { | 190 val = VP8LPrefetchBits(br); |
163 VP8LSetBitPos(br, bitpos + lut_bits); | 191 table += table->value; |
164 return tree->lut_symbol_[lut_ix]; | 192 table += val & ((1 << nbits) - 1); |
165 } | 193 } |
166 node += tree->lut_jump_[lut_ix]; | 194 VP8LSetBitPos(br, br->bit_pos_ + table->bits); |
167 bitpos += HUFF_LUT_BITS; | 195 return table->value; |
168 bits >>= HUFF_LUT_BITS; | 196 } |
169 | 197 |
170 // Decode the value from a binary tree. | 198 // Reads packed symbol depending on GREEN channel |
171 assert(node != NULL); | 199 #define BITS_SPECIAL_MARKER 0x100 // something large enough (and a bit-mask) |
172 do { | 200 #define PACKED_NON_LITERAL_CODE 0 // must be < NUM_LITERAL_CODES |
173 node = HuffmanTreeNextNode(node, bits & 1); | 201 static WEBP_INLINE int ReadPackedSymbols(const HTreeGroup* group, |
174 bits >>= 1; | 202 VP8LBitReader* const br, |
175 ++bitpos; | 203 uint32_t* const dst) { |
176 } while (HuffmanTreeNodeIsNotLeaf(node)); | 204 const uint32_t val = VP8LPrefetchBits(br) & (HUFFMAN_PACKED_TABLE_SIZE - 1); |
177 VP8LSetBitPos(br, bitpos); | 205 const HuffmanCode32 code = group->packed_table[val]; |
178 return node->symbol_; | 206 assert(group->use_packed_table); |
| 207 if (code.bits < BITS_SPECIAL_MARKER) { |
| 208 VP8LSetBitPos(br, br->bit_pos_ + code.bits); |
| 209 *dst = code.value; |
| 210 return PACKED_NON_LITERAL_CODE; |
| 211 } else { |
| 212 VP8LSetBitPos(br, br->bit_pos_ + code.bits - BITS_SPECIAL_MARKER); |
| 213 assert(code.value >= NUM_LITERAL_CODES); |
| 214 return code.value; |
| 215 } |
| 216 } |
| 217 |
| 218 static int AccumulateHCode(HuffmanCode hcode, int shift, |
| 219 HuffmanCode32* const huff) { |
| 220 huff->bits += hcode.bits; |
| 221 huff->value |= (uint32_t)hcode.value << shift; |
| 222 assert(huff->bits <= HUFFMAN_TABLE_BITS); |
| 223 return hcode.bits; |
| 224 } |
| 225 |
| 226 static void BuildPackedTable(HTreeGroup* const htree_group) { |
| 227 uint32_t code; |
| 228 for (code = 0; code < HUFFMAN_PACKED_TABLE_SIZE; ++code) { |
| 229 uint32_t bits = code; |
| 230 HuffmanCode32* const huff = &htree_group->packed_table[bits]; |
| 231 HuffmanCode hcode = htree_group->htrees[GREEN][bits]; |
| 232 if (hcode.value >= NUM_LITERAL_CODES) { |
| 233 huff->bits = hcode.bits + BITS_SPECIAL_MARKER; |
| 234 huff->value = hcode.value; |
| 235 } else { |
| 236 huff->bits = 0; |
| 237 huff->value = 0; |
| 238 bits >>= AccumulateHCode(hcode, 8, huff); |
| 239 bits >>= AccumulateHCode(htree_group->htrees[RED][bits], 16, huff); |
| 240 bits >>= AccumulateHCode(htree_group->htrees[BLUE][bits], 0, huff); |
| 241 bits >>= AccumulateHCode(htree_group->htrees[ALPHA][bits], 24, huff); |
| 242 (void)bits; |
| 243 } |
| 244 } |
179 } | 245 } |
180 | 246 |
181 static int ReadHuffmanCodeLengths( | 247 static int ReadHuffmanCodeLengths( |
182 VP8LDecoder* const dec, const int* const code_length_code_lengths, | 248 VP8LDecoder* const dec, const int* const code_length_code_lengths, |
183 int num_symbols, int* const code_lengths) { | 249 int num_symbols, int* const code_lengths) { |
184 int ok = 0; | 250 int ok = 0; |
185 VP8LBitReader* const br = &dec->br_; | 251 VP8LBitReader* const br = &dec->br_; |
186 int symbol; | 252 int symbol; |
187 int max_symbol; | 253 int max_symbol; |
188 int prev_code_len = DEFAULT_CODE_LENGTH; | 254 int prev_code_len = DEFAULT_CODE_LENGTH; |
189 HuffmanTree tree; | 255 HuffmanCode table[1 << LENGTHS_TABLE_BITS]; |
190 int huff_codes[NUM_CODE_LENGTH_CODES] = { 0 }; | |
191 | 256 |
192 if (!VP8LHuffmanTreeBuildImplicit(&tree, code_length_code_lengths, | 257 if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS, |
193 huff_codes, NUM_CODE_LENGTH_CODES)) { | 258 code_length_code_lengths, |
194 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 259 NUM_CODE_LENGTH_CODES)) { |
195 return 0; | 260 goto End; |
196 } | 261 } |
197 | 262 |
198 if (VP8LReadBits(br, 1)) { // use length | 263 if (VP8LReadBits(br, 1)) { // use length |
199 const int length_nbits = 2 + 2 * VP8LReadBits(br, 3); | 264 const int length_nbits = 2 + 2 * VP8LReadBits(br, 3); |
200 max_symbol = 2 + VP8LReadBits(br, length_nbits); | 265 max_symbol = 2 + VP8LReadBits(br, length_nbits); |
201 if (max_symbol > num_symbols) { | 266 if (max_symbol > num_symbols) { |
202 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | |
203 goto End; | 267 goto End; |
204 } | 268 } |
205 } else { | 269 } else { |
206 max_symbol = num_symbols; | 270 max_symbol = num_symbols; |
207 } | 271 } |
208 | 272 |
209 symbol = 0; | 273 symbol = 0; |
210 while (symbol < num_symbols) { | 274 while (symbol < num_symbols) { |
| 275 const HuffmanCode* p; |
211 int code_len; | 276 int code_len; |
212 if (max_symbol-- == 0) break; | 277 if (max_symbol-- == 0) break; |
213 VP8LFillBitWindow(br); | 278 VP8LFillBitWindow(br); |
214 code_len = ReadSymbol(&tree, br); | 279 p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK]; |
| 280 VP8LSetBitPos(br, br->bit_pos_ + p->bits); |
| 281 code_len = p->value; |
215 if (code_len < kCodeLengthLiterals) { | 282 if (code_len < kCodeLengthLiterals) { |
216 code_lengths[symbol++] = code_len; | 283 code_lengths[symbol++] = code_len; |
217 if (code_len != 0) prev_code_len = code_len; | 284 if (code_len != 0) prev_code_len = code_len; |
218 } else { | 285 } else { |
219 const int use_prev = (code_len == kCodeLengthRepeatCode); | 286 const int use_prev = (code_len == kCodeLengthRepeatCode); |
220 const int slot = code_len - kCodeLengthLiterals; | 287 const int slot = code_len - kCodeLengthLiterals; |
221 const int extra_bits = kCodeLengthExtraBits[slot]; | 288 const int extra_bits = kCodeLengthExtraBits[slot]; |
222 const int repeat_offset = kCodeLengthRepeatOffsets[slot]; | 289 const int repeat_offset = kCodeLengthRepeatOffsets[slot]; |
223 int repeat = VP8LReadBits(br, extra_bits) + repeat_offset; | 290 int repeat = VP8LReadBits(br, extra_bits) + repeat_offset; |
224 if (symbol + repeat > num_symbols) { | 291 if (symbol + repeat > num_symbols) { |
225 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | |
226 goto End; | 292 goto End; |
227 } else { | 293 } else { |
228 const int length = use_prev ? prev_code_len : 0; | 294 const int length = use_prev ? prev_code_len : 0; |
229 while (repeat-- > 0) code_lengths[symbol++] = length; | 295 while (repeat-- > 0) code_lengths[symbol++] = length; |
230 } | 296 } |
231 } | 297 } |
232 } | 298 } |
233 ok = 1; | 299 ok = 1; |
234 | 300 |
235 End: | 301 End: |
236 VP8LHuffmanTreeFree(&tree); | |
237 if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 302 if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR; |
238 return ok; | 303 return ok; |
239 } | 304 } |
240 | 305 |
241 // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman | 306 // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman |
242 // tree. | 307 // tree. |
243 static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec, | 308 static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec, |
244 int* const code_lengths, int* const huff_codes, | 309 int* const code_lengths, HuffmanCode* const table) { |
245 HuffmanTree* const tree) { | |
246 int ok = 0; | 310 int ok = 0; |
| 311 int size = 0; |
247 VP8LBitReader* const br = &dec->br_; | 312 VP8LBitReader* const br = &dec->br_; |
248 const int simple_code = VP8LReadBits(br, 1); | 313 const int simple_code = VP8LReadBits(br, 1); |
249 | 314 |
| 315 memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths)); |
| 316 |
250 if (simple_code) { // Read symbols, codes & code lengths directly. | 317 if (simple_code) { // Read symbols, codes & code lengths directly. |
251 int symbols[2]; | |
252 int codes[2]; | |
253 const int num_symbols = VP8LReadBits(br, 1) + 1; | 318 const int num_symbols = VP8LReadBits(br, 1) + 1; |
254 const int first_symbol_len_code = VP8LReadBits(br, 1); | 319 const int first_symbol_len_code = VP8LReadBits(br, 1); |
255 // The first code is either 1 bit or 8 bit code. | 320 // The first code is either 1 bit or 8 bit code. |
256 symbols[0] = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8); | 321 int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8); |
257 codes[0] = 0; | 322 code_lengths[symbol] = 1; |
258 code_lengths[0] = num_symbols - 1; | |
259 // The second code (if present), is always 8 bit long. | 323 // The second code (if present), is always 8 bit long. |
260 if (num_symbols == 2) { | 324 if (num_symbols == 2) { |
261 symbols[1] = VP8LReadBits(br, 8); | 325 symbol = VP8LReadBits(br, 8); |
262 codes[1] = 1; | 326 code_lengths[symbol] = 1; |
263 code_lengths[1] = num_symbols - 1; | |
264 } | 327 } |
265 ok = VP8LHuffmanTreeBuildExplicit(tree, code_lengths, codes, symbols, | 328 ok = 1; |
266 alphabet_size, num_symbols); | |
267 } else { // Decode Huffman-coded code lengths. | 329 } else { // Decode Huffman-coded code lengths. |
268 int i; | 330 int i; |
269 int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; | 331 int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; |
270 const int num_codes = VP8LReadBits(br, 4) + 4; | 332 const int num_codes = VP8LReadBits(br, 4) + 4; |
271 if (num_codes > NUM_CODE_LENGTH_CODES) { | 333 if (num_codes > NUM_CODE_LENGTH_CODES) { |
272 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 334 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; |
273 return 0; | 335 return 0; |
274 } | 336 } |
275 | 337 |
276 memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths)); | |
277 | |
278 for (i = 0; i < num_codes; ++i) { | 338 for (i = 0; i < num_codes; ++i) { |
279 code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3); | 339 code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3); |
280 } | 340 } |
281 ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size, | 341 ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size, |
282 code_lengths); | 342 code_lengths); |
283 ok = ok && VP8LHuffmanTreeBuildImplicit(tree, code_lengths, huff_codes, | |
284 alphabet_size); | |
285 } | 343 } |
286 ok = ok && !br->error_; | 344 |
287 if (!ok) { | 345 ok = ok && !br->eos_; |
| 346 if (ok) { |
| 347 size = VP8LBuildHuffmanTable(table, HUFFMAN_TABLE_BITS, |
| 348 code_lengths, alphabet_size); |
| 349 } |
| 350 if (!ok || size == 0) { |
288 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 351 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; |
289 return 0; | 352 return 0; |
290 } | 353 } |
291 return 1; | 354 return size; |
292 } | 355 } |
293 | 356 |
294 static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, | 357 static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize, |
295 int color_cache_bits, int allow_recursion) { | 358 int color_cache_bits, int allow_recursion) { |
296 int i, j; | 359 int i, j; |
297 VP8LBitReader* const br = &dec->br_; | 360 VP8LBitReader* const br = &dec->br_; |
298 VP8LMetadata* const hdr = &dec->hdr_; | 361 VP8LMetadata* const hdr = &dec->hdr_; |
299 uint32_t* huffman_image = NULL; | 362 uint32_t* huffman_image = NULL; |
300 HTreeGroup* htree_groups = NULL; | 363 HTreeGroup* htree_groups = NULL; |
| 364 HuffmanCode* huffman_tables = NULL; |
| 365 HuffmanCode* next = NULL; |
301 int num_htree_groups = 1; | 366 int num_htree_groups = 1; |
302 int max_alphabet_size = 0; | 367 int max_alphabet_size = 0; |
303 int* code_lengths = NULL; | 368 int* code_lengths = NULL; |
304 int* huff_codes = NULL; | 369 const int table_size = kTableSize[color_cache_bits]; |
305 | 370 |
306 if (allow_recursion && VP8LReadBits(br, 1)) { | 371 if (allow_recursion && VP8LReadBits(br, 1)) { |
307 // use meta Huffman codes. | 372 // use meta Huffman codes. |
308 const int huffman_precision = VP8LReadBits(br, 3) + 2; | 373 const int huffman_precision = VP8LReadBits(br, 3) + 2; |
309 const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision); | 374 const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision); |
310 const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision); | 375 const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision); |
311 const int huffman_pixs = huffman_xsize * huffman_ysize; | 376 const int huffman_pixs = huffman_xsize * huffman_ysize; |
312 if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec, | 377 if (!DecodeImageStream(huffman_xsize, huffman_ysize, 0, dec, |
313 &huffman_image)) { | 378 &huffman_image)) { |
314 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | |
315 goto Error; | 379 goto Error; |
316 } | 380 } |
317 hdr->huffman_subsample_bits_ = huffman_precision; | 381 hdr->huffman_subsample_bits_ = huffman_precision; |
318 for (i = 0; i < huffman_pixs; ++i) { | 382 for (i = 0; i < huffman_pixs; ++i) { |
319 // The huffman data is stored in red and green bytes. | 383 // The huffman data is stored in red and green bytes. |
320 const int group = (huffman_image[i] >> 8) & 0xffff; | 384 const int group = (huffman_image[i] >> 8) & 0xffff; |
321 huffman_image[i] = group; | 385 huffman_image[i] = group; |
322 if (group >= num_htree_groups) { | 386 if (group >= num_htree_groups) { |
323 num_htree_groups = group + 1; | 387 num_htree_groups = group + 1; |
324 } | 388 } |
325 } | 389 } |
326 } | 390 } |
327 | 391 |
328 if (br->error_) goto Error; | 392 if (br->eos_) goto Error; |
329 | 393 |
330 // Find maximum alphabet size for the htree group. | 394 // Find maximum alphabet size for the htree group. |
331 for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { | 395 for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { |
332 int alphabet_size = kAlphabetSize[j]; | 396 int alphabet_size = kAlphabetSize[j]; |
333 if (j == 0 && color_cache_bits > 0) { | 397 if (j == 0 && color_cache_bits > 0) { |
334 alphabet_size += 1 << color_cache_bits; | 398 alphabet_size += 1 << color_cache_bits; |
335 } | 399 } |
336 if (max_alphabet_size < alphabet_size) { | 400 if (max_alphabet_size < alphabet_size) { |
337 max_alphabet_size = alphabet_size; | 401 max_alphabet_size = alphabet_size; |
338 } | 402 } |
339 } | 403 } |
340 | 404 |
| 405 huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size, |
| 406 sizeof(*huffman_tables)); |
341 htree_groups = VP8LHtreeGroupsNew(num_htree_groups); | 407 htree_groups = VP8LHtreeGroupsNew(num_htree_groups); |
342 code_lengths = | 408 code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size, |
343 (int*)WebPSafeCalloc((uint64_t)max_alphabet_size, sizeof(*code_lengths)); | 409 sizeof(*code_lengths)); |
344 huff_codes = | |
345 (int*)WebPSafeMalloc((uint64_t)max_alphabet_size, sizeof(*huff_codes)); | |
346 | 410 |
347 if (htree_groups == NULL || code_lengths == NULL || huff_codes == NULL) { | 411 if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) { |
348 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; | 412 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; |
349 goto Error; | 413 goto Error; |
350 } | 414 } |
351 | 415 |
| 416 next = huffman_tables; |
352 for (i = 0; i < num_htree_groups; ++i) { | 417 for (i = 0; i < num_htree_groups; ++i) { |
353 HuffmanTree* const htrees = htree_groups[i].htrees_; | 418 HTreeGroup* const htree_group = &htree_groups[i]; |
| 419 HuffmanCode** const htrees = htree_group->htrees; |
| 420 int size; |
| 421 int total_size = 0; |
| 422 int is_trivial_literal = 1; |
| 423 int max_bits = 0; |
354 for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { | 424 for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { |
355 int alphabet_size = kAlphabetSize[j]; | 425 int alphabet_size = kAlphabetSize[j]; |
356 HuffmanTree* const htree = htrees + j; | 426 htrees[j] = next; |
357 if (j == 0 && color_cache_bits > 0) { | 427 if (j == 0 && color_cache_bits > 0) { |
358 alphabet_size += 1 << color_cache_bits; | 428 alphabet_size += 1 << color_cache_bits; |
359 } | 429 } |
360 if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, huff_codes, | 430 size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next); |
361 htree)) { | 431 if (size == 0) { |
362 goto Error; | 432 goto Error; |
363 } | 433 } |
| 434 if (is_trivial_literal && kLiteralMap[j] == 1) { |
| 435 is_trivial_literal = (next->bits == 0); |
| 436 } |
| 437 total_size += next->bits; |
| 438 next += size; |
| 439 if (j <= ALPHA) { |
| 440 int local_max_bits = code_lengths[0]; |
| 441 int k; |
| 442 for (k = 1; k < alphabet_size; ++k) { |
| 443 if (code_lengths[k] > local_max_bits) { |
| 444 local_max_bits = code_lengths[k]; |
| 445 } |
| 446 } |
| 447 max_bits += local_max_bits; |
| 448 } |
364 } | 449 } |
| 450 htree_group->is_trivial_literal = is_trivial_literal; |
| 451 htree_group->is_trivial_code = 0; |
| 452 if (is_trivial_literal) { |
| 453 const int red = htrees[RED][0].value; |
| 454 const int blue = htrees[BLUE][0].value; |
| 455 const int alpha = htrees[ALPHA][0].value; |
| 456 htree_group->literal_arb = |
| 457 ((uint32_t)alpha << 24) | (red << 16) | blue; |
| 458 if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) { |
| 459 htree_group->is_trivial_code = 1; |
| 460 htree_group->literal_arb |= htrees[GREEN][0].value << 8; |
| 461 } |
| 462 } |
| 463 htree_group->use_packed_table = !htree_group->is_trivial_code && |
| 464 (max_bits < HUFFMAN_PACKED_BITS); |
| 465 if (htree_group->use_packed_table) BuildPackedTable(htree_group); |
365 } | 466 } |
366 WebPSafeFree(huff_codes); | |
367 WebPSafeFree(code_lengths); | 467 WebPSafeFree(code_lengths); |
368 | 468 |
369 // All OK. Finalize pointers and return. | 469 // All OK. Finalize pointers and return. |
370 hdr->huffman_image_ = huffman_image; | 470 hdr->huffman_image_ = huffman_image; |
371 hdr->num_htree_groups_ = num_htree_groups; | 471 hdr->num_htree_groups_ = num_htree_groups; |
372 hdr->htree_groups_ = htree_groups; | 472 hdr->htree_groups_ = htree_groups; |
| 473 hdr->huffman_tables_ = huffman_tables; |
373 return 1; | 474 return 1; |
374 | 475 |
375 Error: | 476 Error: |
376 WebPSafeFree(huff_codes); | |
377 WebPSafeFree(code_lengths); | 477 WebPSafeFree(code_lengths); |
378 WebPSafeFree(huffman_image); | 478 WebPSafeFree(huffman_image); |
379 VP8LHtreeGroupsFree(htree_groups, num_htree_groups); | 479 WebPSafeFree(huffman_tables); |
| 480 VP8LHtreeGroupsFree(htree_groups); |
380 return 0; | 481 return 0; |
381 } | 482 } |
382 | 483 |
383 //------------------------------------------------------------------------------ | 484 //------------------------------------------------------------------------------ |
384 // Scaling. | 485 // Scaling. |
385 | 486 |
386 static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) { | 487 static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) { |
387 const int num_channels = 4; | 488 const int num_channels = 4; |
388 const int in_width = io->mb_w; | 489 const int in_width = io->mb_w; |
389 const int out_width = io->scaled_width; | 490 const int out_width = io->scaled_width; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out); | 568 VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out); |
468 row_in += in_stride; | 569 row_in += in_stride; |
469 row_out += out_stride; | 570 row_out += out_stride; |
470 } | 571 } |
471 return mb_h; // Num rows out == num rows in. | 572 return mb_h; // Num rows out == num rows in. |
472 } | 573 } |
473 | 574 |
474 //------------------------------------------------------------------------------ | 575 //------------------------------------------------------------------------------ |
475 // Export to YUVA | 576 // Export to YUVA |
476 | 577 |
477 // TODO(skal): should be in yuv.c | |
478 static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos, | 578 static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos, |
479 const WebPDecBuffer* const output) { | 579 const WebPDecBuffer* const output) { |
480 const WebPYUVABuffer* const buf = &output->u.YUVA; | 580 const WebPYUVABuffer* const buf = &output->u.YUVA; |
| 581 |
481 // first, the luma plane | 582 // first, the luma plane |
482 { | 583 WebPConvertARGBToY(src, buf->y + y_pos * buf->y_stride, width); |
483 int i; | |
484 uint8_t* const y = buf->y + y_pos * buf->y_stride; | |
485 for (i = 0; i < width; ++i) { | |
486 const uint32_t p = src[i]; | |
487 y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff, | |
488 YUV_HALF); | |
489 } | |
490 } | |
491 | 584 |
492 // then U/V planes | 585 // then U/V planes |
493 { | 586 { |
494 uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride; | 587 uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride; |
495 uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride; | 588 uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride; |
496 const int uv_width = width >> 1; | 589 // even lines: store values |
497 int i; | 590 // odd lines: average with previous values |
498 for (i = 0; i < uv_width; ++i) { | 591 WebPConvertARGBToUV(src, u, v, width, !(y_pos & 1)); |
499 const uint32_t v0 = src[2 * i + 0]; | |
500 const uint32_t v1 = src[2 * i + 1]; | |
501 // VP8RGBToU/V expects four accumulated pixels. Hence we need to | |
502 // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less. | |
503 const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe); | |
504 const int g = ((v0 >> 7) & 0x1fe) + ((v1 >> 7) & 0x1fe); | |
505 const int b = ((v0 << 1) & 0x1fe) + ((v1 << 1) & 0x1fe); | |
506 if (!(y_pos & 1)) { // even lines: store values | |
507 u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); | |
508 v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); | |
509 } else { // odd lines: average with previous values | |
510 const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2); | |
511 const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2); | |
512 // Approximated average-of-four. But it's an acceptable diff. | |
513 u[i] = (u[i] + tmp_u + 1) >> 1; | |
514 v[i] = (v[i] + tmp_v + 1) >> 1; | |
515 } | |
516 } | |
517 if (width & 1) { // last pixel | |
518 const uint32_t v0 = src[2 * i + 0]; | |
519 const int r = (v0 >> 14) & 0x3fc; | |
520 const int g = (v0 >> 6) & 0x3fc; | |
521 const int b = (v0 << 2) & 0x3fc; | |
522 if (!(y_pos & 1)) { // even lines | |
523 u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); | |
524 v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); | |
525 } else { // odd lines (note: we could just skip this) | |
526 const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2); | |
527 const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2); | |
528 u[i] = (u[i] + tmp_u + 1) >> 1; | |
529 v[i] = (v[i] + tmp_v + 1) >> 1; | |
530 } | |
531 } | |
532 } | 592 } |
533 // Lastly, store alpha if needed. | 593 // Lastly, store alpha if needed. |
534 if (buf->a != NULL) { | 594 if (buf->a != NULL) { |
535 int i; | |
536 uint8_t* const a = buf->a + y_pos * buf->a_stride; | 595 uint8_t* const a = buf->a + y_pos * buf->a_stride; |
537 for (i = 0; i < width; ++i) a[i] = (src[i] >> 24); | 596 #if defined(WORDS_BIGENDIAN) |
| 597 WebPExtractAlpha((uint8_t*)src + 0, 0, width, 1, a, 0); |
| 598 #else |
| 599 WebPExtractAlpha((uint8_t*)src + 3, 0, width, 1, a, 0); |
| 600 #endif |
538 } | 601 } |
539 } | 602 } |
540 | 603 |
541 static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) { | 604 static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) { |
542 WebPRescaler* const rescaler = dec->rescaler; | 605 WebPRescaler* const rescaler = dec->rescaler; |
543 uint32_t* const src = (uint32_t*)rescaler->dst; | 606 uint32_t* const src = (uint32_t*)rescaler->dst; |
544 const int dst_width = rescaler->dst_width; | 607 const int dst_width = rescaler->dst_width; |
545 int num_lines_out = 0; | 608 int num_lines_out = 0; |
546 while (WebPRescalerHasPendingOutput(rescaler)) { | 609 while (WebPRescalerHasPendingOutput(rescaler)) { |
547 WebPRescalerExportRow(rescaler); | 610 WebPRescalerExportRow(rescaler); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 | 739 |
677 // Emit output. | 740 // Emit output. |
678 { | 741 { |
679 VP8Io* const io = dec->io_; | 742 VP8Io* const io = dec->io_; |
680 uint8_t* rows_data = (uint8_t*)dec->argb_cache_; | 743 uint8_t* rows_data = (uint8_t*)dec->argb_cache_; |
681 const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA | 744 const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA |
682 if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) { | 745 if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) { |
683 // Nothing to output (this time). | 746 // Nothing to output (this time). |
684 } else { | 747 } else { |
685 const WebPDecBuffer* const output = dec->output_; | 748 const WebPDecBuffer* const output = dec->output_; |
686 if (output->colorspace < MODE_YUV) { // convert to RGBA | 749 if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA |
687 const WebPRGBABuffer* const buf = &output->u.RGBA; | 750 const WebPRGBABuffer* const buf = &output->u.RGBA; |
688 uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride; | 751 uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride; |
689 const int num_rows_out = io->use_scaling ? | 752 const int num_rows_out = io->use_scaling ? |
690 EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h, | 753 EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h, |
691 rgba, buf->stride) : | 754 rgba, buf->stride) : |
692 EmitRows(output->colorspace, rows_data, in_stride, | 755 EmitRows(output->colorspace, rows_data, in_stride, |
693 io->mb_w, io->mb_h, rgba, buf->stride); | 756 io->mb_w, io->mb_h, rgba, buf->stride); |
694 // Update 'last_out_row_'. | 757 // Update 'last_out_row_'. |
695 dec->last_out_row_ += num_rows_out; | 758 dec->last_out_row_ += num_rows_out; |
696 } else { // convert to YUVA | 759 } else { // convert to YUVA |
(...skipping 11 matching lines...) Expand all Loading... |
708 } | 771 } |
709 | 772 |
710 // Row-processing for the special case when alpha data contains only one | 773 // Row-processing for the special case when alpha data contains only one |
711 // transform (color indexing), and trivial non-green literals. | 774 // transform (color indexing), and trivial non-green literals. |
712 static int Is8bOptimizable(const VP8LMetadata* const hdr) { | 775 static int Is8bOptimizable(const VP8LMetadata* const hdr) { |
713 int i; | 776 int i; |
714 if (hdr->color_cache_size_ > 0) return 0; | 777 if (hdr->color_cache_size_ > 0) return 0; |
715 // When the Huffman tree contains only one symbol, we can skip the | 778 // When the Huffman tree contains only one symbol, we can skip the |
716 // call to ReadSymbol() for red/blue/alpha channels. | 779 // call to ReadSymbol() for red/blue/alpha channels. |
717 for (i = 0; i < hdr->num_htree_groups_; ++i) { | 780 for (i = 0; i < hdr->num_htree_groups_; ++i) { |
718 const HuffmanTree* const htrees = hdr->htree_groups_[i].htrees_; | 781 HuffmanCode** const htrees = hdr->htree_groups_[i].htrees; |
719 if (htrees[RED].num_nodes_ > 1) return 0; | 782 if (htrees[RED][0].bits > 0) return 0; |
720 if (htrees[BLUE].num_nodes_ > 1) return 0; | 783 if (htrees[BLUE][0].bits > 0) return 0; |
721 if (htrees[ALPHA].num_nodes_ > 1) return 0; | 784 if (htrees[ALPHA][0].bits > 0) return 0; |
722 } | 785 } |
723 return 1; | 786 return 1; |
724 } | 787 } |
725 | 788 |
726 static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int row) { | 789 static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int row) { |
727 const int num_rows = row - dec->last_row_; | 790 const int num_rows = row - dec->last_row_; |
728 const uint8_t* const in = | 791 const uint8_t* const in = |
729 (uint8_t*)dec->pixels_ + dec->width_ * dec->last_row_; | 792 (uint8_t*)dec->pixels_ + dec->width_ * dec->last_row_; |
730 if (num_rows > 0) { | 793 if (num_rows > 0) { |
731 ApplyInverseTransformsAlpha(dec, num_rows, in); | 794 ApplyInverseTransformsAlpha(dec, num_rows, in); |
732 } | 795 } |
733 dec->last_row_ = dec->last_out_row_ = row; | 796 dec->last_row_ = dec->last_out_row_ = row; |
734 } | 797 } |
735 | 798 |
| 799 //------------------------------------------------------------------------------ |
| 800 // Helper functions for fast pattern copy (8b and 32b) |
| 801 |
| 802 // cyclic rotation of pattern word |
| 803 static WEBP_INLINE uint32_t Rotate8b(uint32_t V) { |
| 804 #if defined(WORDS_BIGENDIAN) |
| 805 return ((V & 0xff000000u) >> 24) | (V << 8); |
| 806 #else |
| 807 return ((V & 0xffu) << 24) | (V >> 8); |
| 808 #endif |
| 809 } |
| 810 |
| 811 // copy 1, 2 or 4-bytes pattern |
| 812 static WEBP_INLINE void CopySmallPattern8b(const uint8_t* src, uint8_t* dst, |
| 813 int length, uint32_t pattern) { |
| 814 int i; |
| 815 // align 'dst' to 4-bytes boundary. Adjust the pattern along the way. |
| 816 while ((uintptr_t)dst & 3) { |
| 817 *dst++ = *src++; |
| 818 pattern = Rotate8b(pattern); |
| 819 --length; |
| 820 } |
| 821 // Copy the pattern 4 bytes at a time. |
| 822 for (i = 0; i < (length >> 2); ++i) { |
| 823 ((uint32_t*)dst)[i] = pattern; |
| 824 } |
| 825 // Finish with left-overs. 'pattern' is still correctly positioned, |
| 826 // so no Rotate8b() call is needed. |
| 827 for (i <<= 2; i < length; ++i) { |
| 828 dst[i] = src[i]; |
| 829 } |
| 830 } |
| 831 |
| 832 static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) { |
| 833 const uint8_t* src = dst - dist; |
| 834 if (length >= 8) { |
| 835 uint32_t pattern = 0; |
| 836 switch (dist) { |
| 837 case 1: |
| 838 pattern = src[0]; |
| 839 #if defined(__arm__) || defined(_M_ARM) // arm doesn't like multiply that much |
| 840 pattern |= pattern << 8; |
| 841 pattern |= pattern << 16; |
| 842 #elif defined(WEBP_USE_MIPS_DSP_R2) |
| 843 __asm__ volatile ("replv.qb %0, %0" : "+r"(pattern)); |
| 844 #else |
| 845 pattern = 0x01010101u * pattern; |
| 846 #endif |
| 847 break; |
| 848 case 2: |
| 849 memcpy(&pattern, src, sizeof(uint16_t)); |
| 850 #if defined(__arm__) || defined(_M_ARM) |
| 851 pattern |= pattern << 16; |
| 852 #elif defined(WEBP_USE_MIPS_DSP_R2) |
| 853 __asm__ volatile ("replv.ph %0, %0" : "+r"(pattern)); |
| 854 #else |
| 855 pattern = 0x00010001u * pattern; |
| 856 #endif |
| 857 break; |
| 858 case 4: |
| 859 memcpy(&pattern, src, sizeof(uint32_t)); |
| 860 break; |
| 861 default: |
| 862 goto Copy; |
| 863 break; |
| 864 } |
| 865 CopySmallPattern8b(src, dst, length, pattern); |
| 866 return; |
| 867 } |
| 868 Copy: |
| 869 if (dist >= length) { // no overlap -> use memcpy() |
| 870 memcpy(dst, src, length * sizeof(*dst)); |
| 871 } else { |
| 872 int i; |
| 873 for (i = 0; i < length; ++i) dst[i] = src[i]; |
| 874 } |
| 875 } |
| 876 |
| 877 // copy pattern of 1 or 2 uint32_t's |
| 878 static WEBP_INLINE void CopySmallPattern32b(const uint32_t* src, |
| 879 uint32_t* dst, |
| 880 int length, uint64_t pattern) { |
| 881 int i; |
| 882 if ((uintptr_t)dst & 4) { // Align 'dst' to 8-bytes boundary. |
| 883 *dst++ = *src++; |
| 884 pattern = (pattern >> 32) | (pattern << 32); |
| 885 --length; |
| 886 } |
| 887 assert(0 == ((uintptr_t)dst & 7)); |
| 888 for (i = 0; i < (length >> 1); ++i) { |
| 889 ((uint64_t*)dst)[i] = pattern; // Copy the pattern 8 bytes at a time. |
| 890 } |
| 891 if (length & 1) { // Finish with left-over. |
| 892 dst[i << 1] = src[i << 1]; |
| 893 } |
| 894 } |
| 895 |
| 896 static WEBP_INLINE void CopyBlock32b(uint32_t* const dst, |
| 897 int dist, int length) { |
| 898 const uint32_t* const src = dst - dist; |
| 899 if (dist <= 2 && length >= 4 && ((uintptr_t)dst & 3) == 0) { |
| 900 uint64_t pattern; |
| 901 if (dist == 1) { |
| 902 pattern = (uint64_t)src[0]; |
| 903 pattern |= pattern << 32; |
| 904 } else { |
| 905 memcpy(&pattern, src, sizeof(pattern)); |
| 906 } |
| 907 CopySmallPattern32b(src, dst, length, pattern); |
| 908 } else if (dist >= length) { // no overlap |
| 909 memcpy(dst, src, length * sizeof(*dst)); |
| 910 } else { |
| 911 int i; |
| 912 for (i = 0; i < length; ++i) dst[i] = src[i]; |
| 913 } |
| 914 } |
| 915 |
| 916 //------------------------------------------------------------------------------ |
| 917 |
736 static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data, | 918 static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data, |
737 int width, int height, int last_row) { | 919 int width, int height, int last_row) { |
738 int ok = 1; | 920 int ok = 1; |
739 int row = dec->last_pixel_ / width; | 921 int row = dec->last_pixel_ / width; |
740 int col = dec->last_pixel_ % width; | 922 int col = dec->last_pixel_ % width; |
741 VP8LBitReader* const br = &dec->br_; | 923 VP8LBitReader* const br = &dec->br_; |
742 VP8LMetadata* const hdr = &dec->hdr_; | 924 VP8LMetadata* const hdr = &dec->hdr_; |
743 const HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row); | 925 const HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row); |
744 int pos = dec->last_pixel_; // current position | 926 int pos = dec->last_pixel_; // current position |
745 const int end = width * height; // End of data | 927 const int end = width * height; // End of data |
746 const int last = width * last_row; // Last pixel to decode | 928 const int last = width * last_row; // Last pixel to decode |
747 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; | 929 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; |
748 const int mask = hdr->huffman_mask_; | 930 const int mask = hdr->huffman_mask_; |
749 assert(htree_group != NULL); | 931 assert(htree_group != NULL); |
750 assert(pos < end); | 932 assert(pos < end); |
751 assert(last_row <= height); | 933 assert(last_row <= height); |
752 assert(Is8bOptimizable(hdr)); | 934 assert(Is8bOptimizable(hdr)); |
753 | 935 |
754 while (!br->eos_ && pos < last) { | 936 while (!br->eos_ && pos < last) { |
755 int code; | 937 int code; |
756 // Only update when changing tile. | 938 // Only update when changing tile. |
757 if ((col & mask) == 0) { | 939 if ((col & mask) == 0) { |
758 htree_group = GetHtreeGroupForPos(hdr, col, row); | 940 htree_group = GetHtreeGroupForPos(hdr, col, row); |
759 } | 941 } |
760 VP8LFillBitWindow(br); | 942 VP8LFillBitWindow(br); |
761 code = ReadSymbol(&htree_group->htrees_[GREEN], br); | 943 code = ReadSymbol(htree_group->htrees[GREEN], br); |
762 if (code < NUM_LITERAL_CODES) { // Literal | 944 if (code < NUM_LITERAL_CODES) { // Literal |
763 data[pos] = code; | 945 data[pos] = code; |
764 ++pos; | 946 ++pos; |
765 ++col; | 947 ++col; |
766 if (col >= width) { | 948 if (col >= width) { |
767 col = 0; | 949 col = 0; |
768 ++row; | 950 ++row; |
769 if (row % NUM_ARGB_CACHE_ROWS == 0) { | 951 if (row % NUM_ARGB_CACHE_ROWS == 0) { |
770 ExtractPalettedAlphaRows(dec, row); | 952 ExtractPalettedAlphaRows(dec, row); |
771 } | 953 } |
772 } | 954 } |
773 } else if (code < len_code_limit) { // Backward reference | 955 } else if (code < len_code_limit) { // Backward reference |
774 int dist_code, dist; | 956 int dist_code, dist; |
775 const int length_sym = code - NUM_LITERAL_CODES; | 957 const int length_sym = code - NUM_LITERAL_CODES; |
776 const int length = GetCopyLength(length_sym, br); | 958 const int length = GetCopyLength(length_sym, br); |
777 const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br); | 959 const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br); |
778 VP8LFillBitWindow(br); | 960 VP8LFillBitWindow(br); |
779 dist_code = GetCopyDistance(dist_symbol, br); | 961 dist_code = GetCopyDistance(dist_symbol, br); |
780 dist = PlaneCodeToDistance(width, dist_code); | 962 dist = PlaneCodeToDistance(width, dist_code); |
781 if (pos >= dist && end - pos >= length) { | 963 if (pos >= dist && end - pos >= length) { |
782 int i; | 964 CopyBlock8b(data + pos, dist, length); |
783 for (i = 0; i < length; ++i) data[pos + i] = data[pos + i - dist]; | |
784 } else { | 965 } else { |
785 ok = 0; | 966 ok = 0; |
786 goto End; | 967 goto End; |
787 } | 968 } |
788 pos += length; | 969 pos += length; |
789 col += length; | 970 col += length; |
790 while (col >= width) { | 971 while (col >= width) { |
791 col -= width; | 972 col -= width; |
792 ++row; | 973 ++row; |
793 if (row % NUM_ARGB_CACHE_ROWS == 0) { | 974 if (row % NUM_ARGB_CACHE_ROWS == 0) { |
794 ExtractPalettedAlphaRows(dec, row); | 975 ExtractPalettedAlphaRows(dec, row); |
795 } | 976 } |
796 } | 977 } |
797 if (pos < last && (col & mask)) { | 978 if (pos < last && (col & mask)) { |
798 htree_group = GetHtreeGroupForPos(hdr, col, row); | 979 htree_group = GetHtreeGroupForPos(hdr, col, row); |
799 } | 980 } |
800 } else { // Not reached | 981 } else { // Not reached |
801 ok = 0; | 982 ok = 0; |
802 goto End; | 983 goto End; |
803 } | 984 } |
804 assert(br->eos_ == VP8LIsEndOfStream(br)); | 985 assert(br->eos_ == VP8LIsEndOfStream(br)); |
805 ok = !br->error_; | |
806 if (!ok) goto End; | |
807 } | 986 } |
808 // Process the remaining rows corresponding to last row-block. | 987 // Process the remaining rows corresponding to last row-block. |
809 ExtractPalettedAlphaRows(dec, row); | 988 ExtractPalettedAlphaRows(dec, row); |
810 | 989 |
811 End: | 990 End: |
812 if (br->error_ || !ok || (br->eos_ && pos < end)) { | 991 if (!ok || (br->eos_ && pos < end)) { |
813 ok = 0; | 992 ok = 0; |
814 dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED | 993 dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED |
815 : VP8_STATUS_BITSTREAM_ERROR; | 994 : VP8_STATUS_BITSTREAM_ERROR; |
816 } else { | 995 } else { |
817 dec->last_pixel_ = (int)pos; | 996 dec->last_pixel_ = pos; |
818 if (pos == end) dec->state_ = READ_DATA; | |
819 } | 997 } |
820 return ok; | 998 return ok; |
821 } | 999 } |
822 | 1000 |
| 1001 static void SaveState(VP8LDecoder* const dec, int last_pixel) { |
| 1002 assert(dec->incremental_); |
| 1003 dec->saved_br_ = dec->br_; |
| 1004 dec->saved_last_pixel_ = last_pixel; |
| 1005 if (dec->hdr_.color_cache_size_ > 0) { |
| 1006 VP8LColorCacheCopy(&dec->hdr_.color_cache_, &dec->hdr_.saved_color_cache_); |
| 1007 } |
| 1008 } |
| 1009 |
| 1010 static void RestoreState(VP8LDecoder* const dec) { |
| 1011 assert(dec->br_.eos_); |
| 1012 dec->status_ = VP8_STATUS_SUSPENDED; |
| 1013 dec->br_ = dec->saved_br_; |
| 1014 dec->last_pixel_ = dec->saved_last_pixel_; |
| 1015 if (dec->hdr_.color_cache_size_ > 0) { |
| 1016 VP8LColorCacheCopy(&dec->hdr_.saved_color_cache_, &dec->hdr_.color_cache_); |
| 1017 } |
| 1018 } |
| 1019 |
| 1020 #define SYNC_EVERY_N_ROWS 8 // minimum number of rows between check-points |
823 static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data, | 1021 static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data, |
824 int width, int height, int last_row, | 1022 int width, int height, int last_row, |
825 ProcessRowsFunc process_func) { | 1023 ProcessRowsFunc process_func) { |
826 int ok = 1; | |
827 int row = dec->last_pixel_ / width; | 1024 int row = dec->last_pixel_ / width; |
828 int col = dec->last_pixel_ % width; | 1025 int col = dec->last_pixel_ % width; |
829 VP8LBitReader* const br = &dec->br_; | 1026 VP8LBitReader* const br = &dec->br_; |
830 VP8LMetadata* const hdr = &dec->hdr_; | 1027 VP8LMetadata* const hdr = &dec->hdr_; |
831 HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row); | 1028 HTreeGroup* htree_group = GetHtreeGroupForPos(hdr, col, row); |
832 uint32_t* src = data + dec->last_pixel_; | 1029 uint32_t* src = data + dec->last_pixel_; |
833 uint32_t* last_cached = src; | 1030 uint32_t* last_cached = src; |
834 uint32_t* const src_end = data + width * height; // End of data | 1031 uint32_t* const src_end = data + width * height; // End of data |
835 uint32_t* const src_last = data + width * last_row; // Last pixel to decode | 1032 uint32_t* const src_last = data + width * last_row; // Last pixel to decode |
836 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; | 1033 const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES; |
837 const int color_cache_limit = len_code_limit + hdr->color_cache_size_; | 1034 const int color_cache_limit = len_code_limit + hdr->color_cache_size_; |
| 1035 int next_sync_row = dec->incremental_ ? row : 1 << 24; |
838 VP8LColorCache* const color_cache = | 1036 VP8LColorCache* const color_cache = |
839 (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL; | 1037 (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL; |
840 const int mask = hdr->huffman_mask_; | 1038 const int mask = hdr->huffman_mask_; |
841 assert(htree_group != NULL); | 1039 assert(htree_group != NULL); |
842 assert(src < src_end); | 1040 assert(src < src_end); |
843 assert(src_last <= src_end); | 1041 assert(src_last <= src_end); |
844 | 1042 |
845 while (!br->eos_ && src < src_last) { | 1043 while (src < src_last) { |
846 int code; | 1044 int code; |
| 1045 if (row >= next_sync_row) { |
| 1046 SaveState(dec, (int)(src - data)); |
| 1047 next_sync_row = row + SYNC_EVERY_N_ROWS; |
| 1048 } |
847 // Only update when changing tile. Note we could use this test: | 1049 // Only update when changing tile. Note we could use this test: |
848 // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed | 1050 // if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed |
849 // but that's actually slower and needs storing the previous col/row. | 1051 // but that's actually slower and needs storing the previous col/row. |
850 if ((col & mask) == 0) { | 1052 if ((col & mask) == 0) htree_group = GetHtreeGroupForPos(hdr, col, row); |
851 htree_group = GetHtreeGroupForPos(hdr, col, row); | 1053 if (htree_group->is_trivial_code) { |
| 1054 *src = htree_group->literal_arb; |
| 1055 goto AdvanceByOne; |
852 } | 1056 } |
853 VP8LFillBitWindow(br); | 1057 VP8LFillBitWindow(br); |
854 code = ReadSymbol(&htree_group->htrees_[GREEN], br); | 1058 if (htree_group->use_packed_table) { |
| 1059 code = ReadPackedSymbols(htree_group, br, src); |
| 1060 if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne; |
| 1061 } else { |
| 1062 code = ReadSymbol(htree_group->htrees[GREEN], br); |
| 1063 } |
| 1064 if (br->eos_) break; // early out |
855 if (code < NUM_LITERAL_CODES) { // Literal | 1065 if (code < NUM_LITERAL_CODES) { // Literal |
856 int red, green, blue, alpha; | 1066 if (htree_group->is_trivial_literal) { |
857 red = ReadSymbol(&htree_group->htrees_[RED], br); | 1067 *src = htree_group->literal_arb | (code << 8); |
858 green = code; | 1068 } else { |
859 VP8LFillBitWindow(br); | 1069 int red, blue, alpha; |
860 blue = ReadSymbol(&htree_group->htrees_[BLUE], br); | 1070 red = ReadSymbol(htree_group->htrees[RED], br); |
861 alpha = ReadSymbol(&htree_group->htrees_[ALPHA], br); | 1071 VP8LFillBitWindow(br); |
862 *src = ((uint32_t)alpha << 24) | (red << 16) | (green << 8) | blue; | 1072 blue = ReadSymbol(htree_group->htrees[BLUE], br); |
| 1073 alpha = ReadSymbol(htree_group->htrees[ALPHA], br); |
| 1074 if (br->eos_) break; |
| 1075 *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue; |
| 1076 } |
863 AdvanceByOne: | 1077 AdvanceByOne: |
864 ++src; | 1078 ++src; |
865 ++col; | 1079 ++col; |
866 if (col >= width) { | 1080 if (col >= width) { |
867 col = 0; | 1081 col = 0; |
868 ++row; | 1082 ++row; |
869 if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { | 1083 if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { |
870 process_func(dec, row); | 1084 process_func(dec, row); |
871 } | 1085 } |
872 if (color_cache != NULL) { | 1086 if (color_cache != NULL) { |
873 while (last_cached < src) { | 1087 while (last_cached < src) { |
874 VP8LColorCacheInsert(color_cache, *last_cached++); | 1088 VP8LColorCacheInsert(color_cache, *last_cached++); |
875 } | 1089 } |
876 } | 1090 } |
877 } | 1091 } |
878 } else if (code < len_code_limit) { // Backward reference | 1092 } else if (code < len_code_limit) { // Backward reference |
879 int dist_code, dist; | 1093 int dist_code, dist; |
880 const int length_sym = code - NUM_LITERAL_CODES; | 1094 const int length_sym = code - NUM_LITERAL_CODES; |
881 const int length = GetCopyLength(length_sym, br); | 1095 const int length = GetCopyLength(length_sym, br); |
882 const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br); | 1096 const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br); |
883 VP8LFillBitWindow(br); | 1097 VP8LFillBitWindow(br); |
884 dist_code = GetCopyDistance(dist_symbol, br); | 1098 dist_code = GetCopyDistance(dist_symbol, br); |
885 dist = PlaneCodeToDistance(width, dist_code); | 1099 dist = PlaneCodeToDistance(width, dist_code); |
| 1100 if (br->eos_) break; |
886 if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { | 1101 if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { |
887 ok = 0; | 1102 goto Error; |
888 goto End; | |
889 } else { | 1103 } else { |
890 int i; | 1104 CopyBlock32b(src, dist, length); |
891 for (i = 0; i < length; ++i) src[i] = src[i - dist]; | |
892 src += length; | |
893 } | 1105 } |
| 1106 src += length; |
894 col += length; | 1107 col += length; |
895 while (col >= width) { | 1108 while (col >= width) { |
896 col -= width; | 1109 col -= width; |
897 ++row; | 1110 ++row; |
898 if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { | 1111 if ((row % NUM_ARGB_CACHE_ROWS == 0) && (process_func != NULL)) { |
899 process_func(dec, row); | 1112 process_func(dec, row); |
900 } | 1113 } |
901 } | 1114 } |
902 if (src < src_end) { | 1115 // Because of the check done above (before 'src' was incremented by |
903 if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row); | 1116 // 'length'), the following holds true. |
904 if (color_cache != NULL) { | 1117 assert(src <= src_end); |
905 while (last_cached < src) { | 1118 if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row); |
906 VP8LColorCacheInsert(color_cache, *last_cached++); | 1119 if (color_cache != NULL) { |
907 } | 1120 while (last_cached < src) { |
| 1121 VP8LColorCacheInsert(color_cache, *last_cached++); |
908 } | 1122 } |
909 } | 1123 } |
910 } else if (code < color_cache_limit) { // Color cache | 1124 } else if (code < color_cache_limit) { // Color cache |
911 const int key = code - len_code_limit; | 1125 const int key = code - len_code_limit; |
912 assert(color_cache != NULL); | 1126 assert(color_cache != NULL); |
913 while (last_cached < src) { | 1127 while (last_cached < src) { |
914 VP8LColorCacheInsert(color_cache, *last_cached++); | 1128 VP8LColorCacheInsert(color_cache, *last_cached++); |
915 } | 1129 } |
916 *src = VP8LColorCacheLookup(color_cache, key); | 1130 *src = VP8LColorCacheLookup(color_cache, key); |
917 goto AdvanceByOne; | 1131 goto AdvanceByOne; |
918 } else { // Not reached | 1132 } else { // Not reached |
919 ok = 0; | 1133 goto Error; |
920 goto End; | |
921 } | 1134 } |
922 assert(br->eos_ == VP8LIsEndOfStream(br)); | 1135 assert(br->eos_ == VP8LIsEndOfStream(br)); |
923 ok = !br->error_; | |
924 if (!ok) goto End; | |
925 } | 1136 } |
926 // Process the remaining rows corresponding to last row-block. | |
927 if (process_func != NULL) process_func(dec, row); | |
928 | 1137 |
929 End: | 1138 if (dec->incremental_ && br->eos_ && src < src_end) { |
930 if (br->error_ || !ok || (br->eos_ && src < src_end)) { | 1139 RestoreState(dec); |
931 ok = 0; | 1140 } else if (!br->eos_) { |
932 dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED | 1141 // Process the remaining rows corresponding to last row-block. |
933 : VP8_STATUS_BITSTREAM_ERROR; | 1142 if (process_func != NULL) { |
| 1143 process_func(dec, row); |
| 1144 } |
| 1145 dec->status_ = VP8_STATUS_OK; |
| 1146 dec->last_pixel_ = (int)(src - data); // end-of-scan marker |
934 } else { | 1147 } else { |
935 dec->last_pixel_ = (int)(src - data); | 1148 // if not incremental, and we are past the end of buffer (eos_=1), then this |
936 if (src == src_end) dec->state_ = READ_DATA; | 1149 // is a real bitstream error. |
| 1150 goto Error; |
937 } | 1151 } |
938 return ok; | 1152 return 1; |
| 1153 |
| 1154 Error: |
| 1155 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; |
| 1156 return 0; |
939 } | 1157 } |
940 | 1158 |
941 // ----------------------------------------------------------------------------- | 1159 // ----------------------------------------------------------------------------- |
942 // VP8LTransform | 1160 // VP8LTransform |
943 | 1161 |
944 static void ClearTransform(VP8LTransform* const transform) { | 1162 static void ClearTransform(VP8LTransform* const transform) { |
945 WebPSafeFree(transform->data_); | 1163 WebPSafeFree(transform->data_); |
946 transform->data_ = NULL; | 1164 transform->data_ = NULL; |
947 } | 1165 } |
948 | 1166 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 break; | 1240 break; |
1023 } | 1241 } |
1024 | 1242 |
1025 return ok; | 1243 return ok; |
1026 } | 1244 } |
1027 | 1245 |
1028 // ----------------------------------------------------------------------------- | 1246 // ----------------------------------------------------------------------------- |
1029 // VP8LMetadata | 1247 // VP8LMetadata |
1030 | 1248 |
1031 static void InitMetadata(VP8LMetadata* const hdr) { | 1249 static void InitMetadata(VP8LMetadata* const hdr) { |
1032 assert(hdr); | 1250 assert(hdr != NULL); |
1033 memset(hdr, 0, sizeof(*hdr)); | 1251 memset(hdr, 0, sizeof(*hdr)); |
1034 } | 1252 } |
1035 | 1253 |
1036 static void ClearMetadata(VP8LMetadata* const hdr) { | 1254 static void ClearMetadata(VP8LMetadata* const hdr) { |
1037 assert(hdr); | 1255 assert(hdr != NULL); |
1038 | 1256 |
1039 WebPSafeFree(hdr->huffman_image_); | 1257 WebPSafeFree(hdr->huffman_image_); |
1040 VP8LHtreeGroupsFree(hdr->htree_groups_, hdr->num_htree_groups_); | 1258 WebPSafeFree(hdr->huffman_tables_); |
| 1259 VP8LHtreeGroupsFree(hdr->htree_groups_); |
1041 VP8LColorCacheClear(&hdr->color_cache_); | 1260 VP8LColorCacheClear(&hdr->color_cache_); |
| 1261 VP8LColorCacheClear(&hdr->saved_color_cache_); |
1042 InitMetadata(hdr); | 1262 InitMetadata(hdr); |
1043 } | 1263 } |
1044 | 1264 |
1045 // ----------------------------------------------------------------------------- | 1265 // ----------------------------------------------------------------------------- |
1046 // VP8LDecoder | 1266 // VP8LDecoder |
1047 | 1267 |
1048 VP8LDecoder* VP8LNew(void) { | 1268 VP8LDecoder* VP8LNew(void) { |
1049 VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); | 1269 VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); |
1050 if (dec == NULL) return NULL; | 1270 if (dec == NULL) return NULL; |
1051 dec->status_ = VP8_STATUS_OK; | 1271 dec->status_ = VP8_STATUS_OK; |
1052 dec->action_ = READ_DIM; | |
1053 dec->state_ = READ_DIM; | 1272 dec->state_ = READ_DIM; |
1054 | 1273 |
1055 VP8LDspInit(); // Init critical function pointers. | 1274 VP8LDspInit(); // Init critical function pointers. |
1056 | 1275 |
1057 return dec; | 1276 return dec; |
1058 } | 1277 } |
1059 | 1278 |
1060 void VP8LClear(VP8LDecoder* const dec) { | 1279 void VP8LClear(VP8LDecoder* const dec) { |
1061 int i; | 1280 int i; |
1062 if (dec == NULL) return; | 1281 if (dec == NULL) return; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 if (data == NULL) { | 1373 if (data == NULL) { |
1155 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; | 1374 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; |
1156 ok = 0; | 1375 ok = 0; |
1157 goto End; | 1376 goto End; |
1158 } | 1377 } |
1159 } | 1378 } |
1160 | 1379 |
1161 // Use the Huffman trees to decode the LZ77 encoded data. | 1380 // Use the Huffman trees to decode the LZ77 encoded data. |
1162 ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, | 1381 ok = DecodeImageData(dec, data, transform_xsize, transform_ysize, |
1163 transform_ysize, NULL); | 1382 transform_ysize, NULL); |
1164 ok = ok && !br->error_; | 1383 ok = ok && !br->eos_; |
1165 | 1384 |
1166 End: | 1385 End: |
1167 | |
1168 if (!ok) { | 1386 if (!ok) { |
1169 WebPSafeFree(data); | 1387 WebPSafeFree(data); |
1170 ClearMetadata(hdr); | 1388 ClearMetadata(hdr); |
1171 // If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the | |
1172 // status appropriately. | |
1173 if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR && dec->br_.eos_) { | |
1174 dec->status_ = VP8_STATUS_SUSPENDED; | |
1175 } | |
1176 } else { | 1389 } else { |
1177 if (decoded_data != NULL) { | 1390 if (decoded_data != NULL) { |
1178 *decoded_data = data; | 1391 *decoded_data = data; |
1179 } else { | 1392 } else { |
1180 // We allocate image data in this function only for transforms. At level 0 | 1393 // We allocate image data in this function only for transforms. At level 0 |
1181 // (that is: not the transforms), we shouldn't have allocated anything. | 1394 // (that is: not the transforms), we shouldn't have allocated anything. |
1182 assert(data == NULL); | 1395 assert(data == NULL); |
1183 assert(is_level0); | 1396 assert(is_level0); |
1184 } | 1397 } |
1185 dec->last_pixel_ = 0; // Reset for future DECODE_DATA_FUNC() calls. | 1398 dec->last_pixel_ = 0; // Reset for future DECODE_DATA_FUNC() calls. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 | 1475 |
1263 VP8InitIo(io); | 1476 VP8InitIo(io); |
1264 WebPInitCustomIo(NULL, io); // Just a sanity Init. io won't be used. | 1477 WebPInitCustomIo(NULL, io); // Just a sanity Init. io won't be used. |
1265 io->opaque = output; | 1478 io->opaque = output; |
1266 io->width = alph_dec->width_; | 1479 io->width = alph_dec->width_; |
1267 io->height = alph_dec->height_; | 1480 io->height = alph_dec->height_; |
1268 | 1481 |
1269 dec->status_ = VP8_STATUS_OK; | 1482 dec->status_ = VP8_STATUS_OK; |
1270 VP8LInitBitReader(&dec->br_, data, data_size); | 1483 VP8LInitBitReader(&dec->br_, data, data_size); |
1271 | 1484 |
1272 dec->action_ = READ_HDR; | |
1273 if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) { | 1485 if (!DecodeImageStream(alph_dec->width_, alph_dec->height_, 1, dec, NULL)) { |
1274 goto Err; | 1486 goto Err; |
1275 } | 1487 } |
1276 | 1488 |
1277 // Special case: if alpha data uses only the color indexing transform and | 1489 // Special case: if alpha data uses only the color indexing transform and |
1278 // doesn't use color cache (a frequent case), we will use DecodeAlphaData() | 1490 // doesn't use color cache (a frequent case), we will use DecodeAlphaData() |
1279 // method that only needs allocation of 1 byte per pixel (alpha channel). | 1491 // method that only needs allocation of 1 byte per pixel (alpha channel). |
1280 if (dec->next_transform_ == 1 && | 1492 if (dec->next_transform_ == 1 && |
1281 dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM && | 1493 dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM && |
1282 Is8bOptimizable(&dec->hdr_)) { | 1494 Is8bOptimizable(&dec->hdr_)) { |
1283 alph_dec->use_8b_decode = 1; | 1495 alph_dec->use_8b_decode = 1; |
1284 ok = AllocateInternalBuffers8b(dec); | 1496 ok = AllocateInternalBuffers8b(dec); |
1285 } else { | 1497 } else { |
1286 // Allocate internal buffers (note that dec->width_ may have changed here). | 1498 // Allocate internal buffers (note that dec->width_ may have changed here). |
1287 alph_dec->use_8b_decode = 0; | 1499 alph_dec->use_8b_decode = 0; |
1288 ok = AllocateInternalBuffers32b(dec, alph_dec->width_); | 1500 ok = AllocateInternalBuffers32b(dec, alph_dec->width_); |
1289 } | 1501 } |
1290 | 1502 |
1291 if (!ok) goto Err; | 1503 if (!ok) goto Err; |
1292 | 1504 |
1293 dec->action_ = READ_DATA; | |
1294 return 1; | 1505 return 1; |
1295 | 1506 |
1296 Err: | 1507 Err: |
1297 VP8LDelete(alph_dec->vp8l_dec_); | 1508 VP8LDelete(alph_dec->vp8l_dec_); |
1298 alph_dec->vp8l_dec_ = NULL; | 1509 alph_dec->vp8l_dec_ = NULL; |
1299 return 0; | 1510 return 0; |
1300 } | 1511 } |
1301 | 1512 |
1302 int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) { | 1513 int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) { |
1303 VP8LDecoder* const dec = alph_dec->vp8l_dec_; | 1514 VP8LDecoder* const dec = alph_dec->vp8l_dec_; |
1304 assert(dec != NULL); | 1515 assert(dec != NULL); |
1305 assert(dec->action_ == READ_DATA); | |
1306 assert(last_row <= dec->height_); | 1516 assert(last_row <= dec->height_); |
1307 | 1517 |
1308 if (dec->last_pixel_ == dec->width_ * dec->height_) { | 1518 if (dec->last_pixel_ == dec->width_ * dec->height_) { |
1309 return 1; // done | 1519 return 1; // done |
1310 } | 1520 } |
1311 | 1521 |
1312 // Decode (with special row processing). | 1522 // Decode (with special row processing). |
1313 return alph_dec->use_8b_decode ? | 1523 return alph_dec->use_8b_decode ? |
1314 DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_, | 1524 DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_, |
1315 last_row) : | 1525 last_row) : |
(...skipping 16 matching lines...) Expand all Loading... |
1332 dec->status_ = VP8_STATUS_OK; | 1542 dec->status_ = VP8_STATUS_OK; |
1333 VP8LInitBitReader(&dec->br_, io->data, io->data_size); | 1543 VP8LInitBitReader(&dec->br_, io->data, io->data_size); |
1334 if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) { | 1544 if (!ReadImageInfo(&dec->br_, &width, &height, &has_alpha)) { |
1335 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 1545 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; |
1336 goto Error; | 1546 goto Error; |
1337 } | 1547 } |
1338 dec->state_ = READ_DIM; | 1548 dec->state_ = READ_DIM; |
1339 io->width = width; | 1549 io->width = width; |
1340 io->height = height; | 1550 io->height = height; |
1341 | 1551 |
1342 dec->action_ = READ_HDR; | |
1343 if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error; | 1552 if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Error; |
1344 return 1; | 1553 return 1; |
1345 | 1554 |
1346 Error: | 1555 Error: |
1347 VP8LClear(dec); | 1556 VP8LClear(dec); |
1348 assert(dec->status_ != VP8_STATUS_OK); | 1557 assert(dec->status_ != VP8_STATUS_OK); |
1349 return 0; | 1558 return 0; |
1350 } | 1559 } |
1351 | 1560 |
1352 int VP8LDecodeImage(VP8LDecoder* const dec) { | 1561 int VP8LDecodeImage(VP8LDecoder* const dec) { |
1353 VP8Io* io = NULL; | 1562 VP8Io* io = NULL; |
1354 WebPDecParams* params = NULL; | 1563 WebPDecParams* params = NULL; |
1355 | 1564 |
1356 // Sanity checks. | 1565 // Sanity checks. |
1357 if (dec == NULL) return 0; | 1566 if (dec == NULL) return 0; |
1358 | 1567 |
1359 dec->status_ = VP8_STATUS_BITSTREAM_ERROR; | 1568 assert(dec->hdr_.huffman_tables_ != NULL); |
1360 assert(dec->hdr_.htree_groups_ != NULL); | 1569 assert(dec->hdr_.htree_groups_ != NULL); |
1361 assert(dec->hdr_.num_htree_groups_ > 0); | 1570 assert(dec->hdr_.num_htree_groups_ > 0); |
1362 | 1571 |
1363 io = dec->io_; | 1572 io = dec->io_; |
1364 assert(io != NULL); | 1573 assert(io != NULL); |
1365 params = (WebPDecParams*)io->opaque; | 1574 params = (WebPDecParams*)io->opaque; |
1366 assert(params != NULL); | 1575 assert(params != NULL); |
1367 dec->output_ = params->output; | |
1368 assert(dec->output_ != NULL); | |
1369 | 1576 |
1370 // Initialization. | 1577 // Initialization. |
1371 if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) { | 1578 if (dec->state_ != READ_DATA) { |
1372 dec->status_ = VP8_STATUS_INVALID_PARAM; | 1579 dec->output_ = params->output; |
1373 goto Err; | 1580 assert(dec->output_ != NULL); |
1374 } | |
1375 | 1581 |
1376 if (!AllocateInternalBuffers32b(dec, io->width)) goto Err; | 1582 if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) { |
| 1583 dec->status_ = VP8_STATUS_INVALID_PARAM; |
| 1584 goto Err; |
| 1585 } |
1377 | 1586 |
1378 if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err; | 1587 if (!AllocateInternalBuffers32b(dec, io->width)) goto Err; |
1379 | 1588 |
1380 if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) { | 1589 if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err; |
1381 // need the alpha-multiply functions for premultiplied output or rescaling | 1590 |
1382 WebPInitAlphaProcessing(); | 1591 if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) { |
| 1592 // need the alpha-multiply functions for premultiplied output or rescaling |
| 1593 WebPInitAlphaProcessing(); |
| 1594 } |
| 1595 if (!WebPIsRGBMode(dec->output_->colorspace)) { |
| 1596 WebPInitConvertARGBToYUV(); |
| 1597 if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing(); |
| 1598 } |
| 1599 if (dec->incremental_) { |
| 1600 if (dec->hdr_.color_cache_size_ > 0 && |
| 1601 dec->hdr_.saved_color_cache_.colors_ == NULL) { |
| 1602 if (!VP8LColorCacheInit(&dec->hdr_.saved_color_cache_, |
| 1603 dec->hdr_.color_cache_.hash_bits_)) { |
| 1604 dec->status_ = VP8_STATUS_OUT_OF_MEMORY; |
| 1605 goto Err; |
| 1606 } |
| 1607 } |
| 1608 } |
| 1609 dec->state_ = READ_DATA; |
1383 } | 1610 } |
1384 | 1611 |
1385 // Decode. | 1612 // Decode. |
1386 dec->action_ = READ_DATA; | |
1387 if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_, | 1613 if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_, |
1388 dec->height_, ProcessRows)) { | 1614 dec->height_, ProcessRows)) { |
1389 goto Err; | 1615 goto Err; |
1390 } | 1616 } |
1391 | 1617 |
1392 // Cleanup. | |
1393 params->last_y = dec->last_out_row_; | 1618 params->last_y = dec->last_out_row_; |
1394 VP8LClear(dec); | |
1395 return 1; | 1619 return 1; |
1396 | 1620 |
1397 Err: | 1621 Err: |
1398 VP8LClear(dec); | 1622 VP8LClear(dec); |
1399 assert(dec->status_ != VP8_STATUS_OK); | 1623 assert(dec->status_ != VP8_STATUS_OK); |
1400 return 0; | 1624 return 0; |
1401 } | 1625 } |
1402 | 1626 |
1403 //------------------------------------------------------------------------------ | 1627 //------------------------------------------------------------------------------ |
OLD | NEW |