Coverage Report

Created: 2026-03-31 06:35

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