Coverage Report

Created: 2025-08-12 07:37

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