Coverage Report

Created: 2025-06-13 06:48

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