Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libwebp/src/dec/vp8l_dec.c
21395 views
1
// Copyright 2012 Google Inc. All Rights Reserved.
2
//
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
5
// tree. An additional intellectual property rights grant can be found
6
// in the file PATENTS. All contributing project authors may
7
// be found in the AUTHORS file in the root of the source tree.
8
// -----------------------------------------------------------------------------
9
//
10
// main entry for the decoder
11
//
12
// Authors: Vikas Arora ([email protected])
13
// Jyrki Alakuijala ([email protected])
14
15
#include <assert.h>
16
#include <stddef.h>
17
#include <stdlib.h>
18
#include <string.h>
19
20
#include "src/dec/alphai_dec.h"
21
#include "src/dec/vp8_dec.h"
22
#include "src/dec/vp8li_dec.h"
23
#include "src/dec/webpi_dec.h"
24
#include "src/dsp/dsp.h"
25
#include "src/dsp/lossless.h"
26
#include "src/dsp/lossless_common.h"
27
#include "src/utils/bit_reader_utils.h"
28
#include "src/utils/color_cache_utils.h"
29
#include "src/utils/huffman_utils.h"
30
#include "src/utils/rescaler_utils.h"
31
#include "src/utils/utils.h"
32
#include "src/webp/decode.h"
33
#include "src/webp/format_constants.h"
34
#include "src/webp/types.h"
35
36
#define NUM_ARGB_CACHE_ROWS 16
37
38
static const int kCodeLengthLiterals = 16;
39
static const int kCodeLengthRepeatCode = 16;
40
static const uint8_t kCodeLengthExtraBits[3] = { 2, 3, 7 };
41
static const uint8_t kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
42
43
// -----------------------------------------------------------------------------
44
// Five Huffman codes are used at each meta code:
45
// 1. green + length prefix codes + color cache codes,
46
// 2. alpha,
47
// 3. red,
48
// 4. blue, and,
49
// 5. distance prefix codes.
50
typedef enum {
51
GREEN = 0,
52
RED = 1,
53
BLUE = 2,
54
ALPHA = 3,
55
DIST = 4
56
} HuffIndex;
57
58
static const uint16_t kAlphabetSize[HUFFMAN_CODES_PER_META_CODE] = {
59
NUM_LITERAL_CODES + NUM_LENGTH_CODES,
60
NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
61
NUM_DISTANCE_CODES
62
};
63
64
static const uint8_t kLiteralMap[HUFFMAN_CODES_PER_META_CODE] = {
65
0, 1, 1, 1, 0
66
};
67
68
#define NUM_CODE_LENGTH_CODES 19
69
static const uint8_t kCodeLengthCodeOrder[NUM_CODE_LENGTH_CODES] = {
70
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
71
};
72
73
#define CODE_TO_PLANE_CODES 120
74
static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
75
0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a,
76
0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a,
77
0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b,
78
0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03,
79
0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c,
80
0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e,
81
0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b,
82
0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f,
83
0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b,
84
0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41,
85
0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f,
86
0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70
87
};
88
89
// Memory needed for lookup tables of one Huffman tree group. Red, blue, alpha
90
// and distance alphabets are constant (256 for red, blue and alpha, 40 for
91
// distance) and lookup table sizes for them in worst case are 630 and 410
92
// respectively. Size of green alphabet depends on color cache size and is equal
93
// to 256 (green component values) + 24 (length prefix values)
94
// + color_cache_size (between 0 and 2048).
95
// All values computed for 8-bit first level lookup with Mark Adler's tool:
96
// https://github.com/madler/zlib/blob/v1.2.5/examples/enough.c
97
#define FIXED_TABLE_SIZE (630 * 3 + 410)
98
static const uint16_t kTableSize[12] = {
99
FIXED_TABLE_SIZE + 654,
100
FIXED_TABLE_SIZE + 656,
101
FIXED_TABLE_SIZE + 658,
102
FIXED_TABLE_SIZE + 662,
103
FIXED_TABLE_SIZE + 670,
104
FIXED_TABLE_SIZE + 686,
105
FIXED_TABLE_SIZE + 718,
106
FIXED_TABLE_SIZE + 782,
107
FIXED_TABLE_SIZE + 912,
108
FIXED_TABLE_SIZE + 1168,
109
FIXED_TABLE_SIZE + 1680,
110
FIXED_TABLE_SIZE + 2704
111
};
112
113
static int VP8LSetError(VP8LDecoder* const dec, VP8StatusCode error) {
114
// The oldest error reported takes precedence over the new one.
115
if (dec->status == VP8_STATUS_OK || dec->status == VP8_STATUS_SUSPENDED) {
116
dec->status = error;
117
}
118
return 0;
119
}
120
121
static int DecodeImageStream(int xsize, int ysize,
122
int is_level0,
123
VP8LDecoder* const dec,
124
uint32_t** const decoded_data);
125
126
//------------------------------------------------------------------------------
127
128
int VP8LCheckSignature(const uint8_t* const data, size_t size) {
129
return (size >= VP8L_FRAME_HEADER_SIZE &&
130
data[0] == VP8L_MAGIC_BYTE &&
131
(data[4] >> 5) == 0); // version
132
}
133
134
static int ReadImageInfo(VP8LBitReader* const br,
135
int* const width, int* const height,
136
int* const has_alpha) {
137
if (VP8LReadBits(br, 8) != VP8L_MAGIC_BYTE) return 0;
138
*width = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
139
*height = VP8LReadBits(br, VP8L_IMAGE_SIZE_BITS) + 1;
140
*has_alpha = VP8LReadBits(br, 1);
141
if (VP8LReadBits(br, VP8L_VERSION_BITS) != 0) return 0;
142
return !br->eos;
143
}
144
145
int VP8LGetInfo(const uint8_t* data, size_t data_size,
146
int* const width, int* const height, int* const has_alpha) {
147
if (data == NULL || data_size < VP8L_FRAME_HEADER_SIZE) {
148
return 0; // not enough data
149
} else if (!VP8LCheckSignature(data, data_size)) {
150
return 0; // bad signature
151
} else {
152
int w, h, a;
153
VP8LBitReader br;
154
VP8LInitBitReader(&br, data, data_size);
155
if (!ReadImageInfo(&br, &w, &h, &a)) {
156
return 0;
157
}
158
if (width != NULL) *width = w;
159
if (height != NULL) *height = h;
160
if (has_alpha != NULL) *has_alpha = a;
161
return 1;
162
}
163
}
164
165
//------------------------------------------------------------------------------
166
167
static WEBP_INLINE int GetCopyDistance(int distance_symbol,
168
VP8LBitReader* const br) {
169
int extra_bits, offset;
170
if (distance_symbol < 4) {
171
return distance_symbol + 1;
172
}
173
extra_bits = (distance_symbol - 2) >> 1;
174
offset = (2 + (distance_symbol & 1)) << extra_bits;
175
return offset + VP8LReadBits(br, extra_bits) + 1;
176
}
177
178
static WEBP_INLINE int GetCopyLength(int length_symbol,
179
VP8LBitReader* const br) {
180
// Length and distance prefixes are encoded the same way.
181
return GetCopyDistance(length_symbol, br);
182
}
183
184
static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
185
if (plane_code > CODE_TO_PLANE_CODES) {
186
return plane_code - CODE_TO_PLANE_CODES;
187
} else {
188
const int dist_code = kCodeToPlane[plane_code - 1];
189
const int yoffset = dist_code >> 4;
190
const int xoffset = 8 - (dist_code & 0xf);
191
const int dist = yoffset * xsize + xoffset;
192
return (dist >= 1) ? dist : 1; // dist<1 can happen if xsize is very small
193
}
194
}
195
196
//------------------------------------------------------------------------------
197
// Decodes the next Huffman code from bit-stream.
198
// VP8LFillBitWindow(br) needs to be called at minimum every second call
199
// to ReadSymbol, in order to pre-fetch enough bits.
200
static WEBP_INLINE int ReadSymbol(const HuffmanCode* table,
201
VP8LBitReader* const br) {
202
int nbits;
203
uint32_t val = VP8LPrefetchBits(br);
204
table += val & HUFFMAN_TABLE_MASK;
205
nbits = table->bits - HUFFMAN_TABLE_BITS;
206
if (nbits > 0) {
207
VP8LSetBitPos(br, br->bit_pos + HUFFMAN_TABLE_BITS);
208
val = VP8LPrefetchBits(br);
209
table += table->value;
210
table += val & ((1 << nbits) - 1);
211
}
212
VP8LSetBitPos(br, br->bit_pos + table->bits);
213
return table->value;
214
}
215
216
// Reads packed symbol depending on GREEN channel
217
#define BITS_SPECIAL_MARKER 0x100 // something large enough (and a bit-mask)
218
#define PACKED_NON_LITERAL_CODE 0 // must be < NUM_LITERAL_CODES
219
static WEBP_INLINE int ReadPackedSymbols(const HTreeGroup* group,
220
VP8LBitReader* const br,
221
uint32_t* const dst) {
222
const uint32_t val = VP8LPrefetchBits(br) & (HUFFMAN_PACKED_TABLE_SIZE - 1);
223
const HuffmanCode32 code = group->packed_table[val];
224
assert(group->use_packed_table);
225
if (code.bits < BITS_SPECIAL_MARKER) {
226
VP8LSetBitPos(br, br->bit_pos + code.bits);
227
*dst = code.value;
228
return PACKED_NON_LITERAL_CODE;
229
} else {
230
VP8LSetBitPos(br, br->bit_pos + code.bits - BITS_SPECIAL_MARKER);
231
assert(code.value >= NUM_LITERAL_CODES);
232
return code.value;
233
}
234
}
235
236
static int AccumulateHCode(HuffmanCode hcode, int shift,
237
HuffmanCode32* const huff) {
238
huff->bits += hcode.bits;
239
huff->value |= (uint32_t)hcode.value << shift;
240
assert(huff->bits <= HUFFMAN_TABLE_BITS);
241
return hcode.bits;
242
}
243
244
static void BuildPackedTable(HTreeGroup* const htree_group) {
245
uint32_t code;
246
for (code = 0; code < HUFFMAN_PACKED_TABLE_SIZE; ++code) {
247
uint32_t bits = code;
248
HuffmanCode32* const huff = &htree_group->packed_table[bits];
249
HuffmanCode hcode = htree_group->htrees[GREEN][bits];
250
if (hcode.value >= NUM_LITERAL_CODES) {
251
huff->bits = hcode.bits + BITS_SPECIAL_MARKER;
252
huff->value = hcode.value;
253
} else {
254
huff->bits = 0;
255
huff->value = 0;
256
bits >>= AccumulateHCode(hcode, 8, huff);
257
bits >>= AccumulateHCode(htree_group->htrees[RED][bits], 16, huff);
258
bits >>= AccumulateHCode(htree_group->htrees[BLUE][bits], 0, huff);
259
bits >>= AccumulateHCode(htree_group->htrees[ALPHA][bits], 24, huff);
260
(void)bits;
261
}
262
}
263
}
264
265
static int ReadHuffmanCodeLengths(
266
VP8LDecoder* const dec, const int* const code_length_code_lengths,
267
int num_symbols, int* const code_lengths) {
268
int ok = 0;
269
VP8LBitReader* const br = &dec->br;
270
int symbol;
271
int max_symbol;
272
int prev_code_len = DEFAULT_CODE_LENGTH;
273
HuffmanTables tables;
274
275
if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
276
!VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
277
code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
278
goto End;
279
}
280
281
if (VP8LReadBits(br, 1)) { // use length
282
const int length_nbits = 2 + 2 * VP8LReadBits(br, 3);
283
max_symbol = 2 + VP8LReadBits(br, length_nbits);
284
if (max_symbol > num_symbols) {
285
goto End;
286
}
287
} else {
288
max_symbol = num_symbols;
289
}
290
291
symbol = 0;
292
while (symbol < num_symbols) {
293
const HuffmanCode* p;
294
int code_len;
295
if (max_symbol-- == 0) break;
296
VP8LFillBitWindow(br);
297
p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
298
VP8LSetBitPos(br, br->bit_pos + p->bits);
299
code_len = p->value;
300
if (code_len < kCodeLengthLiterals) {
301
code_lengths[symbol++] = code_len;
302
if (code_len != 0) prev_code_len = code_len;
303
} else {
304
const int use_prev = (code_len == kCodeLengthRepeatCode);
305
const int slot = code_len - kCodeLengthLiterals;
306
const int extra_bits = kCodeLengthExtraBits[slot];
307
const int repeat_offset = kCodeLengthRepeatOffsets[slot];
308
int repeat = VP8LReadBits(br, extra_bits) + repeat_offset;
309
if (symbol + repeat > num_symbols) {
310
goto End;
311
} else {
312
const int length = use_prev ? prev_code_len : 0;
313
while (repeat-- > 0) code_lengths[symbol++] = length;
314
}
315
}
316
}
317
ok = 1;
318
319
End:
320
VP8LHuffmanTablesDeallocate(&tables);
321
if (!ok) return VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
322
return ok;
323
}
324
325
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
326
// tree.
327
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
328
int* const code_lengths,
329
HuffmanTables* const table) {
330
int ok = 0;
331
int size = 0;
332
VP8LBitReader* const br = &dec->br;
333
const int simple_code = VP8LReadBits(br, 1);
334
335
memset(code_lengths, 0, alphabet_size * sizeof(*code_lengths));
336
337
if (simple_code) { // Read symbols, codes & code lengths directly.
338
const int num_symbols = VP8LReadBits(br, 1) + 1;
339
const int first_symbol_len_code = VP8LReadBits(br, 1);
340
// The first code is either 1 bit or 8 bit code.
341
int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
342
code_lengths[symbol] = 1;
343
// The second code (if present), is always 8 bits long.
344
if (num_symbols == 2) {
345
symbol = VP8LReadBits(br, 8);
346
code_lengths[symbol] = 1;
347
}
348
ok = 1;
349
} else { // Decode Huffman-coded code lengths.
350
int i;
351
int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
352
const int num_codes = VP8LReadBits(br, 4) + 4;
353
assert(num_codes <= NUM_CODE_LENGTH_CODES);
354
355
for (i = 0; i < num_codes; ++i) {
356
code_length_code_lengths[kCodeLengthCodeOrder[i]] = VP8LReadBits(br, 3);
357
}
358
ok = ReadHuffmanCodeLengths(dec, code_length_code_lengths, alphabet_size,
359
code_lengths);
360
}
361
362
ok = ok && !br->eos;
363
if (ok) {
364
size = VP8LBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
365
code_lengths, alphabet_size);
366
}
367
if (!ok || size == 0) {
368
return VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
369
}
370
return size;
371
}
372
373
static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
374
int color_cache_bits, int allow_recursion) {
375
int i;
376
VP8LBitReader* const br = &dec->br;
377
VP8LMetadata* const hdr = &dec->hdr;
378
uint32_t* huffman_image = NULL;
379
HTreeGroup* htree_groups = NULL;
380
HuffmanTables* huffman_tables = &hdr->huffman_tables;
381
int num_htree_groups = 1;
382
int num_htree_groups_max = 1;
383
int* mapping = NULL;
384
int ok = 0;
385
386
// Check the table has been 0 initialized (through InitMetadata).
387
assert(huffman_tables->root.start == NULL);
388
assert(huffman_tables->curr_segment == NULL);
389
390
if (allow_recursion && VP8LReadBits(br, 1)) {
391
// use meta Huffman codes.
392
const int huffman_precision =
393
MIN_HUFFMAN_BITS + VP8LReadBits(br, NUM_HUFFMAN_BITS);
394
const int huffman_xsize = VP8LSubSampleSize(xsize, huffman_precision);
395
const int huffman_ysize = VP8LSubSampleSize(ysize, huffman_precision);
396
const int huffman_pixs = huffman_xsize * huffman_ysize;
397
if (!DecodeImageStream(huffman_xsize, huffman_ysize, /*is_level0=*/0, dec,
398
&huffman_image)) {
399
goto Error;
400
}
401
hdr->huffman_subsample_bits = huffman_precision;
402
for (i = 0; i < huffman_pixs; ++i) {
403
// The huffman data is stored in red and green bytes.
404
const int group = (huffman_image[i] >> 8) & 0xffff;
405
huffman_image[i] = group;
406
if (group >= num_htree_groups_max) {
407
num_htree_groups_max = group + 1;
408
}
409
}
410
// Check the validity of num_htree_groups_max. If it seems too big, use a
411
// smaller value for later. This will prevent big memory allocations to end
412
// up with a bad bitstream anyway.
413
// The value of 1000 is totally arbitrary. We know that num_htree_groups_max
414
// is smaller than (1 << 16) and should be smaller than the number of pixels
415
// (though the format allows it to be bigger).
416
if (num_htree_groups_max > 1000 || num_htree_groups_max > xsize * ysize) {
417
// Create a mapping from the used indices to the minimal set of used
418
// values [0, num_htree_groups)
419
mapping = (int*)WebPSafeMalloc(num_htree_groups_max, sizeof(*mapping));
420
if (mapping == NULL) {
421
VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
422
goto Error;
423
}
424
// -1 means a value is unmapped, and therefore unused in the Huffman
425
// image.
426
memset(mapping, 0xff, num_htree_groups_max * sizeof(*mapping));
427
for (num_htree_groups = 0, i = 0; i < huffman_pixs; ++i) {
428
// Get the current mapping for the group and remap the Huffman image.
429
int* const mapped_group = &mapping[huffman_image[i]];
430
if (*mapped_group == -1) *mapped_group = num_htree_groups++;
431
huffman_image[i] = *mapped_group;
432
}
433
} else {
434
num_htree_groups = num_htree_groups_max;
435
}
436
}
437
438
if (br->eos) goto Error;
439
440
if (!ReadHuffmanCodesHelper(color_cache_bits, num_htree_groups,
441
num_htree_groups_max, mapping, dec,
442
huffman_tables, &htree_groups)) {
443
goto Error;
444
}
445
ok = 1;
446
447
// All OK. Finalize pointers.
448
hdr->huffman_image = huffman_image;
449
hdr->num_htree_groups = num_htree_groups;
450
hdr->htree_groups = htree_groups;
451
452
Error:
453
WebPSafeFree(mapping);
454
if (!ok) {
455
WebPSafeFree(huffman_image);
456
VP8LHuffmanTablesDeallocate(huffman_tables);
457
VP8LHtreeGroupsFree(htree_groups);
458
}
459
return ok;
460
}
461
462
int ReadHuffmanCodesHelper(int color_cache_bits, int num_htree_groups,
463
int num_htree_groups_max, const int* const mapping,
464
VP8LDecoder* const dec,
465
HuffmanTables* const huffman_tables,
466
HTreeGroup** const htree_groups) {
467
int i, j, ok = 0;
468
const int max_alphabet_size =
469
kAlphabetSize[0] + ((color_cache_bits > 0) ? 1 << color_cache_bits : 0);
470
const int table_size = kTableSize[color_cache_bits];
471
int* code_lengths = NULL;
472
473
if ((mapping == NULL && num_htree_groups != num_htree_groups_max) ||
474
num_htree_groups > num_htree_groups_max) {
475
goto Error;
476
}
477
478
code_lengths =
479
(int*)WebPSafeCalloc((uint64_t)max_alphabet_size, sizeof(*code_lengths));
480
*htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
481
482
if (*htree_groups == NULL || code_lengths == NULL ||
483
!VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
484
huffman_tables)) {
485
VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
486
goto Error;
487
}
488
489
for (i = 0; i < num_htree_groups_max; ++i) {
490
// If the index "i" is unused in the Huffman image, just make sure the
491
// coefficients are valid but do not store them.
492
if (mapping != NULL && mapping[i] == -1) {
493
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
494
int alphabet_size = kAlphabetSize[j];
495
if (j == 0 && color_cache_bits > 0) {
496
alphabet_size += (1 << color_cache_bits);
497
}
498
// Passing in NULL so that nothing gets filled.
499
if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) {
500
goto Error;
501
}
502
}
503
} else {
504
HTreeGroup* const htree_group =
505
&(*htree_groups)[(mapping == NULL) ? i : mapping[i]];
506
HuffmanCode** const htrees = htree_group->htrees;
507
int size;
508
int total_size = 0;
509
int is_trivial_literal = 1;
510
int max_bits = 0;
511
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
512
int alphabet_size = kAlphabetSize[j];
513
if (j == 0 && color_cache_bits > 0) {
514
alphabet_size += (1 << color_cache_bits);
515
}
516
size =
517
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
518
htrees[j] = huffman_tables->curr_segment->curr_table;
519
if (size == 0) {
520
goto Error;
521
}
522
if (is_trivial_literal && kLiteralMap[j] == 1) {
523
is_trivial_literal = (htrees[j]->bits == 0);
524
}
525
total_size += htrees[j]->bits;
526
huffman_tables->curr_segment->curr_table += size;
527
if (j <= ALPHA) {
528
int local_max_bits = code_lengths[0];
529
int k;
530
for (k = 1; k < alphabet_size; ++k) {
531
if (code_lengths[k] > local_max_bits) {
532
local_max_bits = code_lengths[k];
533
}
534
}
535
max_bits += local_max_bits;
536
}
537
}
538
htree_group->is_trivial_literal = is_trivial_literal;
539
htree_group->is_trivial_code = 0;
540
if (is_trivial_literal) {
541
const int red = htrees[RED][0].value;
542
const int blue = htrees[BLUE][0].value;
543
const int alpha = htrees[ALPHA][0].value;
544
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
545
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
546
htree_group->is_trivial_code = 1;
547
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
548
}
549
}
550
htree_group->use_packed_table =
551
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
552
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
553
}
554
}
555
ok = 1;
556
557
Error:
558
WebPSafeFree(code_lengths);
559
if (!ok) {
560
VP8LHuffmanTablesDeallocate(huffman_tables);
561
VP8LHtreeGroupsFree(*htree_groups);
562
*htree_groups = NULL;
563
}
564
return ok;
565
}
566
567
//------------------------------------------------------------------------------
568
// Scaling.
569
570
#if !defined(WEBP_REDUCE_SIZE)
571
static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
572
const int num_channels = 4;
573
const int in_width = io->mb_w;
574
const int out_width = io->scaled_width;
575
const int in_height = io->mb_h;
576
const int out_height = io->scaled_height;
577
const uint64_t work_size = 2 * num_channels * (uint64_t)out_width;
578
rescaler_t* work; // Rescaler work area.
579
const uint64_t scaled_data_size = (uint64_t)out_width;
580
uint32_t* scaled_data; // Temporary storage for scaled BGRA data.
581
const uint64_t memory_size = sizeof(*dec->rescaler) +
582
work_size * sizeof(*work) +
583
scaled_data_size * sizeof(*scaled_data);
584
uint8_t* memory = (uint8_t*)WebPSafeMalloc(memory_size, sizeof(*memory));
585
if (memory == NULL) {
586
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
587
}
588
assert(dec->rescaler_memory == NULL);
589
dec->rescaler_memory = memory;
590
591
dec->rescaler = (WebPRescaler*)memory;
592
memory += sizeof(*dec->rescaler);
593
work = (rescaler_t*)memory;
594
memory += work_size * sizeof(*work);
595
scaled_data = (uint32_t*)memory;
596
597
if (!WebPRescalerInit(dec->rescaler, in_width, in_height,
598
(uint8_t*)scaled_data, out_width, out_height,
599
0, num_channels, work)) {
600
return 0;
601
}
602
return 1;
603
}
604
#endif // WEBP_REDUCE_SIZE
605
606
//------------------------------------------------------------------------------
607
// Export to ARGB
608
609
#if !defined(WEBP_REDUCE_SIZE)
610
611
// We have special "export" function since we need to convert from BGRA
612
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
613
int rgba_stride, uint8_t* const rgba) {
614
uint32_t* const src = (uint32_t*)rescaler->dst;
615
uint8_t* dst = rgba;
616
const int dst_width = rescaler->dst_width;
617
int num_lines_out = 0;
618
while (WebPRescalerHasPendingOutput(rescaler)) {
619
WebPRescalerExportRow(rescaler);
620
WebPMultARGBRow(src, dst_width, 1);
621
VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
622
dst += rgba_stride;
623
++num_lines_out;
624
}
625
return num_lines_out;
626
}
627
628
// Emit scaled rows.
629
static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
630
uint8_t* in, int in_stride, int mb_h,
631
uint8_t* const out, int out_stride) {
632
const WEBP_CSP_MODE colorspace = dec->output->colorspace;
633
int num_lines_in = 0;
634
int num_lines_out = 0;
635
while (num_lines_in < mb_h) {
636
uint8_t* const row_in = in + (ptrdiff_t)num_lines_in * in_stride;
637
uint8_t* const row_out = out + (ptrdiff_t)num_lines_out * out_stride;
638
const int lines_left = mb_h - num_lines_in;
639
const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
640
int lines_imported;
641
assert(needed_lines > 0 && needed_lines <= lines_left);
642
WebPMultARGBRows(row_in, in_stride,
643
dec->rescaler->src_width, needed_lines, 0);
644
lines_imported =
645
WebPRescalerImport(dec->rescaler, lines_left, row_in, in_stride);
646
assert(lines_imported == needed_lines);
647
num_lines_in += lines_imported;
648
num_lines_out += Export(dec->rescaler, colorspace, out_stride, row_out);
649
}
650
return num_lines_out;
651
}
652
653
#endif // WEBP_REDUCE_SIZE
654
655
// Emit rows without any scaling.
656
static int EmitRows(WEBP_CSP_MODE colorspace,
657
const uint8_t* row_in, int in_stride,
658
int mb_w, int mb_h,
659
uint8_t* const out, int out_stride) {
660
int lines = mb_h;
661
uint8_t* row_out = out;
662
while (lines-- > 0) {
663
VP8LConvertFromBGRA((const uint32_t*)row_in, mb_w, colorspace, row_out);
664
row_in += in_stride;
665
row_out += out_stride;
666
}
667
return mb_h; // Num rows out == num rows in.
668
}
669
670
//------------------------------------------------------------------------------
671
// Export to YUVA
672
673
static void ConvertToYUVA(const uint32_t* const src, int width, int y_pos,
674
const WebPDecBuffer* const output) {
675
const WebPYUVABuffer* const buf = &output->u.YUVA;
676
677
// first, the luma plane
678
WebPConvertARGBToY(src, buf->y + y_pos * buf->y_stride, width);
679
680
// then U/V planes
681
{
682
uint8_t* const u = buf->u + (y_pos >> 1) * buf->u_stride;
683
uint8_t* const v = buf->v + (y_pos >> 1) * buf->v_stride;
684
// even lines: store values
685
// odd lines: average with previous values
686
WebPConvertARGBToUV(src, u, v, width, !(y_pos & 1));
687
}
688
// Lastly, store alpha if needed.
689
if (buf->a != NULL) {
690
uint8_t* const a = buf->a + y_pos * buf->a_stride;
691
#if defined(WORDS_BIGENDIAN)
692
WebPExtractAlpha((uint8_t*)src + 0, 0, width, 1, a, 0);
693
#else
694
WebPExtractAlpha((uint8_t*)src + 3, 0, width, 1, a, 0);
695
#endif
696
}
697
}
698
699
static int ExportYUVA(const VP8LDecoder* const dec, int y_pos) {
700
WebPRescaler* const rescaler = dec->rescaler;
701
uint32_t* const src = (uint32_t*)rescaler->dst;
702
const int dst_width = rescaler->dst_width;
703
int num_lines_out = 0;
704
while (WebPRescalerHasPendingOutput(rescaler)) {
705
WebPRescalerExportRow(rescaler);
706
WebPMultARGBRow(src, dst_width, 1);
707
ConvertToYUVA(src, dst_width, y_pos, dec->output);
708
++y_pos;
709
++num_lines_out;
710
}
711
return num_lines_out;
712
}
713
714
static int EmitRescaledRowsYUVA(const VP8LDecoder* const dec,
715
uint8_t* in, int in_stride, int mb_h) {
716
int num_lines_in = 0;
717
int y_pos = dec->last_out_row;
718
while (num_lines_in < mb_h) {
719
const int lines_left = mb_h - num_lines_in;
720
const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
721
int lines_imported;
722
WebPMultARGBRows(in, in_stride, dec->rescaler->src_width, needed_lines, 0);
723
lines_imported =
724
WebPRescalerImport(dec->rescaler, lines_left, in, in_stride);
725
assert(lines_imported == needed_lines);
726
num_lines_in += lines_imported;
727
in += needed_lines * in_stride;
728
y_pos += ExportYUVA(dec, y_pos);
729
}
730
return y_pos;
731
}
732
733
static int EmitRowsYUVA(const VP8LDecoder* const dec,
734
const uint8_t* in, int in_stride,
735
int mb_w, int num_rows) {
736
int y_pos = dec->last_out_row;
737
while (num_rows-- > 0) {
738
ConvertToYUVA((const uint32_t*)in, mb_w, y_pos, dec->output);
739
in += in_stride;
740
++y_pos;
741
}
742
return y_pos;
743
}
744
745
//------------------------------------------------------------------------------
746
// Cropping.
747
748
// Sets io->mb_y, io->mb_h & io->mb_w according to start row, end row and
749
// crop options. Also updates the input data pointer, so that it points to the
750
// start of the cropped window. Note that pixels are in ARGB format even if
751
// 'in_data' is uint8_t*.
752
// Returns true if the crop window is not empty.
753
static int SetCropWindow(VP8Io* const io, int y_start, int y_end,
754
uint8_t** const in_data, int pixel_stride) {
755
assert(y_start < y_end);
756
assert(io->crop_left < io->crop_right);
757
if (y_end > io->crop_bottom) {
758
y_end = io->crop_bottom; // make sure we don't overflow on last row.
759
}
760
if (y_start < io->crop_top) {
761
const int delta = io->crop_top - y_start;
762
y_start = io->crop_top;
763
*in_data += delta * pixel_stride;
764
}
765
if (y_start >= y_end) return 0; // Crop window is empty.
766
767
*in_data += io->crop_left * sizeof(uint32_t);
768
769
io->mb_y = y_start - io->crop_top;
770
io->mb_w = io->crop_right - io->crop_left;
771
io->mb_h = y_end - y_start;
772
return 1; // Non-empty crop window.
773
}
774
775
//------------------------------------------------------------------------------
776
777
static WEBP_INLINE int GetMetaIndex(
778
const uint32_t* const image, int xsize, int bits, int x, int y) {
779
if (bits == 0) return 0;
780
return image[xsize * (y >> bits) + (x >> bits)];
781
}
782
783
static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr,
784
int x, int y) {
785
const int meta_index = GetMetaIndex(hdr->huffman_image, hdr->huffman_xsize,
786
hdr->huffman_subsample_bits, x, y);
787
assert(meta_index < hdr->num_htree_groups);
788
return hdr->htree_groups + meta_index;
789
}
790
791
//------------------------------------------------------------------------------
792
// Main loop, with custom row-processing function
793
794
typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row);
795
796
static void ApplyInverseTransforms(VP8LDecoder* const dec,
797
int start_row, int num_rows,
798
const uint32_t* const rows) {
799
int n = dec->next_transform;
800
const int cache_pixs = dec->width * num_rows;
801
const int end_row = start_row + num_rows;
802
const uint32_t* rows_in = rows;
803
uint32_t* const rows_out = dec->argb_cache;
804
805
// Inverse transforms.
806
while (n-- > 0) {
807
VP8LTransform* const transform = &dec->transforms[n];
808
VP8LInverseTransform(transform, start_row, end_row, rows_in, rows_out);
809
rows_in = rows_out;
810
}
811
if (rows_in != rows_out) {
812
// No transform called, hence just copy.
813
memcpy(rows_out, rows_in, cache_pixs * sizeof(*rows_out));
814
}
815
}
816
817
// Processes (transforms, scales & color-converts) the rows decoded after the
818
// last call.
819
static void ProcessRows(VP8LDecoder* const dec, int row) {
820
const uint32_t* const rows = dec->pixels + dec->width * dec->last_row;
821
const int num_rows = row - dec->last_row;
822
823
assert(row <= dec->io->crop_bottom);
824
// We can't process more than NUM_ARGB_CACHE_ROWS at a time (that's the size
825
// of argb_cache), but we currently don't need more than that.
826
assert(num_rows <= NUM_ARGB_CACHE_ROWS);
827
if (num_rows > 0) { // Emit output.
828
VP8Io* const io = dec->io;
829
uint8_t* rows_data = (uint8_t*)dec->argb_cache;
830
const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA
831
ApplyInverseTransforms(dec, dec->last_row, num_rows, rows);
832
if (!SetCropWindow(io, dec->last_row, row, &rows_data, in_stride)) {
833
// Nothing to output (this time).
834
} else {
835
const WebPDecBuffer* const output = dec->output;
836
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
837
const WebPRGBABuffer* const buf = &output->u.RGBA;
838
uint8_t* const rgba =
839
buf->rgba + (ptrdiff_t)dec->last_out_row * buf->stride;
840
const int num_rows_out =
841
#if !defined(WEBP_REDUCE_SIZE)
842
io->use_scaling ?
843
EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
844
rgba, buf->stride) :
845
#endif // WEBP_REDUCE_SIZE
846
EmitRows(output->colorspace, rows_data, in_stride,
847
io->mb_w, io->mb_h, rgba, buf->stride);
848
// Update 'last_out_row'.
849
dec->last_out_row += num_rows_out;
850
} else { // convert to YUVA
851
dec->last_out_row = io->use_scaling ?
852
EmitRescaledRowsYUVA(dec, rows_data, in_stride, io->mb_h) :
853
EmitRowsYUVA(dec, rows_data, in_stride, io->mb_w, io->mb_h);
854
}
855
assert(dec->last_out_row <= output->height);
856
}
857
}
858
859
// Update 'last_row'.
860
dec->last_row = row;
861
assert(dec->last_row <= dec->height);
862
}
863
864
// Row-processing for the special case when alpha data contains only one
865
// transform (color indexing), and trivial non-green literals.
866
static int Is8bOptimizable(const VP8LMetadata* const hdr) {
867
int i;
868
if (hdr->color_cache_size > 0) return 0;
869
// When the Huffman tree contains only one symbol, we can skip the
870
// call to ReadSymbol() for red/blue/alpha channels.
871
for (i = 0; i < hdr->num_htree_groups; ++i) {
872
HuffmanCode** const htrees = hdr->htree_groups[i].htrees;
873
if (htrees[RED][0].bits > 0) return 0;
874
if (htrees[BLUE][0].bits > 0) return 0;
875
if (htrees[ALPHA][0].bits > 0) return 0;
876
}
877
return 1;
878
}
879
880
static void AlphaApplyFilter(ALPHDecoder* const alph_dec,
881
int first_row, int last_row,
882
uint8_t* out, int stride) {
883
if (alph_dec->filter != WEBP_FILTER_NONE) {
884
int y;
885
const uint8_t* prev_line = alph_dec->prev_line;
886
assert(WebPUnfilters[alph_dec->filter] != NULL);
887
for (y = first_row; y < last_row; ++y) {
888
WebPUnfilters[alph_dec->filter](prev_line, out, out, stride);
889
prev_line = out;
890
out += stride;
891
}
892
alph_dec->prev_line = prev_line;
893
}
894
}
895
896
static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int last_row) {
897
// For vertical and gradient filtering, we need to decode the part above the
898
// crop_top row, in order to have the correct spatial predictors.
899
ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io->opaque;
900
const int top_row =
901
(alph_dec->filter == WEBP_FILTER_NONE ||
902
alph_dec->filter == WEBP_FILTER_HORIZONTAL) ? dec->io->crop_top
903
: dec->last_row;
904
const int first_row = (dec->last_row < top_row) ? top_row : dec->last_row;
905
assert(last_row <= dec->io->crop_bottom);
906
if (last_row > first_row) {
907
// Special method for paletted alpha data. We only process the cropped area.
908
const int width = dec->io->width;
909
uint8_t* out = alph_dec->output + width * first_row;
910
const uint8_t* const in =
911
(uint8_t*)dec->pixels + dec->width * first_row;
912
VP8LTransform* const transform = &dec->transforms[0];
913
assert(dec->next_transform == 1);
914
assert(transform->type == COLOR_INDEXING_TRANSFORM);
915
VP8LColorIndexInverseTransformAlpha(transform, first_row, last_row,
916
in, out);
917
AlphaApplyFilter(alph_dec, first_row, last_row, out, width);
918
}
919
dec->last_row = dec->last_out_row = last_row;
920
}
921
922
//------------------------------------------------------------------------------
923
// Helper functions for fast pattern copy (8b and 32b)
924
925
// cyclic rotation of pattern word
926
static WEBP_INLINE uint32_t Rotate8b(uint32_t V) {
927
#if defined(WORDS_BIGENDIAN)
928
return ((V & 0xff000000u) >> 24) | (V << 8);
929
#else
930
return ((V & 0xffu) << 24) | (V >> 8);
931
#endif
932
}
933
934
// copy 1, 2 or 4-bytes pattern
935
static WEBP_INLINE void CopySmallPattern8b(const uint8_t* src, uint8_t* dst,
936
int length, uint32_t pattern) {
937
int i;
938
// align 'dst' to 4-bytes boundary. Adjust the pattern along the way.
939
while ((uintptr_t)dst & 3) {
940
*dst++ = *src++;
941
pattern = Rotate8b(pattern);
942
--length;
943
}
944
// Copy the pattern 4 bytes at a time.
945
for (i = 0; i < (length >> 2); ++i) {
946
((uint32_t*)dst)[i] = pattern;
947
}
948
// Finish with left-overs. 'pattern' is still correctly positioned,
949
// so no Rotate8b() call is needed.
950
for (i <<= 2; i < length; ++i) {
951
dst[i] = src[i];
952
}
953
}
954
955
static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
956
const uint8_t* src = dst - dist;
957
if (length >= 8) {
958
uint32_t pattern = 0;
959
switch (dist) {
960
case 1:
961
pattern = src[0];
962
#if defined(__arm__) || defined(_M_ARM) // arm doesn't like multiply that much
963
pattern |= pattern << 8;
964
pattern |= pattern << 16;
965
#elif defined(WEBP_USE_MIPS_DSP_R2)
966
__asm__ volatile ("replv.qb %0, %0" : "+r"(pattern));
967
#else
968
pattern = 0x01010101u * pattern;
969
#endif
970
break;
971
case 2:
972
#if !defined(WORDS_BIGENDIAN)
973
memcpy(&pattern, src, sizeof(uint16_t));
974
#else
975
pattern = ((uint32_t)src[0] << 8) | src[1];
976
#endif
977
#if defined(__arm__) || defined(_M_ARM)
978
pattern |= pattern << 16;
979
#elif defined(WEBP_USE_MIPS_DSP_R2)
980
__asm__ volatile ("replv.ph %0, %0" : "+r"(pattern));
981
#else
982
pattern = 0x00010001u * pattern;
983
#endif
984
break;
985
case 4:
986
memcpy(&pattern, src, sizeof(uint32_t));
987
break;
988
default:
989
goto Copy;
990
}
991
CopySmallPattern8b(src, dst, length, pattern);
992
return;
993
}
994
Copy:
995
if (dist >= length) { // no overlap -> use memcpy()
996
memcpy(dst, src, length * sizeof(*dst));
997
} else {
998
int i;
999
for (i = 0; i < length; ++i) dst[i] = src[i];
1000
}
1001
}
1002
1003
// copy pattern of 1 or 2 uint32_t's
1004
static WEBP_INLINE void CopySmallPattern32b(const uint32_t* src,
1005
uint32_t* dst,
1006
int length, uint64_t pattern) {
1007
int i;
1008
if ((uintptr_t)dst & 4) { // Align 'dst' to 8-bytes boundary.
1009
*dst++ = *src++;
1010
pattern = (pattern >> 32) | (pattern << 32);
1011
--length;
1012
}
1013
assert(0 == ((uintptr_t)dst & 7));
1014
for (i = 0; i < (length >> 1); ++i) {
1015
((uint64_t*)dst)[i] = pattern; // Copy the pattern 8 bytes at a time.
1016
}
1017
if (length & 1) { // Finish with left-over.
1018
dst[i << 1] = src[i << 1];
1019
}
1020
}
1021
1022
static WEBP_INLINE void CopyBlock32b(uint32_t* const dst,
1023
int dist, int length) {
1024
const uint32_t* const src = dst - dist;
1025
if (dist <= 2 && length >= 4 && ((uintptr_t)dst & 3) == 0) {
1026
uint64_t pattern;
1027
if (dist == 1) {
1028
pattern = (uint64_t)src[0];
1029
pattern |= pattern << 32;
1030
} else {
1031
memcpy(&pattern, src, sizeof(pattern));
1032
}
1033
CopySmallPattern32b(src, dst, length, pattern);
1034
} else if (dist >= length) { // no overlap
1035
memcpy(dst, src, length * sizeof(*dst));
1036
} else {
1037
int i;
1038
for (i = 0; i < length; ++i) dst[i] = src[i];
1039
}
1040
}
1041
1042
//------------------------------------------------------------------------------
1043
1044
static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
1045
int width, int height, int last_row) {
1046
int ok = 1;
1047
int row = dec->last_pixel / width;
1048
int col = dec->last_pixel % width;
1049
VP8LBitReader* const br = &dec->br;
1050
VP8LMetadata* const hdr = &dec->hdr;
1051
int pos = dec->last_pixel; // current position
1052
const int end = width * height; // End of data
1053
const int last = width * last_row; // Last pixel to decode
1054
const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
1055
const int mask = hdr->huffman_mask;
1056
const HTreeGroup* htree_group =
1057
(pos < last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
1058
assert(pos <= end);
1059
assert(last_row <= height);
1060
assert(Is8bOptimizable(hdr));
1061
1062
while (!br->eos && pos < last) {
1063
int code;
1064
// Only update when changing tile.
1065
if ((col & mask) == 0) {
1066
htree_group = GetHtreeGroupForPos(hdr, col, row);
1067
}
1068
assert(htree_group != NULL);
1069
VP8LFillBitWindow(br);
1070
code = ReadSymbol(htree_group->htrees[GREEN], br);
1071
if (code < NUM_LITERAL_CODES) { // Literal
1072
data[pos] = code;
1073
++pos;
1074
++col;
1075
if (col >= width) {
1076
col = 0;
1077
++row;
1078
if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
1079
ExtractPalettedAlphaRows(dec, row);
1080
}
1081
}
1082
} else if (code < len_code_limit) { // Backward reference
1083
int dist_code, dist;
1084
const int length_sym = code - NUM_LITERAL_CODES;
1085
const int length = GetCopyLength(length_sym, br);
1086
const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
1087
VP8LFillBitWindow(br);
1088
dist_code = GetCopyDistance(dist_symbol, br);
1089
dist = PlaneCodeToDistance(width, dist_code);
1090
if (pos >= dist && end - pos >= length) {
1091
CopyBlock8b(data + pos, dist, length);
1092
} else {
1093
ok = 0;
1094
goto End;
1095
}
1096
pos += length;
1097
col += length;
1098
while (col >= width) {
1099
col -= width;
1100
++row;
1101
if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
1102
ExtractPalettedAlphaRows(dec, row);
1103
}
1104
}
1105
if (pos < last && (col & mask)) {
1106
htree_group = GetHtreeGroupForPos(hdr, col, row);
1107
}
1108
} else { // Not reached
1109
ok = 0;
1110
goto End;
1111
}
1112
br->eos = VP8LIsEndOfStream(br);
1113
}
1114
// Process the remaining rows corresponding to last row-block.
1115
ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
1116
1117
End:
1118
br->eos = VP8LIsEndOfStream(br);
1119
if (!ok || (br->eos && pos < end)) {
1120
return VP8LSetError(
1121
dec, br->eos ? VP8_STATUS_SUSPENDED : VP8_STATUS_BITSTREAM_ERROR);
1122
}
1123
dec->last_pixel = pos;
1124
return ok;
1125
}
1126
1127
static void SaveState(VP8LDecoder* const dec, int last_pixel) {
1128
assert(dec->incremental);
1129
dec->saved_br = dec->br;
1130
dec->saved_last_pixel = last_pixel;
1131
if (dec->hdr.color_cache_size > 0) {
1132
VP8LColorCacheCopy(&dec->hdr.color_cache, &dec->hdr.saved_color_cache);
1133
}
1134
}
1135
1136
static void RestoreState(VP8LDecoder* const dec) {
1137
assert(dec->br.eos);
1138
dec->status = VP8_STATUS_SUSPENDED;
1139
dec->br = dec->saved_br;
1140
dec->last_pixel = dec->saved_last_pixel;
1141
if (dec->hdr.color_cache_size > 0) {
1142
VP8LColorCacheCopy(&dec->hdr.saved_color_cache, &dec->hdr.color_cache);
1143
}
1144
}
1145
1146
#define SYNC_EVERY_N_ROWS 8 // minimum number of rows between check-points
1147
static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
1148
int width, int height, int last_row,
1149
ProcessRowsFunc process_func) {
1150
int row = dec->last_pixel / width;
1151
int col = dec->last_pixel % width;
1152
VP8LBitReader* const br = &dec->br;
1153
VP8LMetadata* const hdr = &dec->hdr;
1154
uint32_t* src = data + dec->last_pixel;
1155
uint32_t* last_cached = src;
1156
uint32_t* const src_end = data + width * height; // End of data
1157
uint32_t* const src_last = data + width * last_row; // Last pixel to decode
1158
const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
1159
const int color_cache_limit = len_code_limit + hdr->color_cache_size;
1160
int next_sync_row = dec->incremental ? row : 1 << 24;
1161
VP8LColorCache* const color_cache =
1162
(hdr->color_cache_size > 0) ? &hdr->color_cache : NULL;
1163
const int mask = hdr->huffman_mask;
1164
const HTreeGroup* htree_group =
1165
(src < src_last) ? GetHtreeGroupForPos(hdr, col, row) : NULL;
1166
assert(dec->last_row < last_row);
1167
assert(src_last <= src_end);
1168
1169
while (src < src_last) {
1170
int code;
1171
if (row >= next_sync_row) {
1172
SaveState(dec, (int)(src - data));
1173
next_sync_row = row + SYNC_EVERY_N_ROWS;
1174
}
1175
// Only update when changing tile. Note we could use this test:
1176
// if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed
1177
// but that's actually slower and needs storing the previous col/row.
1178
if ((col & mask) == 0) {
1179
htree_group = GetHtreeGroupForPos(hdr, col, row);
1180
}
1181
assert(htree_group != NULL);
1182
if (htree_group->is_trivial_code) {
1183
*src = htree_group->literal_arb;
1184
goto AdvanceByOne;
1185
}
1186
VP8LFillBitWindow(br);
1187
if (htree_group->use_packed_table) {
1188
code = ReadPackedSymbols(htree_group, br, src);
1189
if (VP8LIsEndOfStream(br)) break;
1190
if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne;
1191
} else {
1192
code = ReadSymbol(htree_group->htrees[GREEN], br);
1193
}
1194
if (VP8LIsEndOfStream(br)) break;
1195
if (code < NUM_LITERAL_CODES) { // Literal
1196
if (htree_group->is_trivial_literal) {
1197
*src = htree_group->literal_arb | (code << 8);
1198
} else {
1199
int red, blue, alpha;
1200
red = ReadSymbol(htree_group->htrees[RED], br);
1201
VP8LFillBitWindow(br);
1202
blue = ReadSymbol(htree_group->htrees[BLUE], br);
1203
alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
1204
if (VP8LIsEndOfStream(br)) break;
1205
*src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
1206
}
1207
AdvanceByOne:
1208
++src;
1209
++col;
1210
if (col >= width) {
1211
col = 0;
1212
++row;
1213
if (process_func != NULL) {
1214
if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
1215
process_func(dec, row);
1216
}
1217
}
1218
if (color_cache != NULL) {
1219
while (last_cached < src) {
1220
VP8LColorCacheInsert(color_cache, *last_cached++);
1221
}
1222
}
1223
}
1224
} else if (code < len_code_limit) { // Backward reference
1225
int dist_code, dist;
1226
const int length_sym = code - NUM_LITERAL_CODES;
1227
const int length = GetCopyLength(length_sym, br);
1228
const int dist_symbol = ReadSymbol(htree_group->htrees[DIST], br);
1229
VP8LFillBitWindow(br);
1230
dist_code = GetCopyDistance(dist_symbol, br);
1231
dist = PlaneCodeToDistance(width, dist_code);
1232
1233
if (VP8LIsEndOfStream(br)) break;
1234
if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
1235
goto Error;
1236
} else {
1237
CopyBlock32b(src, dist, length);
1238
}
1239
src += length;
1240
col += length;
1241
while (col >= width) {
1242
col -= width;
1243
++row;
1244
if (process_func != NULL) {
1245
if (row <= last_row && (row % NUM_ARGB_CACHE_ROWS == 0)) {
1246
process_func(dec, row);
1247
}
1248
}
1249
}
1250
// Because of the check done above (before 'src' was incremented by
1251
// 'length'), the following holds true.
1252
assert(src <= src_end);
1253
if (col & mask) htree_group = GetHtreeGroupForPos(hdr, col, row);
1254
if (color_cache != NULL) {
1255
while (last_cached < src) {
1256
VP8LColorCacheInsert(color_cache, *last_cached++);
1257
}
1258
}
1259
} else if (code < color_cache_limit) { // Color cache
1260
const int key = code - len_code_limit;
1261
assert(color_cache != NULL);
1262
while (last_cached < src) {
1263
VP8LColorCacheInsert(color_cache, *last_cached++);
1264
}
1265
*src = VP8LColorCacheLookup(color_cache, key);
1266
goto AdvanceByOne;
1267
} else { // Not reached
1268
goto Error;
1269
}
1270
}
1271
1272
br->eos = VP8LIsEndOfStream(br);
1273
// In incremental decoding:
1274
// br->eos && src < src_last: if 'br' reached the end of the buffer and
1275
// 'src_last' has not been reached yet, there is not enough data. 'dec' has to
1276
// be reset until there is more data.
1277
// !br->eos && src < src_last: this cannot happen as either the buffer is
1278
// fully read, either enough has been read to reach 'src_last'.
1279
// src >= src_last: 'src_last' is reached, all is fine. 'src' can actually go
1280
// beyond 'src_last' in case the image is cropped and an LZ77 goes further.
1281
// The buffer might have been enough or there is some left. 'br->eos' does
1282
// not matter.
1283
assert(!dec->incremental || (br->eos && src < src_last) || src >= src_last);
1284
if (dec->incremental && br->eos && src < src_last) {
1285
RestoreState(dec);
1286
} else if ((dec->incremental && src >= src_last) || !br->eos) {
1287
// Process the remaining rows corresponding to last row-block.
1288
if (process_func != NULL) {
1289
process_func(dec, row > last_row ? last_row : row);
1290
}
1291
dec->status = VP8_STATUS_OK;
1292
dec->last_pixel = (int)(src - data); // end-of-scan marker
1293
} else {
1294
// if not incremental, and we are past the end of buffer (eos=1), then this
1295
// is a real bitstream error.
1296
goto Error;
1297
}
1298
return 1;
1299
1300
Error:
1301
return VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
1302
}
1303
1304
// -----------------------------------------------------------------------------
1305
// VP8LTransform
1306
1307
static void ClearTransform(VP8LTransform* const transform) {
1308
WebPSafeFree(transform->data);
1309
transform->data = NULL;
1310
}
1311
1312
// For security reason, we need to remap the color map to span
1313
// the total possible bundled values, and not just the num_colors.
1314
static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
1315
int i;
1316
const int final_num_colors = 1 << (8 >> transform->bits);
1317
uint32_t* const new_color_map =
1318
(uint32_t*)WebPSafeMalloc((uint64_t)final_num_colors,
1319
sizeof(*new_color_map));
1320
if (new_color_map == NULL) {
1321
return 0;
1322
} else {
1323
uint8_t* const data = (uint8_t*)transform->data;
1324
uint8_t* const new_data = (uint8_t*)new_color_map;
1325
new_color_map[0] = transform->data[0];
1326
for (i = 4; i < 4 * num_colors; ++i) {
1327
// Equivalent to VP8LAddPixels(), on a byte-basis.
1328
new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
1329
}
1330
for (; i < 4 * final_num_colors; ++i) {
1331
new_data[i] = 0; // black tail.
1332
}
1333
WebPSafeFree(transform->data);
1334
transform->data = new_color_map;
1335
}
1336
return 1;
1337
}
1338
1339
static int ReadTransform(int* const xsize, int const* ysize,
1340
VP8LDecoder* const dec) {
1341
int ok = 1;
1342
VP8LBitReader* const br = &dec->br;
1343
VP8LTransform* transform = &dec->transforms[dec->next_transform];
1344
const VP8LImageTransformType type =
1345
(VP8LImageTransformType)VP8LReadBits(br, 2);
1346
1347
// Each transform type can only be present once in the stream.
1348
if (dec->transforms_seen & (1U << type)) {
1349
return 0; // Already there, let's not accept the second same transform.
1350
}
1351
dec->transforms_seen |= (1U << type);
1352
1353
transform->type = type;
1354
transform->xsize = *xsize;
1355
transform->ysize = *ysize;
1356
transform->data = NULL;
1357
++dec->next_transform;
1358
assert(dec->next_transform <= NUM_TRANSFORMS);
1359
1360
switch (type) {
1361
case PREDICTOR_TRANSFORM:
1362
case CROSS_COLOR_TRANSFORM:
1363
transform->bits =
1364
MIN_TRANSFORM_BITS + VP8LReadBits(br, NUM_TRANSFORM_BITS);
1365
ok = DecodeImageStream(VP8LSubSampleSize(transform->xsize,
1366
transform->bits),
1367
VP8LSubSampleSize(transform->ysize,
1368
transform->bits),
1369
/*is_level0=*/0, dec, &transform->data);
1370
break;
1371
case COLOR_INDEXING_TRANSFORM: {
1372
const int num_colors = VP8LReadBits(br, 8) + 1;
1373
const int bits = (num_colors > 16) ? 0
1374
: (num_colors > 4) ? 1
1375
: (num_colors > 2) ? 2
1376
: 3;
1377
*xsize = VP8LSubSampleSize(transform->xsize, bits);
1378
transform->bits = bits;
1379
ok = DecodeImageStream(num_colors, /*ysize=*/1, /*is_level0=*/0, dec,
1380
&transform->data);
1381
if (ok && !ExpandColorMap(num_colors, transform)) {
1382
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
1383
}
1384
break;
1385
}
1386
case SUBTRACT_GREEN_TRANSFORM:
1387
break;
1388
default:
1389
assert(0); // can't happen
1390
break;
1391
}
1392
1393
return ok;
1394
}
1395
1396
// -----------------------------------------------------------------------------
1397
// VP8LMetadata
1398
1399
static void InitMetadata(VP8LMetadata* const hdr) {
1400
assert(hdr != NULL);
1401
memset(hdr, 0, sizeof(*hdr));
1402
}
1403
1404
static void ClearMetadata(VP8LMetadata* const hdr) {
1405
assert(hdr != NULL);
1406
1407
WebPSafeFree(hdr->huffman_image);
1408
VP8LHuffmanTablesDeallocate(&hdr->huffman_tables);
1409
VP8LHtreeGroupsFree(hdr->htree_groups);
1410
VP8LColorCacheClear(&hdr->color_cache);
1411
VP8LColorCacheClear(&hdr->saved_color_cache);
1412
InitMetadata(hdr);
1413
}
1414
1415
// -----------------------------------------------------------------------------
1416
// VP8LDecoder
1417
1418
VP8LDecoder* VP8LNew(void) {
1419
VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
1420
if (dec == NULL) return NULL;
1421
dec->status = VP8_STATUS_OK;
1422
dec->state = READ_DIM;
1423
1424
VP8LDspInit(); // Init critical function pointers.
1425
1426
return dec;
1427
}
1428
1429
// Resets the decoder in its initial state, reclaiming memory.
1430
// Preserves the dec->status value.
1431
static void VP8LClear(VP8LDecoder* const dec) {
1432
int i;
1433
if (dec == NULL) return;
1434
ClearMetadata(&dec->hdr);
1435
1436
WebPSafeFree(dec->pixels);
1437
dec->pixels = NULL;
1438
for (i = 0; i < dec->next_transform; ++i) {
1439
ClearTransform(&dec->transforms[i]);
1440
}
1441
dec->next_transform = 0;
1442
dec->transforms_seen = 0;
1443
1444
WebPSafeFree(dec->rescaler_memory);
1445
dec->rescaler_memory = NULL;
1446
1447
dec->output = NULL; // leave no trace behind
1448
}
1449
1450
void VP8LDelete(VP8LDecoder* const dec) {
1451
if (dec != NULL) {
1452
VP8LClear(dec);
1453
WebPSafeFree(dec);
1454
}
1455
}
1456
1457
static void UpdateDecoder(VP8LDecoder* const dec, int width, int height) {
1458
VP8LMetadata* const hdr = &dec->hdr;
1459
const int num_bits = hdr->huffman_subsample_bits;
1460
dec->width = width;
1461
dec->height = height;
1462
1463
hdr->huffman_xsize = VP8LSubSampleSize(width, num_bits);
1464
hdr->huffman_mask = (num_bits == 0) ? ~0 : (1 << num_bits) - 1;
1465
}
1466
1467
static int DecodeImageStream(int xsize, int ysize,
1468
int is_level0,
1469
VP8LDecoder* const dec,
1470
uint32_t** const decoded_data) {
1471
int ok = 1;
1472
int transform_xsize = xsize;
1473
int transform_ysize = ysize;
1474
VP8LBitReader* const br = &dec->br;
1475
VP8LMetadata* const hdr = &dec->hdr;
1476
uint32_t* data = NULL;
1477
int color_cache_bits = 0;
1478
1479
// Read the transforms (may recurse).
1480
if (is_level0) {
1481
while (ok && VP8LReadBits(br, 1)) {
1482
ok = ReadTransform(&transform_xsize, &transform_ysize, dec);
1483
}
1484
}
1485
1486
// Color cache
1487
if (ok && VP8LReadBits(br, 1)) {
1488
color_cache_bits = VP8LReadBits(br, 4);
1489
ok = (color_cache_bits >= 1 && color_cache_bits <= MAX_CACHE_BITS);
1490
if (!ok) {
1491
VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
1492
goto End;
1493
}
1494
}
1495
1496
// Read the Huffman codes (may recurse).
1497
ok = ok && ReadHuffmanCodes(dec, transform_xsize, transform_ysize,
1498
color_cache_bits, is_level0);
1499
if (!ok) {
1500
VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
1501
goto End;
1502
}
1503
1504
// Finish setting up the color-cache
1505
if (color_cache_bits > 0) {
1506
hdr->color_cache_size = 1 << color_cache_bits;
1507
if (!VP8LColorCacheInit(&hdr->color_cache, color_cache_bits)) {
1508
ok = VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
1509
goto End;
1510
}
1511
} else {
1512
hdr->color_cache_size = 0;
1513
}
1514
UpdateDecoder(dec, transform_xsize, transform_ysize);
1515
1516
if (is_level0) { // level 0 complete
1517
dec->state = READ_HDR;
1518
goto End;
1519
}
1520
1521
{
1522
const uint64_t total_size = (uint64_t)transform_xsize * transform_ysize;
1523
data = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*data));
1524
if (data == NULL) {
1525
ok = VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
1526
goto End;
1527
}
1528
}
1529
1530
// Use the Huffman trees to decode the LZ77 encoded data.
1531
ok = DecodeImageData(dec, data, transform_xsize, transform_ysize,
1532
transform_ysize, NULL);
1533
ok = ok && !br->eos;
1534
1535
End:
1536
if (!ok) {
1537
WebPSafeFree(data);
1538
ClearMetadata(hdr);
1539
} else {
1540
if (decoded_data != NULL) {
1541
*decoded_data = data;
1542
} else {
1543
// We allocate image data in this function only for transforms. At level 0
1544
// (that is: not the transforms), we shouldn't have allocated anything.
1545
assert(data == NULL);
1546
assert(is_level0);
1547
}
1548
dec->last_pixel = 0; // Reset for future DECODE_DATA_FUNC() calls.
1549
if (!is_level0) ClearMetadata(hdr); // Clean up temporary data behind.
1550
}
1551
return ok;
1552
}
1553
1554
//------------------------------------------------------------------------------
1555
// Allocate internal buffers dec->pixels and dec->argb_cache.
1556
static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
1557
const uint64_t num_pixels = (uint64_t)dec->width * dec->height;
1558
// Scratch buffer corresponding to top-prediction row for transforming the
1559
// first row in the row-blocks. Not needed for paletted alpha.
1560
const uint64_t cache_top_pixels = (uint16_t)final_width;
1561
// Scratch buffer for temporary BGRA storage. Not needed for paletted alpha.
1562
const uint64_t cache_pixels = (uint64_t)final_width * NUM_ARGB_CACHE_ROWS;
1563
const uint64_t total_num_pixels =
1564
num_pixels + cache_top_pixels + cache_pixels;
1565
1566
assert(dec->width <= final_width);
1567
dec->pixels = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
1568
if (dec->pixels == NULL) {
1569
dec->argb_cache = NULL; // for soundness
1570
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
1571
}
1572
dec->argb_cache = dec->pixels + num_pixels + cache_top_pixels;
1573
return 1;
1574
}
1575
1576
static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
1577
const uint64_t total_num_pixels = (uint64_t)dec->width * dec->height;
1578
dec->argb_cache = NULL; // for soundness
1579
dec->pixels = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
1580
if (dec->pixels == NULL) {
1581
return VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
1582
}
1583
return 1;
1584
}
1585
1586
//------------------------------------------------------------------------------
1587
1588
// Special row-processing that only stores the alpha data.
1589
static void ExtractAlphaRows(VP8LDecoder* const dec, int last_row) {
1590
int cur_row = dec->last_row;
1591
int num_rows = last_row - cur_row;
1592
const uint32_t* in = dec->pixels + dec->width * cur_row;
1593
1594
assert(last_row <= dec->io->crop_bottom);
1595
while (num_rows > 0) {
1596
const int num_rows_to_process =
1597
(num_rows > NUM_ARGB_CACHE_ROWS) ? NUM_ARGB_CACHE_ROWS : num_rows;
1598
// Extract alpha (which is stored in the green plane).
1599
ALPHDecoder* const alph_dec = (ALPHDecoder*)dec->io->opaque;
1600
uint8_t* const output = alph_dec->output;
1601
const int width = dec->io->width; // the final width (!= dec->width)
1602
const int cache_pixs = width * num_rows_to_process;
1603
uint8_t* const dst = output + width * cur_row;
1604
const uint32_t* const src = dec->argb_cache;
1605
ApplyInverseTransforms(dec, cur_row, num_rows_to_process, in);
1606
WebPExtractGreen(src, dst, cache_pixs);
1607
AlphaApplyFilter(alph_dec,
1608
cur_row, cur_row + num_rows_to_process, dst, width);
1609
num_rows -= num_rows_to_process;
1610
in += num_rows_to_process * dec->width;
1611
cur_row += num_rows_to_process;
1612
}
1613
assert(cur_row == last_row);
1614
dec->last_row = dec->last_out_row = last_row;
1615
}
1616
1617
int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
1618
const uint8_t* const data, size_t data_size) {
1619
int ok = 0;
1620
VP8LDecoder* dec = VP8LNew();
1621
1622
if (dec == NULL) return 0;
1623
1624
assert(alph_dec != NULL);
1625
1626
dec->width = alph_dec->width;
1627
dec->height = alph_dec->height;
1628
dec->io = &alph_dec->io;
1629
dec->io->opaque = alph_dec;
1630
dec->io->width = alph_dec->width;
1631
dec->io->height = alph_dec->height;
1632
1633
dec->status = VP8_STATUS_OK;
1634
VP8LInitBitReader(&dec->br, data, data_size);
1635
1636
if (!DecodeImageStream(alph_dec->width, alph_dec->height, /*is_level0=*/1,
1637
dec, /*decoded_data=*/NULL)) {
1638
goto Err;
1639
}
1640
1641
// Special case: if alpha data uses only the color indexing transform and
1642
// doesn't use color cache (a frequent case), we will use DecodeAlphaData()
1643
// method that only needs allocation of 1 byte per pixel (alpha channel).
1644
if (dec->next_transform == 1 &&
1645
dec->transforms[0].type == COLOR_INDEXING_TRANSFORM &&
1646
Is8bOptimizable(&dec->hdr)) {
1647
alph_dec->use_8b_decode = 1;
1648
ok = AllocateInternalBuffers8b(dec);
1649
} else {
1650
// Allocate internal buffers (note that dec->width may have changed here).
1651
alph_dec->use_8b_decode = 0;
1652
ok = AllocateInternalBuffers32b(dec, alph_dec->width);
1653
}
1654
1655
if (!ok) goto Err;
1656
1657
// Only set here, once we are sure it is valid (to avoid thread races).
1658
alph_dec->vp8l_dec = dec;
1659
return 1;
1660
1661
Err:
1662
VP8LDelete(dec);
1663
return 0;
1664
}
1665
1666
int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) {
1667
VP8LDecoder* const dec = alph_dec->vp8l_dec;
1668
assert(dec != NULL);
1669
assert(last_row <= dec->height);
1670
1671
if (dec->last_row >= last_row) {
1672
return 1; // done
1673
}
1674
1675
if (!alph_dec->use_8b_decode) WebPInitAlphaProcessing();
1676
1677
// Decode (with special row processing).
1678
return alph_dec->use_8b_decode ?
1679
DecodeAlphaData(dec, (uint8_t*)dec->pixels, dec->width, dec->height,
1680
last_row) :
1681
DecodeImageData(dec, dec->pixels, dec->width, dec->height,
1682
last_row, ExtractAlphaRows);
1683
}
1684
1685
//------------------------------------------------------------------------------
1686
1687
int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
1688
int width, height, has_alpha;
1689
1690
if (dec == NULL) return 0;
1691
if (io == NULL) {
1692
return VP8LSetError(dec, VP8_STATUS_INVALID_PARAM);
1693
}
1694
1695
dec->io = io;
1696
dec->status = VP8_STATUS_OK;
1697
VP8LInitBitReader(&dec->br, io->data, io->data_size);
1698
if (!ReadImageInfo(&dec->br, &width, &height, &has_alpha)) {
1699
VP8LSetError(dec, VP8_STATUS_BITSTREAM_ERROR);
1700
goto Error;
1701
}
1702
dec->state = READ_DIM;
1703
io->width = width;
1704
io->height = height;
1705
1706
if (!DecodeImageStream(width, height, /*is_level0=*/1, dec,
1707
/*decoded_data=*/NULL)) {
1708
goto Error;
1709
}
1710
return 1;
1711
1712
Error:
1713
VP8LClear(dec);
1714
assert(dec->status != VP8_STATUS_OK);
1715
return 0;
1716
}
1717
1718
int VP8LDecodeImage(VP8LDecoder* const dec) {
1719
VP8Io* io = NULL;
1720
WebPDecParams* params = NULL;
1721
1722
if (dec == NULL) return 0;
1723
1724
assert(dec->hdr.huffman_tables.root.start != NULL);
1725
assert(dec->hdr.htree_groups != NULL);
1726
assert(dec->hdr.num_htree_groups > 0);
1727
1728
io = dec->io;
1729
assert(io != NULL);
1730
params = (WebPDecParams*)io->opaque;
1731
assert(params != NULL);
1732
1733
// Initialization.
1734
if (dec->state != READ_DATA) {
1735
dec->output = params->output;
1736
assert(dec->output != NULL);
1737
1738
if (!WebPIoInitFromOptions(params->options, io, MODE_BGRA)) {
1739
VP8LSetError(dec, VP8_STATUS_INVALID_PARAM);
1740
goto Err;
1741
}
1742
1743
if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
1744
1745
#if !defined(WEBP_REDUCE_SIZE)
1746
if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
1747
#else
1748
if (io->use_scaling) {
1749
VP8LSetError(dec, VP8_STATUS_INVALID_PARAM);
1750
goto Err;
1751
}
1752
#endif
1753
if (io->use_scaling || WebPIsPremultipliedMode(dec->output->colorspace)) {
1754
// need the alpha-multiply functions for premultiplied output or rescaling
1755
WebPInitAlphaProcessing();
1756
}
1757
1758
if (!WebPIsRGBMode(dec->output->colorspace)) {
1759
WebPInitConvertARGBToYUV();
1760
if (dec->output->u.YUVA.a != NULL) WebPInitAlphaProcessing();
1761
}
1762
if (dec->incremental) {
1763
if (dec->hdr.color_cache_size > 0 &&
1764
dec->hdr.saved_color_cache.colors == NULL) {
1765
if (!VP8LColorCacheInit(&dec->hdr.saved_color_cache,
1766
dec->hdr.color_cache.hash_bits)) {
1767
VP8LSetError(dec, VP8_STATUS_OUT_OF_MEMORY);
1768
goto Err;
1769
}
1770
}
1771
}
1772
dec->state = READ_DATA;
1773
}
1774
1775
// Decode.
1776
if (!DecodeImageData(dec, dec->pixels, dec->width, dec->height,
1777
io->crop_bottom, ProcessRows)) {
1778
goto Err;
1779
}
1780
1781
params->last_y = dec->last_out_row;
1782
return 1;
1783
1784
Err:
1785
VP8LClear(dec);
1786
assert(dec->status != VP8_STATUS_OK);
1787
return 0;
1788
}
1789
1790
//------------------------------------------------------------------------------
1791
1792