Coverage Report

Created: 2026-09-01 06:55

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