/src/ffmpeg/libavcodec/webp.c
Line | Count | Source |
1 | | /* |
2 | | * WebP (.webp) image decoder |
3 | | * Copyright (c) 2013 Aneesh Dogra <aneesh@sugarlabs.org> |
4 | | * Copyright (c) 2013 Justin Ruggles <justin.ruggles@gmail.com> |
5 | | * |
6 | | * This file is part of FFmpeg. |
7 | | * |
8 | | * FFmpeg is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public |
10 | | * License as published by the Free Software Foundation; either |
11 | | * version 2.1 of the License, or (at your option) any later version. |
12 | | * |
13 | | * FFmpeg is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public |
19 | | * License along with FFmpeg; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | */ |
22 | | |
23 | | /** |
24 | | * @file |
25 | | * WebP image decoder |
26 | | * |
27 | | * @author Aneesh Dogra <aneesh@sugarlabs.org> |
28 | | * Container and Lossy decoding |
29 | | * |
30 | | * @author Justin Ruggles <justin.ruggles@gmail.com> |
31 | | * Lossless decoder |
32 | | * Compressed alpha for lossy |
33 | | * |
34 | | * @author James Almer <jamrial@gmail.com> |
35 | | * Exif metadata |
36 | | * ICC profile |
37 | | * |
38 | | * Unimplemented: |
39 | | * - Animation |
40 | | * - XMP metadata |
41 | | */ |
42 | | |
43 | | #include "libavutil/imgutils.h" |
44 | | #include "libavutil/mem.h" |
45 | | |
46 | | #define BITSTREAM_READER_LE |
47 | | #include "avcodec.h" |
48 | | #include "bytestream.h" |
49 | | #include "codec_internal.h" |
50 | | #include "decode.h" |
51 | | #include "exif_internal.h" |
52 | | #include "get_bits.h" |
53 | | #include "thread.h" |
54 | | #include "tiff_common.h" |
55 | | #include "vp8.h" |
56 | | |
57 | | #define VP8X_FLAG_ANIMATION 0x02 |
58 | | #define VP8X_FLAG_XMP_METADATA 0x04 |
59 | 15.5k | #define VP8X_FLAG_EXIF_METADATA 0x08 |
60 | 5.71k | #define VP8X_FLAG_ALPHA 0x10 |
61 | 3.02k | #define VP8X_FLAG_ICC 0x20 |
62 | | |
63 | | #define MAX_PALETTE_SIZE 256 |
64 | | #define MAX_CACHE_BITS 11 |
65 | 15.0k | #define NUM_CODE_LENGTH_CODES 19 |
66 | 972M | #define HUFFMAN_CODES_PER_META_CODE 5 |
67 | 523M | #define NUM_LITERAL_CODES 256 |
68 | 138k | #define NUM_LENGTH_CODES 24 |
69 | | #define NUM_DISTANCE_CODES 40 |
70 | 53.5k | #define NUM_SHORT_DISTANCES 120 |
71 | 380k | #define MAX_HUFFMAN_CODE_LENGTH 15 |
72 | | |
73 | | static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE] = { |
74 | | NUM_LITERAL_CODES + NUM_LENGTH_CODES, |
75 | | NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES, |
76 | | NUM_DISTANCE_CODES |
77 | | }; |
78 | | |
79 | | static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES] = { |
80 | | 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 |
81 | | }; |
82 | | |
83 | | static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2] = { |
84 | | { 0, 1 }, { 1, 0 }, { 1, 1 }, { -1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { -1, 2 }, |
85 | | { 2, 1 }, { -2, 1 }, { 2, 2 }, { -2, 2 }, { 0, 3 }, { 3, 0 }, { 1, 3 }, { -1, 3 }, |
86 | | { 3, 1 }, { -3, 1 }, { 2, 3 }, { -2, 3 }, { 3, 2 }, { -3, 2 }, { 0, 4 }, { 4, 0 }, |
87 | | { 1, 4 }, { -1, 4 }, { 4, 1 }, { -4, 1 }, { 3, 3 }, { -3, 3 }, { 2, 4 }, { -2, 4 }, |
88 | | { 4, 2 }, { -4, 2 }, { 0, 5 }, { 3, 4 }, { -3, 4 }, { 4, 3 }, { -4, 3 }, { 5, 0 }, |
89 | | { 1, 5 }, { -1, 5 }, { 5, 1 }, { -5, 1 }, { 2, 5 }, { -2, 5 }, { 5, 2 }, { -5, 2 }, |
90 | | { 4, 4 }, { -4, 4 }, { 3, 5 }, { -3, 5 }, { 5, 3 }, { -5, 3 }, { 0, 6 }, { 6, 0 }, |
91 | | { 1, 6 }, { -1, 6 }, { 6, 1 }, { -6, 1 }, { 2, 6 }, { -2, 6 }, { 6, 2 }, { -6, 2 }, |
92 | | { 4, 5 }, { -4, 5 }, { 5, 4 }, { -5, 4 }, { 3, 6 }, { -3, 6 }, { 6, 3 }, { -6, 3 }, |
93 | | { 0, 7 }, { 7, 0 }, { 1, 7 }, { -1, 7 }, { 5, 5 }, { -5, 5 }, { 7, 1 }, { -7, 1 }, |
94 | | { 4, 6 }, { -4, 6 }, { 6, 4 }, { -6, 4 }, { 2, 7 }, { -2, 7 }, { 7, 2 }, { -7, 2 }, |
95 | | { 3, 7 }, { -3, 7 }, { 7, 3 }, { -7, 3 }, { 5, 6 }, { -5, 6 }, { 6, 5 }, { -6, 5 }, |
96 | | { 8, 0 }, { 4, 7 }, { -4, 7 }, { 7, 4 }, { -7, 4 }, { 8, 1 }, { 8, 2 }, { 6, 6 }, |
97 | | { -6, 6 }, { 8, 3 }, { 5, 7 }, { -5, 7 }, { 7, 5 }, { -7, 5 }, { 8, 4 }, { 6, 7 }, |
98 | | { -6, 7 }, { 7, 6 }, { -7, 6 }, { 8, 5 }, { 7, 7 }, { -7, 7 }, { 8, 6 }, { 8, 7 } |
99 | | }; |
100 | | |
101 | | enum AlphaCompression { |
102 | | ALPHA_COMPRESSION_NONE, |
103 | | ALPHA_COMPRESSION_VP8L, |
104 | | }; |
105 | | |
106 | | enum AlphaFilter { |
107 | | ALPHA_FILTER_NONE, |
108 | | ALPHA_FILTER_HORIZONTAL, |
109 | | ALPHA_FILTER_VERTICAL, |
110 | | ALPHA_FILTER_GRADIENT, |
111 | | }; |
112 | | |
113 | | enum TransformType { |
114 | | PREDICTOR_TRANSFORM = 0, |
115 | | COLOR_TRANSFORM = 1, |
116 | | SUBTRACT_GREEN = 2, |
117 | | COLOR_INDEXING_TRANSFORM = 3, |
118 | | }; |
119 | | |
120 | | enum PredictionMode { |
121 | | PRED_MODE_BLACK, |
122 | | PRED_MODE_L, |
123 | | PRED_MODE_T, |
124 | | PRED_MODE_TR, |
125 | | PRED_MODE_TL, |
126 | | PRED_MODE_AVG_T_AVG_L_TR, |
127 | | PRED_MODE_AVG_L_TL, |
128 | | PRED_MODE_AVG_L_T, |
129 | | PRED_MODE_AVG_TL_T, |
130 | | PRED_MODE_AVG_T_TR, |
131 | | PRED_MODE_AVG_AVG_L_TL_AVG_T_TR, |
132 | | PRED_MODE_SELECT, |
133 | | PRED_MODE_ADD_SUBTRACT_FULL, |
134 | | PRED_MODE_ADD_SUBTRACT_HALF, |
135 | | }; |
136 | | |
137 | | enum HuffmanIndex { |
138 | | HUFF_IDX_GREEN = 0, |
139 | | HUFF_IDX_RED = 1, |
140 | | HUFF_IDX_BLUE = 2, |
141 | | HUFF_IDX_ALPHA = 3, |
142 | | HUFF_IDX_DIST = 4 |
143 | | }; |
144 | | |
145 | | /* The structure of WebP lossless is an optional series of transformation data, |
146 | | * followed by the primary image. The primary image also optionally contains |
147 | | * an entropy group mapping if there are multiple entropy groups. There is a |
148 | | * basic image type called an "entropy coded image" that is used for all of |
149 | | * these. The type of each entropy coded image is referred to by the |
150 | | * specification as its role. */ |
151 | | enum ImageRole { |
152 | | /* Primary Image: Stores the actual pixels of the image. */ |
153 | | IMAGE_ROLE_ARGB, |
154 | | |
155 | | /* Entropy Image: Defines which Huffman group to use for different areas of |
156 | | * the primary image. */ |
157 | | IMAGE_ROLE_ENTROPY, |
158 | | |
159 | | /* Predictors: Defines which predictor type to use for different areas of |
160 | | * the primary image. */ |
161 | | IMAGE_ROLE_PREDICTOR, |
162 | | |
163 | | /* Color Transform Data: Defines the color transformation for different |
164 | | * areas of the primary image. */ |
165 | | IMAGE_ROLE_COLOR_TRANSFORM, |
166 | | |
167 | | /* Color Index: Stored as an image of height == 1. */ |
168 | | IMAGE_ROLE_COLOR_INDEXING, |
169 | | |
170 | | IMAGE_ROLE_NB, |
171 | | }; |
172 | | |
173 | | typedef struct HuffReader { |
174 | | VLC vlc; /* Huffman decoder context */ |
175 | | int simple; /* whether to use simple mode */ |
176 | | int nb_symbols; /* number of coded symbols */ |
177 | | uint16_t simple_symbols[2]; /* symbols for simple mode */ |
178 | | } HuffReader; |
179 | | |
180 | | typedef struct ImageContext { |
181 | | enum ImageRole role; /* role of this image */ |
182 | | AVFrame *frame; /* AVFrame for data */ |
183 | | int color_cache_bits; /* color cache size, log2 */ |
184 | | uint32_t *color_cache; /* color cache data */ |
185 | | int nb_huffman_groups; /* number of huffman groups */ |
186 | | HuffReader *huffman_groups; /* reader for each huffman group */ |
187 | | /* relative size compared to primary image, log2. |
188 | | * for IMAGE_ROLE_COLOR_INDEXING with <= 16 colors, this is log2 of the |
189 | | * number of pixels per byte in the primary image (pixel packing) */ |
190 | | int size_reduction; |
191 | | int is_alpha_primary; |
192 | | } ImageContext; |
193 | | |
194 | | typedef struct WebPContext { |
195 | | VP8Context v; /* VP8 Context used for lossy decoding */ |
196 | | GetBitContext gb; /* bitstream reader for main image chunk */ |
197 | | AVFrame *alpha_frame; /* AVFrame for alpha data decompressed from VP8L */ |
198 | | AVPacket *pkt; /* AVPacket to be passed to the underlying VP8 decoder */ |
199 | | AVCodecContext *avctx; /* parent AVCodecContext */ |
200 | | int initialized; /* set once the VP8 context is initialized */ |
201 | | int has_alpha; /* has a separate alpha chunk */ |
202 | | enum AlphaCompression alpha_compression; /* compression type for alpha chunk */ |
203 | | enum AlphaFilter alpha_filter; /* filtering method for alpha chunk */ |
204 | | const uint8_t *alpha_data; /* alpha chunk data */ |
205 | | int alpha_data_size; /* alpha chunk data size */ |
206 | | int has_exif; /* set after an EXIF chunk has been processed */ |
207 | | int has_iccp; /* set after an ICCP chunk has been processed */ |
208 | | int width; /* image width */ |
209 | | int height; /* image height */ |
210 | | int lossless; /* indicates lossless or lossy */ |
211 | | |
212 | | int nb_transforms; /* number of transforms */ |
213 | | enum TransformType transforms[4]; /* transformations used in the image, in order */ |
214 | | /* reduced width when using a color indexing transform with <= 16 colors (pixel packing) |
215 | | * before pixels are unpacked, or same as width otherwise. */ |
216 | | int reduced_width; |
217 | | int nb_huffman_groups; /* number of huffman groups in the primary image */ |
218 | | ImageContext image[IMAGE_ROLE_NB]; /* image context for each role */ |
219 | | } WebPContext; |
220 | | |
221 | | #define GET_PIXEL(frame, x, y) \ |
222 | 1.65G | ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x)) |
223 | | |
224 | | #define GET_PIXEL_COMP(frame, x, y, c) \ |
225 | 39.2M | (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c)) |
226 | | |
227 | | static void image_ctx_free(ImageContext *img) |
228 | 247k | { |
229 | 247k | int i, j; |
230 | | |
231 | 247k | av_free(img->color_cache); |
232 | 247k | if (img->role != IMAGE_ROLE_ARGB && !img->is_alpha_primary) |
233 | 50.7k | av_frame_free(&img->frame); |
234 | 247k | if (img->huffman_groups) { |
235 | 26.4M | for (i = 0; i < img->nb_huffman_groups; i++) { |
236 | 157M | for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) |
237 | 131M | ff_vlc_free(&img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE + j].vlc); |
238 | 26.3M | } |
239 | 87.6k | av_free(img->huffman_groups); |
240 | 87.6k | } |
241 | 247k | memset(img, 0, sizeof(*img)); |
242 | 247k | } |
243 | | |
244 | | static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb) |
245 | 2.09G | { |
246 | 2.09G | if (r->simple) { |
247 | 2.03G | if (r->nb_symbols == 1) |
248 | 2.03G | return r->simple_symbols[0]; |
249 | 1.85M | else |
250 | 1.85M | return r->simple_symbols[get_bits1(gb)]; |
251 | 2.03G | } else |
252 | 63.3M | return get_vlc2(gb, r->vlc.table, 8, 2); |
253 | 2.09G | } |
254 | | |
255 | | static int huff_reader_build_canonical(HuffReader *r, const uint8_t *code_lengths, |
256 | | uint16_t len_counts[MAX_HUFFMAN_CODE_LENGTH + 1], |
257 | | uint8_t lens[], uint16_t syms[], |
258 | | int alphabet_size, void *logctx) |
259 | 23.7k | { |
260 | 23.7k | unsigned nb_codes = 0; |
261 | 23.7k | int ret; |
262 | | |
263 | | // Count the number of symbols of each length and transform len_counts |
264 | | // into an array of offsets. |
265 | 380k | for (int len = 1; len <= MAX_HUFFMAN_CODE_LENGTH; ++len) { |
266 | 356k | unsigned cnt = len_counts[len]; |
267 | 356k | len_counts[len] = nb_codes; |
268 | 356k | nb_codes += cnt; |
269 | 356k | } |
270 | | |
271 | 3.38M | for (int sym = 0; sym < alphabet_size; ++sym) { |
272 | 3.36M | if (code_lengths[sym]) { |
273 | 2.44M | unsigned idx = len_counts[code_lengths[sym]]++; |
274 | 2.44M | syms[idx] = sym; |
275 | 2.44M | lens[idx] = code_lengths[sym]; |
276 | 2.44M | } |
277 | 3.36M | } |
278 | | |
279 | 23.7k | if (nb_codes == 0) { |
280 | | // No symbols |
281 | 4.08k | return AVERROR_INVALIDDATA; |
282 | 4.08k | } |
283 | 19.6k | if (nb_codes == 1) { |
284 | | // Special-case 1 symbol since the VLC reader cannot handle it |
285 | 700 | r->nb_symbols = 1; |
286 | 700 | r->simple = 1; |
287 | 700 | r->simple_symbols[0] = syms[0]; |
288 | 700 | return 0; |
289 | 700 | } |
290 | | |
291 | 18.9k | ret = ff_vlc_init_from_lengths(&r->vlc, 8, nb_codes, lens, 1, |
292 | 18.9k | syms, 2, 2, 0, VLC_INIT_OUTPUT_LE, logctx); |
293 | 18.9k | if (ret < 0) |
294 | 1.77k | return ret; |
295 | 17.2k | r->simple = 0; |
296 | | |
297 | 17.2k | return 0; |
298 | 18.9k | } |
299 | | |
300 | | static void read_huffman_code_simple(WebPContext *s, HuffReader *hc) |
301 | 113M | { |
302 | 113M | hc->nb_symbols = get_bits1(&s->gb) + 1; |
303 | | |
304 | 113M | if (get_bits1(&s->gb)) |
305 | 113M | hc->simple_symbols[0] = get_bits(&s->gb, 8); |
306 | 320k | else |
307 | 320k | hc->simple_symbols[0] = get_bits1(&s->gb); |
308 | | |
309 | 113M | if (hc->nb_symbols == 2) |
310 | 113M | hc->simple_symbols[1] = get_bits(&s->gb, 8); |
311 | | |
312 | 113M | hc->simple = 1; |
313 | 113M | } |
314 | | |
315 | | static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, |
316 | | int alphabet_size) |
317 | 15.7k | { |
318 | 15.7k | HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } }; |
319 | 15.7k | uint8_t *code_lengths; |
320 | 15.7k | uint8_t code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 }; |
321 | 15.7k | uint8_t reordered_code_length_code_lengths[NUM_CODE_LENGTH_CODES]; |
322 | 15.7k | uint16_t reordered_code_length_syms[NUM_CODE_LENGTH_CODES]; |
323 | 15.7k | uint16_t len_counts[MAX_HUFFMAN_CODE_LENGTH + 1] = { 0 }; |
324 | 15.7k | int symbol, max_symbol, prev_code_len, ret; |
325 | 15.7k | int num_codes = 4 + get_bits(&s->gb, 4); |
326 | | |
327 | 15.7k | av_assert1(num_codes <= NUM_CODE_LENGTH_CODES); |
328 | | |
329 | 174k | for (int i = 0; i < num_codes; i++) { |
330 | 159k | unsigned len = get_bits(&s->gb, 3); |
331 | 159k | code_length_code_lengths[code_length_code_order[i]] = len; |
332 | 159k | len_counts[len]++; |
333 | 159k | } |
334 | | |
335 | 15.7k | if (get_bits1(&s->gb)) { |
336 | 6.37k | int bits = 2 + 2 * get_bits(&s->gb, 3); |
337 | 6.37k | max_symbol = 2 + get_bits(&s->gb, bits); |
338 | 6.37k | if (max_symbol > alphabet_size) { |
339 | 714 | av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n", |
340 | 714 | max_symbol, alphabet_size); |
341 | 714 | return AVERROR_INVALIDDATA; |
342 | 714 | } |
343 | 9.35k | } else { |
344 | 9.35k | max_symbol = alphabet_size; |
345 | 9.35k | } |
346 | | |
347 | 15.0k | ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths, len_counts, |
348 | 15.0k | reordered_code_length_code_lengths, |
349 | 15.0k | reordered_code_length_syms, |
350 | 15.0k | NUM_CODE_LENGTH_CODES, s->avctx); |
351 | 15.0k | if (ret < 0) |
352 | 4.58k | return ret; |
353 | | |
354 | 10.4k | code_lengths = av_malloc_array(alphabet_size, 2 * sizeof(uint8_t) + sizeof(uint16_t)); |
355 | 10.4k | if (!code_lengths) { |
356 | 0 | ret = AVERROR(ENOMEM); |
357 | 0 | goto finish; |
358 | 0 | } |
359 | | |
360 | 10.4k | prev_code_len = 8; |
361 | 10.4k | symbol = 0; |
362 | 10.4k | memset(len_counts, 0, sizeof(len_counts)); |
363 | 1.87M | while (symbol < alphabet_size) { |
364 | 1.87M | int code_len; |
365 | | |
366 | 1.87M | if (!max_symbol--) |
367 | 3.99k | break; |
368 | 1.86M | code_len = huff_reader_get_symbol(&code_len_hc, &s->gb); |
369 | 1.86M | if (code_len < 16U) { |
370 | | /* Code length code [0..15] indicates literal code lengths. */ |
371 | 1.65M | code_lengths[symbol++] = code_len; |
372 | 1.65M | len_counts[code_len]++; |
373 | 1.65M | if (code_len) |
374 | 1.62M | prev_code_len = code_len; |
375 | 1.65M | } else { |
376 | 208k | int repeat = 0, length = 0; |
377 | 208k | switch (code_len) { |
378 | 1.26k | default: |
379 | 1.26k | ret = AVERROR_INVALIDDATA; |
380 | 1.26k | goto finish; |
381 | 153k | case 16: |
382 | | /* Code 16 repeats the previous non-zero value [3..6] times, |
383 | | * i.e., 3 + ReadBits(2) times. If code 16 is used before a |
384 | | * non-zero value has been emitted, a value of 8 is repeated. */ |
385 | 153k | repeat = 3 + get_bits(&s->gb, 2); |
386 | 153k | length = prev_code_len; |
387 | 153k | len_counts[length] += repeat; |
388 | 153k | break; |
389 | 24.7k | case 17: |
390 | | /* Code 17 emits a streak of zeros [3..10], i.e., |
391 | | * 3 + ReadBits(3) times. */ |
392 | 24.7k | repeat = 3 + get_bits(&s->gb, 3); |
393 | 24.7k | break; |
394 | 29.3k | case 18: |
395 | | /* Code 18 emits a streak of zeros of length [11..138], i.e., |
396 | | * 11 + ReadBits(7) times. */ |
397 | 29.3k | repeat = 11 + get_bits(&s->gb, 7); |
398 | 29.3k | break; |
399 | 208k | } |
400 | 207k | if (symbol + repeat > alphabet_size) { |
401 | 398 | av_log(s->avctx, AV_LOG_ERROR, |
402 | 398 | "invalid symbol %d + repeat %d > alphabet size %d\n", |
403 | 398 | symbol, repeat, alphabet_size); |
404 | 398 | ret = AVERROR_INVALIDDATA; |
405 | 398 | goto finish; |
406 | 398 | } |
407 | 2.00M | while (repeat-- > 0) |
408 | 1.80M | code_lengths[symbol++] = length; |
409 | 206k | } |
410 | 1.86M | } |
411 | | |
412 | 8.76k | ret = huff_reader_build_canonical(hc, code_lengths, len_counts, |
413 | 8.76k | code_lengths + symbol, |
414 | 8.76k | (uint16_t*)(code_lengths + 2 * symbol), |
415 | 8.76k | symbol, s->avctx); |
416 | | |
417 | 10.4k | finish: |
418 | 10.4k | ff_vlc_free(&code_len_hc.vlc); |
419 | 10.4k | av_free(code_lengths); |
420 | 10.4k | return ret; |
421 | 8.76k | } |
422 | | |
423 | | static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, |
424 | | int w, int h); |
425 | | |
426 | 41.0k | #define PARSE_BLOCK_SIZE(w, h) do { \ |
427 | 41.0k | block_bits = get_bits(&s->gb, 3) + 2; \ |
428 | 41.0k | blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \ |
429 | 41.0k | blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \ |
430 | 41.0k | } while (0) |
431 | | |
432 | | static int decode_entropy_image(WebPContext *s) |
433 | 5.69k | { |
434 | 5.69k | ImageContext *img; |
435 | 5.69k | int ret, block_bits, blocks_w, blocks_h, x, y, max; |
436 | | |
437 | 5.69k | PARSE_BLOCK_SIZE(s->reduced_width, s->height); |
438 | | |
439 | 5.69k | ret = decode_entropy_coded_image(s, IMAGE_ROLE_ENTROPY, blocks_w, blocks_h); |
440 | 5.69k | if (ret < 0) |
441 | 4.95k | return ret; |
442 | | |
443 | 739 | img = &s->image[IMAGE_ROLE_ENTROPY]; |
444 | 739 | img->size_reduction = block_bits; |
445 | | |
446 | | /* the number of huffman groups is determined by the maximum group number |
447 | | * coded in the entropy image */ |
448 | 739 | max = 0; |
449 | 9.02k | for (y = 0; y < img->frame->height; y++) { |
450 | 1.87M | for (x = 0; x < img->frame->width; x++) { |
451 | 1.86M | int p0 = GET_PIXEL_COMP(img->frame, x, y, 1); |
452 | 1.86M | int p1 = GET_PIXEL_COMP(img->frame, x, y, 2); |
453 | 1.86M | int p = p0 << 8 | p1; |
454 | 1.86M | max = FFMAX(max, p); |
455 | 1.86M | } |
456 | 8.28k | } |
457 | 739 | s->nb_huffman_groups = max + 1; |
458 | | |
459 | 739 | return 0; |
460 | 5.69k | } |
461 | | |
462 | | static int parse_transform_predictor(WebPContext *s) |
463 | 33.0k | { |
464 | 33.0k | int block_bits, blocks_w, blocks_h, ret; |
465 | | |
466 | 33.0k | PARSE_BLOCK_SIZE(s->reduced_width, s->height); |
467 | | |
468 | 33.0k | ret = decode_entropy_coded_image(s, IMAGE_ROLE_PREDICTOR, blocks_w, |
469 | 33.0k | blocks_h); |
470 | 33.0k | if (ret < 0) |
471 | 1.39k | return ret; |
472 | | |
473 | 31.6k | s->image[IMAGE_ROLE_PREDICTOR].size_reduction = block_bits; |
474 | | |
475 | 31.6k | return 0; |
476 | 33.0k | } |
477 | | |
478 | | static int parse_transform_color(WebPContext *s) |
479 | 2.29k | { |
480 | 2.29k | int block_bits, blocks_w, blocks_h, ret; |
481 | | |
482 | 2.29k | PARSE_BLOCK_SIZE(s->reduced_width, s->height); |
483 | | |
484 | 2.29k | ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_TRANSFORM, blocks_w, |
485 | 2.29k | blocks_h); |
486 | 2.29k | if (ret < 0) |
487 | 1.11k | return ret; |
488 | | |
489 | 1.17k | s->image[IMAGE_ROLE_COLOR_TRANSFORM].size_reduction = block_bits; |
490 | | |
491 | 1.17k | return 0; |
492 | 2.29k | } |
493 | | |
494 | | static int parse_transform_color_indexing(WebPContext *s) |
495 | 9.70k | { |
496 | 9.70k | ImageContext *img; |
497 | 9.70k | int width_bits, index_size, ret, x; |
498 | 9.70k | uint8_t *ct; |
499 | | |
500 | 9.70k | index_size = get_bits(&s->gb, 8) + 1; |
501 | | |
502 | 9.70k | if (index_size <= 2) |
503 | 3.25k | width_bits = 3; |
504 | 6.45k | else if (index_size <= 4) |
505 | 1.11k | width_bits = 2; |
506 | 5.33k | else if (index_size <= 16) |
507 | 747 | width_bits = 1; |
508 | 4.59k | else |
509 | 4.59k | width_bits = 0; |
510 | | |
511 | 9.70k | ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_INDEXING, |
512 | 9.70k | index_size, 1); |
513 | 9.70k | if (ret < 0) |
514 | 4.01k | return ret; |
515 | | |
516 | 5.69k | img = &s->image[IMAGE_ROLE_COLOR_INDEXING]; |
517 | 5.69k | img->size_reduction = width_bits; |
518 | 5.69k | if (width_bits > 0) |
519 | 4.56k | s->reduced_width = (s->width + ((1 << width_bits) - 1)) >> width_bits; |
520 | | |
521 | | /* color index values are delta-coded */ |
522 | 5.69k | ct = img->frame->data[0] + 4; |
523 | 626k | for (x = 4; x < img->frame->width * 4; x++, ct++) |
524 | 620k | ct[0] += ct[-4]; |
525 | | |
526 | 5.69k | return 0; |
527 | 9.70k | } |
528 | | |
529 | | static HuffReader *get_huffman_group(WebPContext *s, ImageContext *img, |
530 | | int x, int y) |
531 | 523M | { |
532 | 523M | ImageContext *gimg = &s->image[IMAGE_ROLE_ENTROPY]; |
533 | 523M | int group = 0; |
534 | | |
535 | 523M | if (gimg->size_reduction > 0) { |
536 | 16.3M | int group_x = x >> gimg->size_reduction; |
537 | 16.3M | int group_y = y >> gimg->size_reduction; |
538 | 16.3M | int g0 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 1); |
539 | 16.3M | int g1 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2); |
540 | 16.3M | group = g0 << 8 | g1; |
541 | 16.3M | } |
542 | | |
543 | 523M | return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE]; |
544 | 523M | } |
545 | | |
546 | | static av_always_inline void color_cache_put(ImageContext *img, uint32_t c) |
547 | 318M | { |
548 | 318M | uint32_t cache_idx = (0x1E35A7BD * c) >> (32 - img->color_cache_bits); |
549 | 318M | img->color_cache[cache_idx] = c; |
550 | 318M | } |
551 | | |
552 | | static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, |
553 | | int w, int h) |
554 | 93.4k | { |
555 | 93.4k | ImageContext *img; |
556 | 93.4k | HuffReader *hg; |
557 | 93.4k | int i, j, ret, x, y, width; |
558 | | |
559 | 93.4k | img = &s->image[role]; |
560 | 93.4k | img->role = role; |
561 | | |
562 | 93.4k | if (!img->frame) { |
563 | 50.7k | img->frame = av_frame_alloc(); |
564 | 50.7k | if (!img->frame) |
565 | 0 | return AVERROR(ENOMEM); |
566 | 50.7k | } |
567 | | |
568 | 93.4k | img->frame->format = AV_PIX_FMT_ARGB; |
569 | 93.4k | img->frame->width = w; |
570 | 93.4k | img->frame->height = h; |
571 | | |
572 | 93.4k | if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) { |
573 | 42.1k | ret = ff_thread_get_buffer(s->avctx, img->frame, 0); |
574 | 42.1k | } else |
575 | 51.2k | ret = av_frame_get_buffer(img->frame, 1); |
576 | 93.4k | if (ret < 0) |
577 | 21 | return ret; |
578 | | |
579 | 93.4k | if (get_bits1(&s->gb)) { |
580 | 12.0k | img->color_cache_bits = get_bits(&s->gb, 4); |
581 | 12.0k | if (img->color_cache_bits < 1 || img->color_cache_bits > 11) { |
582 | 856 | av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n", |
583 | 856 | img->color_cache_bits); |
584 | 856 | return AVERROR_INVALIDDATA; |
585 | 856 | } |
586 | 11.2k | img->color_cache = av_calloc(1 << img->color_cache_bits, |
587 | 11.2k | sizeof(*img->color_cache)); |
588 | 11.2k | if (!img->color_cache) |
589 | 0 | return AVERROR(ENOMEM); |
590 | 81.3k | } else { |
591 | 81.3k | img->color_cache_bits = 0; |
592 | 81.3k | } |
593 | | |
594 | 92.5k | img->nb_huffman_groups = 1; |
595 | 92.5k | if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) { |
596 | 5.69k | ret = decode_entropy_image(s); |
597 | 5.69k | if (ret < 0) |
598 | 4.95k | return ret; |
599 | 739 | img->nb_huffman_groups = s->nb_huffman_groups; |
600 | 739 | } |
601 | 87.6k | img->huffman_groups = av_calloc(img->nb_huffman_groups, |
602 | 87.6k | HUFFMAN_CODES_PER_META_CODE * |
603 | 87.6k | sizeof(*img->huffman_groups)); |
604 | 87.6k | if (!img->huffman_groups) |
605 | 0 | return AVERROR(ENOMEM); |
606 | | |
607 | 22.8M | for (i = 0; i < img->nb_huffman_groups; i++) { |
608 | 22.7M | hg = &img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE]; |
609 | 136M | for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) { |
610 | 113M | int alphabet_size = alphabet_sizes[j]; |
611 | 113M | if (!j && img->color_cache_bits > 0) |
612 | 76.8k | alphabet_size += 1 << img->color_cache_bits; |
613 | | |
614 | 113M | if (get_bits1(&s->gb)) { |
615 | 113M | read_huffman_code_simple(s, &hg[j]); |
616 | 113M | } else { |
617 | 15.7k | ret = read_huffman_code_normal(s, &hg[j], alphabet_size); |
618 | 15.7k | if (ret < 0) |
619 | 8.23k | return ret; |
620 | 15.7k | } |
621 | 113M | } |
622 | 22.7M | } |
623 | | |
624 | 79.4k | width = img->frame->width; |
625 | 79.4k | if (role == IMAGE_ROLE_ARGB) |
626 | 34.7k | width = s->reduced_width; |
627 | | |
628 | 79.4k | x = 0; y = 0; |
629 | 523M | while (y < img->frame->height) { |
630 | 523M | int v; |
631 | | |
632 | 523M | if (get_bits_left(&s->gb) < 0) |
633 | 7.11k | return AVERROR_INVALIDDATA; |
634 | | |
635 | 523M | hg = get_huffman_group(s, img, x, y); |
636 | 523M | v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb); |
637 | 523M | if (v < NUM_LITERAL_CODES) { |
638 | | /* literal pixel values */ |
639 | 523M | uint8_t *p = GET_PIXEL(img->frame, x, y); |
640 | 523M | p[2] = v; |
641 | 523M | p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED], &s->gb); |
642 | 523M | p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE], &s->gb); |
643 | 523M | p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb); |
644 | 523M | if (img->color_cache_bits) |
645 | 316M | color_cache_put(img, AV_RB32(p)); |
646 | 523M | x++; |
647 | 523M | if (x == width) { |
648 | 932k | x = 0; |
649 | 932k | y++; |
650 | 932k | } |
651 | 523M | } else if (v < NUM_LITERAL_CODES + NUM_LENGTH_CODES) { |
652 | | /* LZ77 backwards mapping */ |
653 | 40.9k | int prefix_code, length, distance, ref_x, ref_y; |
654 | | |
655 | | /* parse length and distance */ |
656 | 40.9k | prefix_code = v - NUM_LITERAL_CODES; |
657 | 40.9k | if (prefix_code < 4) { |
658 | 7.38k | length = prefix_code + 1; |
659 | 33.5k | } else { |
660 | 33.5k | int extra_bits = (prefix_code - 2) >> 1; |
661 | 33.5k | int offset = 2 + (prefix_code & 1) << extra_bits; |
662 | 33.5k | length = offset + get_bits(&s->gb, extra_bits) + 1; |
663 | 33.5k | } |
664 | 40.9k | prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb); |
665 | 40.9k | if (prefix_code > 39U) { |
666 | 90 | av_log(s->avctx, AV_LOG_ERROR, |
667 | 90 | "distance prefix code too large: %d\n", prefix_code); |
668 | 90 | return AVERROR_INVALIDDATA; |
669 | 90 | } |
670 | 40.8k | if (prefix_code < 4) { |
671 | 19.1k | distance = prefix_code + 1; |
672 | 21.6k | } else { |
673 | 21.6k | int extra_bits = prefix_code - 2 >> 1; |
674 | 21.6k | int offset = 2 + (prefix_code & 1) << extra_bits; |
675 | 21.6k | distance = offset + get_bits(&s->gb, extra_bits) + 1; |
676 | 21.6k | } |
677 | | |
678 | | /* find reference location */ |
679 | 40.8k | if (distance <= NUM_SHORT_DISTANCES) { |
680 | 28.1k | int xi = lz77_distance_offsets[distance - 1][0]; |
681 | 28.1k | int yi = lz77_distance_offsets[distance - 1][1]; |
682 | 28.1k | distance = FFMAX(1, xi + yi * width); |
683 | 28.1k | } else { |
684 | 12.6k | distance -= NUM_SHORT_DISTANCES; |
685 | 12.6k | } |
686 | 40.8k | ref_x = x; |
687 | 40.8k | ref_y = y; |
688 | 40.8k | if (distance <= x) { |
689 | 14.2k | ref_x -= distance; |
690 | 14.2k | distance = 0; |
691 | 26.5k | } else { |
692 | 26.5k | ref_x = 0; |
693 | 26.5k | distance -= x; |
694 | 26.5k | } |
695 | 181M | while (distance >= width) { |
696 | 181M | ref_y--; |
697 | 181M | distance -= width; |
698 | 181M | } |
699 | 40.8k | if (distance > 0) { |
700 | 23.1k | ref_x = width - distance; |
701 | 23.1k | ref_y--; |
702 | 23.1k | } |
703 | 40.8k | ref_x = FFMAX(0, ref_x); |
704 | 40.8k | ref_y = FFMAX(0, ref_y); |
705 | | |
706 | 40.8k | if (ref_y == y && ref_x >= x) |
707 | 529 | return AVERROR_INVALIDDATA; |
708 | | |
709 | | /* copy pixels |
710 | | * source and dest regions can overlap and wrap lines, so just |
711 | | * copy per-pixel */ |
712 | 2.01M | for (i = 0; i < length; i++) { |
713 | 1.97M | uint8_t *p_ref = GET_PIXEL(img->frame, ref_x, ref_y); |
714 | 1.97M | uint8_t *p = GET_PIXEL(img->frame, x, y); |
715 | | |
716 | 1.97M | AV_COPY32(p, p_ref); |
717 | 1.97M | if (img->color_cache_bits) |
718 | 1.71M | color_cache_put(img, AV_RB32(p)); |
719 | 1.97M | x++; |
720 | 1.97M | ref_x++; |
721 | 1.97M | if (x == width) { |
722 | 131k | x = 0; |
723 | 131k | y++; |
724 | 131k | } |
725 | 1.97M | if (ref_x == width) { |
726 | 131k | ref_x = 0; |
727 | 131k | ref_y++; |
728 | 131k | } |
729 | 1.97M | if (y == img->frame->height || ref_y == img->frame->height) |
730 | 248 | break; |
731 | 1.97M | } |
732 | 48.9k | } else { |
733 | | /* read from color cache */ |
734 | 48.9k | uint8_t *p = GET_PIXEL(img->frame, x, y); |
735 | 48.9k | int cache_idx = v - (NUM_LITERAL_CODES + NUM_LENGTH_CODES); |
736 | | |
737 | 48.9k | if (!img->color_cache_bits) { |
738 | 0 | av_log(s->avctx, AV_LOG_ERROR, "color cache not found\n"); |
739 | 0 | return AVERROR_INVALIDDATA; |
740 | 0 | } |
741 | 48.9k | if (cache_idx >= 1 << img->color_cache_bits) { |
742 | 0 | av_log(s->avctx, AV_LOG_ERROR, |
743 | 0 | "color cache index out-of-bounds\n"); |
744 | 0 | return AVERROR_INVALIDDATA; |
745 | 0 | } |
746 | 48.9k | AV_WB32(p, img->color_cache[cache_idx]); |
747 | 48.9k | x++; |
748 | 48.9k | if (x == width) { |
749 | 336 | x = 0; |
750 | 336 | y++; |
751 | 336 | } |
752 | 48.9k | } |
753 | 523M | } |
754 | | |
755 | 71.6k | return 0; |
756 | 79.4k | } |
757 | | |
758 | | /* PRED_MODE_BLACK */ |
759 | | static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
760 | | const uint8_t *p_t, const uint8_t *p_tr) |
761 | 95.3k | { |
762 | 95.3k | AV_WB32(p, 0xFF000000); |
763 | 95.3k | } |
764 | | |
765 | | /* PRED_MODE_L */ |
766 | | static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
767 | | const uint8_t *p_t, const uint8_t *p_tr) |
768 | 219k | { |
769 | 219k | AV_COPY32(p, p_l); |
770 | 219k | } |
771 | | |
772 | | /* PRED_MODE_T */ |
773 | | static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
774 | | const uint8_t *p_t, const uint8_t *p_tr) |
775 | 180k | { |
776 | 180k | AV_COPY32(p, p_t); |
777 | 180k | } |
778 | | |
779 | | /* PRED_MODE_TR */ |
780 | | static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
781 | | const uint8_t *p_t, const uint8_t *p_tr) |
782 | 25.9k | { |
783 | 25.9k | AV_COPY32(p, p_tr); |
784 | 25.9k | } |
785 | | |
786 | | /* PRED_MODE_TL */ |
787 | | static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
788 | | const uint8_t *p_t, const uint8_t *p_tr) |
789 | 100k | { |
790 | 100k | AV_COPY32(p, p_tl); |
791 | 100k | } |
792 | | |
793 | | /* PRED_MODE_AVG_T_AVG_L_TR */ |
794 | | static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
795 | | const uint8_t *p_t, const uint8_t *p_tr) |
796 | 19.3k | { |
797 | 19.3k | p[0] = p_t[0] + (p_l[0] + p_tr[0] >> 1) >> 1; |
798 | 19.3k | p[1] = p_t[1] + (p_l[1] + p_tr[1] >> 1) >> 1; |
799 | 19.3k | p[2] = p_t[2] + (p_l[2] + p_tr[2] >> 1) >> 1; |
800 | 19.3k | p[3] = p_t[3] + (p_l[3] + p_tr[3] >> 1) >> 1; |
801 | 19.3k | } |
802 | | |
803 | | /* PRED_MODE_AVG_L_TL */ |
804 | | static void inv_predict_6(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
805 | | const uint8_t *p_t, const uint8_t *p_tr) |
806 | 14.6k | { |
807 | 14.6k | p[0] = p_l[0] + p_tl[0] >> 1; |
808 | 14.6k | p[1] = p_l[1] + p_tl[1] >> 1; |
809 | 14.6k | p[2] = p_l[2] + p_tl[2] >> 1; |
810 | 14.6k | p[3] = p_l[3] + p_tl[3] >> 1; |
811 | 14.6k | } |
812 | | |
813 | | /* PRED_MODE_AVG_L_T */ |
814 | | static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
815 | | const uint8_t *p_t, const uint8_t *p_tr) |
816 | 19.6k | { |
817 | 19.6k | p[0] = p_l[0] + p_t[0] >> 1; |
818 | 19.6k | p[1] = p_l[1] + p_t[1] >> 1; |
819 | 19.6k | p[2] = p_l[2] + p_t[2] >> 1; |
820 | 19.6k | p[3] = p_l[3] + p_t[3] >> 1; |
821 | 19.6k | } |
822 | | |
823 | | /* PRED_MODE_AVG_TL_T */ |
824 | | static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
825 | | const uint8_t *p_t, const uint8_t *p_tr) |
826 | 18.0k | { |
827 | 18.0k | p[0] = p_tl[0] + p_t[0] >> 1; |
828 | 18.0k | p[1] = p_tl[1] + p_t[1] >> 1; |
829 | 18.0k | p[2] = p_tl[2] + p_t[2] >> 1; |
830 | 18.0k | p[3] = p_tl[3] + p_t[3] >> 1; |
831 | 18.0k | } |
832 | | |
833 | | /* PRED_MODE_AVG_T_TR */ |
834 | | static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
835 | | const uint8_t *p_t, const uint8_t *p_tr) |
836 | 43.8k | { |
837 | 43.8k | p[0] = p_t[0] + p_tr[0] >> 1; |
838 | 43.8k | p[1] = p_t[1] + p_tr[1] >> 1; |
839 | 43.8k | p[2] = p_t[2] + p_tr[2] >> 1; |
840 | 43.8k | p[3] = p_t[3] + p_tr[3] >> 1; |
841 | 43.8k | } |
842 | | |
843 | | /* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */ |
844 | | static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
845 | | const uint8_t *p_t, const uint8_t *p_tr) |
846 | 14.4k | { |
847 | 14.4k | p[0] = (p_l[0] + p_tl[0] >> 1) + (p_t[0] + p_tr[0] >> 1) >> 1; |
848 | 14.4k | p[1] = (p_l[1] + p_tl[1] >> 1) + (p_t[1] + p_tr[1] >> 1) >> 1; |
849 | 14.4k | p[2] = (p_l[2] + p_tl[2] >> 1) + (p_t[2] + p_tr[2] >> 1) >> 1; |
850 | 14.4k | p[3] = (p_l[3] + p_tl[3] >> 1) + (p_t[3] + p_tr[3] >> 1) >> 1; |
851 | 14.4k | } |
852 | | |
853 | | /* PRED_MODE_SELECT */ |
854 | | static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
855 | | const uint8_t *p_t, const uint8_t *p_tr) |
856 | 920k | { |
857 | 920k | int diff = (FFABS(p_l[0] - p_tl[0]) - FFABS(p_t[0] - p_tl[0])) + |
858 | 920k | (FFABS(p_l[1] - p_tl[1]) - FFABS(p_t[1] - p_tl[1])) + |
859 | 920k | (FFABS(p_l[2] - p_tl[2]) - FFABS(p_t[2] - p_tl[2])) + |
860 | 920k | (FFABS(p_l[3] - p_tl[3]) - FFABS(p_t[3] - p_tl[3])); |
861 | 920k | if (diff <= 0) |
862 | 920k | AV_COPY32(p, p_t); |
863 | 37.1k | else |
864 | 920k | AV_COPY32(p, p_l); |
865 | 920k | } |
866 | | |
867 | | /* PRED_MODE_ADD_SUBTRACT_FULL */ |
868 | | static void inv_predict_12(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
869 | | const uint8_t *p_t, const uint8_t *p_tr) |
870 | 475k | { |
871 | 475k | p[0] = av_clip_uint8(p_l[0] + p_t[0] - p_tl[0]); |
872 | 475k | p[1] = av_clip_uint8(p_l[1] + p_t[1] - p_tl[1]); |
873 | 475k | p[2] = av_clip_uint8(p_l[2] + p_t[2] - p_tl[2]); |
874 | 475k | p[3] = av_clip_uint8(p_l[3] + p_t[3] - p_tl[3]); |
875 | 475k | } |
876 | | |
877 | | static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c) |
878 | 2.69M | { |
879 | 2.69M | int d = a + b >> 1; |
880 | 2.69M | return av_clip_uint8(d + (d - c) / 2); |
881 | 2.69M | } |
882 | | |
883 | | /* PRED_MODE_ADD_SUBTRACT_HALF */ |
884 | | static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, |
885 | | const uint8_t *p_t, const uint8_t *p_tr) |
886 | 674k | { |
887 | 674k | p[0] = clamp_add_subtract_half(p_l[0], p_t[0], p_tl[0]); |
888 | 674k | p[1] = clamp_add_subtract_half(p_l[1], p_t[1], p_tl[1]); |
889 | 674k | p[2] = clamp_add_subtract_half(p_l[2], p_t[2], p_tl[2]); |
890 | 674k | p[3] = clamp_add_subtract_half(p_l[3], p_t[3], p_tl[3]); |
891 | 674k | } |
892 | | |
893 | | typedef void (*inv_predict_func)(uint8_t *p, const uint8_t *p_l, |
894 | | const uint8_t *p_tl, const uint8_t *p_t, |
895 | | const uint8_t *p_tr); |
896 | | |
897 | | static const inv_predict_func inverse_predict[14] = { |
898 | | inv_predict_0, inv_predict_1, inv_predict_2, inv_predict_3, |
899 | | inv_predict_4, inv_predict_5, inv_predict_6, inv_predict_7, |
900 | | inv_predict_8, inv_predict_9, inv_predict_10, inv_predict_11, |
901 | | inv_predict_12, inv_predict_13, |
902 | | }; |
903 | | |
904 | | static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y) |
905 | 2.82M | { |
906 | 2.82M | uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr; |
907 | 2.82M | uint8_t p[4]; |
908 | | |
909 | 2.82M | dec = GET_PIXEL(frame, x, y); |
910 | 2.82M | p_l = GET_PIXEL(frame, x - 1, y); |
911 | 2.82M | p_tl = GET_PIXEL(frame, x - 1, y - 1); |
912 | 2.82M | p_t = GET_PIXEL(frame, x, y - 1); |
913 | 2.82M | if (x == frame->width - 1) |
914 | 135k | p_tr = GET_PIXEL(frame, 0, y); |
915 | 2.68M | else |
916 | 2.68M | p_tr = GET_PIXEL(frame, x + 1, y - 1); |
917 | | |
918 | 2.82M | inverse_predict[m](p, p_l, p_tl, p_t, p_tr); |
919 | | |
920 | 2.82M | dec[0] += p[0]; |
921 | 2.82M | dec[1] += p[1]; |
922 | 2.82M | dec[2] += p[2]; |
923 | 2.82M | dec[3] += p[3]; |
924 | 2.82M | } |
925 | | |
926 | | static int apply_predictor_transform(WebPContext *s) |
927 | 30.8k | { |
928 | 30.8k | ImageContext *img = &s->image[IMAGE_ROLE_ARGB]; |
929 | 30.8k | ImageContext *pimg = &s->image[IMAGE_ROLE_PREDICTOR]; |
930 | 30.8k | int x, y; |
931 | | |
932 | 165k | for (y = 0; y < img->frame->height; y++) { |
933 | 2.95M | for (x = 0; x < s->reduced_width; x++) { |
934 | 2.82M | int tx = x >> pimg->size_reduction; |
935 | 2.82M | int ty = y >> pimg->size_reduction; |
936 | 2.82M | enum PredictionMode m = GET_PIXEL_COMP(pimg->frame, tx, ty, 2); |
937 | | |
938 | 2.82M | if (x == 0) { |
939 | 135k | if (y == 0) |
940 | 30.8k | m = PRED_MODE_BLACK; |
941 | 104k | else |
942 | 104k | m = PRED_MODE_T; |
943 | 2.68M | } else if (y == 0) |
944 | 196k | m = PRED_MODE_L; |
945 | | |
946 | 2.82M | if (m > 13) { |
947 | 210 | av_log(s->avctx, AV_LOG_ERROR, |
948 | 210 | "invalid predictor mode: %d\n", m); |
949 | 210 | return AVERROR_INVALIDDATA; |
950 | 210 | } |
951 | 2.82M | inverse_prediction(img->frame, m, x, y); |
952 | 2.82M | } |
953 | 135k | } |
954 | 30.6k | return 0; |
955 | 30.8k | } |
956 | | |
957 | | static av_always_inline uint8_t color_transform_delta(uint8_t color_pred, |
958 | | uint8_t color) |
959 | 7.16M | { |
960 | 7.16M | return (int)ff_u8_to_s8(color_pred) * ff_u8_to_s8(color) >> 5; |
961 | 7.16M | } |
962 | | |
963 | | static int apply_color_transform(WebPContext *s) |
964 | 613 | { |
965 | 613 | ImageContext *img, *cimg; |
966 | 613 | int x, y, cx, cy; |
967 | 613 | uint8_t *p, *cp; |
968 | | |
969 | 613 | img = &s->image[IMAGE_ROLE_ARGB]; |
970 | 613 | cimg = &s->image[IMAGE_ROLE_COLOR_TRANSFORM]; |
971 | | |
972 | 13.2k | for (y = 0; y < img->frame->height; y++) { |
973 | 2.40M | for (x = 0; x < s->reduced_width; x++) { |
974 | 2.38M | cx = x >> cimg->size_reduction; |
975 | 2.38M | cy = y >> cimg->size_reduction; |
976 | 2.38M | cp = GET_PIXEL(cimg->frame, cx, cy); |
977 | 2.38M | p = GET_PIXEL(img->frame, x, y); |
978 | | |
979 | 2.38M | p[1] += color_transform_delta(cp[3], p[2]); |
980 | 2.38M | p[3] += color_transform_delta(cp[2], p[2]) + |
981 | 2.38M | color_transform_delta(cp[1], p[1]); |
982 | 2.38M | } |
983 | 12.6k | } |
984 | 613 | return 0; |
985 | 613 | } |
986 | | |
987 | | static int apply_subtract_green_transform(WebPContext *s) |
988 | 283 | { |
989 | 283 | int x, y; |
990 | 283 | ImageContext *img = &s->image[IMAGE_ROLE_ARGB]; |
991 | | |
992 | 84.7k | for (y = 0; y < img->frame->height; y++) { |
993 | 326M | for (x = 0; x < s->reduced_width; x++) { |
994 | 326M | uint8_t *p = GET_PIXEL(img->frame, x, y); |
995 | 326M | p[1] += p[2]; |
996 | 326M | p[3] += p[2]; |
997 | 326M | } |
998 | 84.4k | } |
999 | 283 | return 0; |
1000 | 283 | } |
1001 | | |
1002 | | static int apply_color_indexing_transform(WebPContext *s) |
1003 | 919 | { |
1004 | 919 | ImageContext *img; |
1005 | 919 | ImageContext *pal; |
1006 | 919 | int i, x, y; |
1007 | 919 | uint8_t *p; |
1008 | | |
1009 | 919 | img = &s->image[IMAGE_ROLE_ARGB]; |
1010 | 919 | pal = &s->image[IMAGE_ROLE_COLOR_INDEXING]; |
1011 | | |
1012 | 919 | if (pal->size_reduction > 0) { // undo pixel packing |
1013 | 507 | GetBitContext gb_g; |
1014 | 507 | uint8_t *line; |
1015 | 507 | int pixel_bits = 8 >> pal->size_reduction; |
1016 | | |
1017 | 507 | line = av_malloc(img->frame->linesize[0] + AV_INPUT_BUFFER_PADDING_SIZE); |
1018 | 507 | if (!line) |
1019 | 0 | return AVERROR(ENOMEM); |
1020 | | |
1021 | 530k | for (y = 0; y < img->frame->height; y++) { |
1022 | 530k | p = GET_PIXEL(img->frame, 0, y); |
1023 | 530k | memcpy(line, p, img->frame->linesize[0]); |
1024 | 530k | init_get_bits(&gb_g, line, img->frame->linesize[0] * 8); |
1025 | 530k | skip_bits(&gb_g, 16); |
1026 | 530k | i = 0; |
1027 | 375M | for (x = 0; x < img->frame->width; x++) { |
1028 | 375M | p = GET_PIXEL(img->frame, x, y); |
1029 | 375M | p[2] = get_bits(&gb_g, pixel_bits); |
1030 | 375M | i++; |
1031 | 375M | if (i == 1 << pal->size_reduction) { |
1032 | 127M | skip_bits(&gb_g, 24); |
1033 | 127M | i = 0; |
1034 | 127M | } |
1035 | 375M | } |
1036 | 530k | } |
1037 | 507 | av_free(line); |
1038 | 507 | s->reduced_width = s->width; // we are back to full size |
1039 | 507 | } |
1040 | | |
1041 | | // switch to local palette if it's worth initializing it |
1042 | 919 | if (img->frame->height * img->frame->width > 300) { |
1043 | 491 | uint8_t palette[256 * 4]; |
1044 | 491 | const int size = pal->frame->width * 4; |
1045 | 491 | av_assert0(size <= 1024U); |
1046 | 491 | memcpy(palette, GET_PIXEL(pal->frame, 0, 0), size); // copy palette |
1047 | | // set extra entries to transparent black |
1048 | 491 | memset(palette + size, 0, 256 * 4 - size); |
1049 | 546k | for (y = 0; y < img->frame->height; y++) { |
1050 | 406M | for (x = 0; x < img->frame->width; x++) { |
1051 | 406M | p = GET_PIXEL(img->frame, x, y); |
1052 | 406M | i = p[2]; |
1053 | 406M | AV_COPY32(p, &palette[i * 4]); |
1054 | 406M | } |
1055 | 546k | } |
1056 | 491 | } else { |
1057 | 2.56k | for (y = 0; y < img->frame->height; y++) { |
1058 | 26.2k | for (x = 0; x < img->frame->width; x++) { |
1059 | 24.1k | p = GET_PIXEL(img->frame, x, y); |
1060 | 24.1k | i = p[2]; |
1061 | 24.1k | if (i >= pal->frame->width) { |
1062 | 1.12k | AV_WB32(p, 0x00000000); |
1063 | 23.0k | } else { |
1064 | 23.0k | const uint8_t *pi = GET_PIXEL(pal->frame, i, 0); |
1065 | 23.0k | AV_COPY32(p, pi); |
1066 | 23.0k | } |
1067 | 24.1k | } |
1068 | 2.13k | } |
1069 | 428 | } |
1070 | | |
1071 | 919 | return 0; |
1072 | 919 | } |
1073 | | |
1074 | | static void update_canvas_size(AVCodecContext *avctx, int w, int h) |
1075 | 66.5k | { |
1076 | 66.5k | WebPContext *s = avctx->priv_data; |
1077 | 66.5k | if (s->width && s->width != w) { |
1078 | 2.56k | av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n", |
1079 | 2.56k | s->width, w); |
1080 | 2.56k | } |
1081 | 66.5k | s->width = w; |
1082 | 66.5k | if (s->height && s->height != h) { |
1083 | 962 | av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n", |
1084 | 962 | s->height, h); |
1085 | 962 | } |
1086 | 66.5k | s->height = h; |
1087 | 66.5k | } |
1088 | | |
1089 | | static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, |
1090 | | int *got_frame, const uint8_t *data_start, |
1091 | | unsigned int data_size, int is_alpha_chunk) |
1092 | 51.8k | { |
1093 | 51.8k | WebPContext *s = avctx->priv_data; |
1094 | 51.8k | int w, h, ret, i, used; |
1095 | | |
1096 | 51.8k | if (!is_alpha_chunk) { |
1097 | 49.9k | s->lossless = 1; |
1098 | 49.9k | avctx->pix_fmt = AV_PIX_FMT_ARGB; |
1099 | 49.9k | } |
1100 | | |
1101 | 51.8k | ret = init_get_bits8(&s->gb, data_start, data_size); |
1102 | 51.8k | if (ret < 0) |
1103 | 0 | return ret; |
1104 | | |
1105 | 51.8k | if (!is_alpha_chunk) { |
1106 | 49.9k | if (get_bits(&s->gb, 8) != 0x2F) { |
1107 | 726 | av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n"); |
1108 | 726 | return AVERROR_INVALIDDATA; |
1109 | 726 | } |
1110 | | |
1111 | 49.2k | w = get_bits(&s->gb, 14) + 1; |
1112 | 49.2k | h = get_bits(&s->gb, 14) + 1; |
1113 | | |
1114 | 49.2k | update_canvas_size(avctx, w, h); |
1115 | | |
1116 | 49.2k | ret = ff_set_dimensions(avctx, s->width, s->height); |
1117 | 49.2k | if (ret < 0) |
1118 | 655 | return ret; |
1119 | | |
1120 | 48.6k | s->has_alpha = get_bits1(&s->gb); |
1121 | | |
1122 | 48.6k | if (get_bits(&s->gb, 3) != 0x0) { |
1123 | 984 | av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n"); |
1124 | 984 | return AVERROR_INVALIDDATA; |
1125 | 984 | } |
1126 | 48.6k | } else { |
1127 | 1.84k | if (!s->width || !s->height) |
1128 | 0 | return AVERROR_BUG; |
1129 | 1.84k | w = s->width; |
1130 | 1.84k | h = s->height; |
1131 | 1.84k | } |
1132 | | |
1133 | | /* parse transformations */ |
1134 | 49.4k | s->nb_transforms = 0; |
1135 | 49.4k | s->reduced_width = s->width; |
1136 | 49.4k | used = 0; |
1137 | 91.9k | while (get_bits1(&s->gb)) { |
1138 | 49.2k | enum TransformType transform = get_bits(&s->gb, 2); |
1139 | 49.2k | if (used & (1 << transform)) { |
1140 | 241 | av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n", |
1141 | 241 | transform); |
1142 | 241 | ret = AVERROR_INVALIDDATA; |
1143 | 241 | goto free_and_return; |
1144 | 241 | } |
1145 | 49.0k | used |= (1 << transform); |
1146 | 49.0k | s->transforms[s->nb_transforms++] = transform; |
1147 | 49.0k | switch (transform) { |
1148 | 33.0k | case PREDICTOR_TRANSFORM: |
1149 | 33.0k | ret = parse_transform_predictor(s); |
1150 | 33.0k | break; |
1151 | 2.29k | case COLOR_TRANSFORM: |
1152 | 2.29k | ret = parse_transform_color(s); |
1153 | 2.29k | break; |
1154 | 9.70k | case COLOR_INDEXING_TRANSFORM: |
1155 | 9.70k | ret = parse_transform_color_indexing(s); |
1156 | 9.70k | break; |
1157 | 49.0k | } |
1158 | 49.0k | if (ret < 0) |
1159 | 6.53k | goto free_and_return; |
1160 | 49.0k | } |
1161 | | |
1162 | | /* decode primary image */ |
1163 | 42.6k | s->image[IMAGE_ROLE_ARGB].frame = p; |
1164 | 42.6k | if (is_alpha_chunk) |
1165 | 510 | s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1; |
1166 | 42.6k | ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h); |
1167 | 42.6k | if (ret < 0) |
1168 | 10.3k | goto free_and_return; |
1169 | | |
1170 | | /* apply transformations */ |
1171 | 64.8k | for (i = s->nb_transforms - 1; i >= 0; i--) { |
1172 | 32.6k | switch (s->transforms[i]) { |
1173 | 30.8k | case PREDICTOR_TRANSFORM: |
1174 | 30.8k | ret = apply_predictor_transform(s); |
1175 | 30.8k | break; |
1176 | 613 | case COLOR_TRANSFORM: |
1177 | 613 | ret = apply_color_transform(s); |
1178 | 613 | break; |
1179 | 283 | case SUBTRACT_GREEN: |
1180 | 283 | ret = apply_subtract_green_transform(s); |
1181 | 283 | break; |
1182 | 919 | case COLOR_INDEXING_TRANSFORM: |
1183 | 919 | ret = apply_color_indexing_transform(s); |
1184 | 919 | break; |
1185 | 32.6k | } |
1186 | 32.6k | if (ret < 0) |
1187 | 210 | goto free_and_return; |
1188 | 32.6k | } |
1189 | | |
1190 | 32.1k | *got_frame = 1; |
1191 | 32.1k | p->pict_type = AV_PICTURE_TYPE_I; |
1192 | 32.1k | p->flags |= AV_FRAME_FLAG_KEY; |
1193 | 32.1k | p->flags |= AV_FRAME_FLAG_LOSSLESS; |
1194 | 32.1k | ret = data_size; |
1195 | | |
1196 | 49.4k | free_and_return: |
1197 | 296k | for (i = 0; i < IMAGE_ROLE_NB; i++) |
1198 | 247k | image_ctx_free(&s->image[i]); |
1199 | | |
1200 | 49.4k | return ret; |
1201 | 32.1k | } |
1202 | | |
1203 | | static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m) |
1204 | 1.79k | { |
1205 | 1.79k | int x, y, ls; |
1206 | 1.79k | uint8_t *dec; |
1207 | | |
1208 | 1.79k | ls = frame->linesize[3]; |
1209 | | |
1210 | | /* filter first row using horizontal filter */ |
1211 | 1.79k | dec = frame->data[3] + 1; |
1212 | 7.86M | for (x = 1; x < frame->width; x++, dec++) |
1213 | 7.86M | *dec += *(dec - 1); |
1214 | | |
1215 | | /* filter first column using vertical filter */ |
1216 | 1.79k | dec = frame->data[3] + ls; |
1217 | 5.01M | for (y = 1; y < frame->height; y++, dec += ls) |
1218 | 5.01M | *dec += *(dec - ls); |
1219 | | |
1220 | | /* filter the rest using the specified filter */ |
1221 | 1.79k | switch (m) { |
1222 | 659 | case ALPHA_FILTER_HORIZONTAL: |
1223 | 1.28M | for (y = 1; y < frame->height; y++) { |
1224 | 1.28M | dec = frame->data[3] + y * ls + 1; |
1225 | 147M | for (x = 1; x < frame->width; x++, dec++) |
1226 | 145M | *dec += *(dec - 1); |
1227 | 1.28M | } |
1228 | 659 | break; |
1229 | 631 | case ALPHA_FILTER_VERTICAL: |
1230 | 3.03M | for (y = 1; y < frame->height; y++) { |
1231 | 3.03M | dec = frame->data[3] + y * ls + 1; |
1232 | 77.1M | for (x = 1; x < frame->width; x++, dec++) |
1233 | 74.0M | *dec += *(dec - ls); |
1234 | 3.03M | } |
1235 | 631 | break; |
1236 | 504 | case ALPHA_FILTER_GRADIENT: |
1237 | 690k | for (y = 1; y < frame->height; y++) { |
1238 | 689k | dec = frame->data[3] + y * ls + 1; |
1239 | 224M | for (x = 1; x < frame->width; x++, dec++) |
1240 | 223M | dec[0] += av_clip_uint8(*(dec - 1) + *(dec - ls) - *(dec - ls - 1)); |
1241 | 689k | } |
1242 | 504 | break; |
1243 | 1.79k | } |
1244 | 1.79k | } |
1245 | | |
1246 | | static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p, |
1247 | | const uint8_t *data_start, |
1248 | | unsigned int data_size) |
1249 | 3.43k | { |
1250 | 3.43k | WebPContext *s = avctx->priv_data; |
1251 | 3.43k | int x, y, ret; |
1252 | | |
1253 | 3.43k | if (s->alpha_compression == ALPHA_COMPRESSION_NONE) { |
1254 | 1.59k | GetByteContext gb; |
1255 | | |
1256 | 1.59k | bytestream2_init(&gb, data_start, data_size); |
1257 | 4.55M | for (y = 0; y < s->height; y++) |
1258 | 4.55M | bytestream2_get_buffer(&gb, p->data[3] + p->linesize[3] * y, |
1259 | 4.55M | s->width); |
1260 | 1.84k | } else if (s->alpha_compression == ALPHA_COMPRESSION_VP8L) { |
1261 | 1.84k | uint8_t *ap, *pp; |
1262 | 1.84k | int alpha_got_frame = 0; |
1263 | | |
1264 | 1.84k | s->alpha_frame = av_frame_alloc(); |
1265 | 1.84k | if (!s->alpha_frame) |
1266 | 0 | return AVERROR(ENOMEM); |
1267 | | |
1268 | 1.84k | ret = vp8_lossless_decode_frame(avctx, s->alpha_frame, &alpha_got_frame, |
1269 | 1.84k | data_start, data_size, 1); |
1270 | 1.84k | if (ret < 0) { |
1271 | 1.56k | av_frame_free(&s->alpha_frame); |
1272 | 1.56k | return ret; |
1273 | 1.56k | } |
1274 | 277 | if (!alpha_got_frame) { |
1275 | 0 | av_frame_free(&s->alpha_frame); |
1276 | 0 | return AVERROR_INVALIDDATA; |
1277 | 0 | } |
1278 | | |
1279 | | /* copy green component of alpha image to alpha plane of primary image */ |
1280 | 516k | for (y = 0; y < s->height; y++) { |
1281 | 516k | ap = GET_PIXEL(s->alpha_frame, 0, y) + 2; |
1282 | 516k | pp = p->data[3] + p->linesize[3] * y; |
1283 | 238M | for (x = 0; x < s->width; x++) { |
1284 | 237M | *pp = *ap; |
1285 | 237M | pp++; |
1286 | 237M | ap += 4; |
1287 | 237M | } |
1288 | 516k | } |
1289 | 277 | av_frame_free(&s->alpha_frame); |
1290 | 277 | } |
1291 | | |
1292 | | /* apply alpha filtering */ |
1293 | 1.87k | if (s->alpha_filter) |
1294 | 1.79k | alpha_inverse_prediction(p, s->alpha_filter); |
1295 | | |
1296 | 1.87k | return 0; |
1297 | 3.43k | } |
1298 | | |
1299 | | static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, |
1300 | | int *got_frame, uint8_t *data_start, |
1301 | | unsigned int data_size) |
1302 | 37.4k | { |
1303 | 37.4k | WebPContext *s = avctx->priv_data; |
1304 | 37.4k | int ret; |
1305 | | |
1306 | 37.4k | if (!s->initialized) { |
1307 | 3.10k | ff_vp8_decode_init(avctx); |
1308 | 3.10k | s->initialized = 1; |
1309 | 3.10k | s->v.actually_webp = 1; |
1310 | 3.10k | } |
1311 | 37.4k | avctx->pix_fmt = s->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; |
1312 | 37.4k | s->lossless = 0; |
1313 | | |
1314 | 37.4k | if (data_size > INT_MAX) { |
1315 | 0 | av_log(avctx, AV_LOG_ERROR, "unsupported chunk size\n"); |
1316 | 0 | return AVERROR_PATCHWELCOME; |
1317 | 0 | } |
1318 | | |
1319 | 37.4k | av_packet_unref(s->pkt); |
1320 | 37.4k | s->pkt->data = data_start; |
1321 | 37.4k | s->pkt->size = data_size; |
1322 | | |
1323 | 37.4k | ret = ff_vp8_decode_frame(avctx, p, got_frame, s->pkt); |
1324 | 37.4k | if (ret < 0) |
1325 | 16.6k | return ret; |
1326 | | |
1327 | 20.8k | if (!*got_frame) |
1328 | 3.57k | return AVERROR_INVALIDDATA; |
1329 | | |
1330 | 17.2k | update_canvas_size(avctx, avctx->width, avctx->height); |
1331 | | |
1332 | 17.2k | if (s->has_alpha) { |
1333 | 3.43k | ret = vp8_lossy_decode_alpha(avctx, p, s->alpha_data, |
1334 | 3.43k | s->alpha_data_size); |
1335 | 3.43k | if (ret < 0) |
1336 | 1.56k | return ret; |
1337 | 3.43k | } |
1338 | 15.6k | return ret; |
1339 | 17.2k | } |
1340 | | |
1341 | | static int webp_decode_frame(AVCodecContext *avctx, AVFrame *p, |
1342 | | int *got_frame, AVPacket *avpkt) |
1343 | 149k | { |
1344 | 149k | WebPContext *s = avctx->priv_data; |
1345 | 149k | GetByteContext gb; |
1346 | 149k | int ret; |
1347 | 149k | uint32_t chunk_type, chunk_size; |
1348 | 149k | int vp8x_flags = 0; |
1349 | | |
1350 | 149k | s->avctx = avctx; |
1351 | 149k | s->width = 0; |
1352 | 149k | s->height = 0; |
1353 | 149k | *got_frame = 0; |
1354 | 149k | s->has_alpha = 0; |
1355 | 149k | s->has_exif = 0; |
1356 | 149k | s->has_iccp = 0; |
1357 | 149k | bytestream2_init(&gb, avpkt->data, avpkt->size); |
1358 | | |
1359 | 149k | if (bytestream2_get_bytes_left(&gb) < 12) |
1360 | 13.0k | return AVERROR_INVALIDDATA; |
1361 | | |
1362 | 136k | if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) { |
1363 | 6.37k | av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); |
1364 | 6.37k | return AVERROR_INVALIDDATA; |
1365 | 6.37k | } |
1366 | | |
1367 | 130k | chunk_size = bytestream2_get_le32(&gb); |
1368 | 130k | if (bytestream2_get_bytes_left(&gb) < chunk_size) |
1369 | 5.46k | return AVERROR_INVALIDDATA; |
1370 | | |
1371 | 125k | if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) { |
1372 | 2.74k | av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n"); |
1373 | 2.74k | return AVERROR_INVALIDDATA; |
1374 | 2.74k | } |
1375 | | |
1376 | 252k | while (bytestream2_get_bytes_left(&gb) > 8) { |
1377 | 202k | char chunk_str[5] = { 0 }; |
1378 | | |
1379 | 202k | chunk_type = bytestream2_get_le32(&gb); |
1380 | 202k | chunk_size = bytestream2_get_le32(&gb); |
1381 | 202k | if (chunk_size == UINT32_MAX) |
1382 | 1.84k | return AVERROR_INVALIDDATA; |
1383 | 200k | chunk_size += chunk_size & 1; |
1384 | | |
1385 | 200k | if (bytestream2_get_bytes_left(&gb) < chunk_size) { |
1386 | | /* we seem to be running out of data, but it could also be that the |
1387 | | bitstream has trailing junk leading to bogus chunk_size. */ |
1388 | 29.1k | break; |
1389 | 29.1k | } |
1390 | | |
1391 | 171k | switch (chunk_type) { |
1392 | 37.7k | case MKTAG('V', 'P', '8', ' '): |
1393 | 37.7k | if (!*got_frame) { |
1394 | 37.4k | ret = vp8_lossy_decode_frame(avctx, p, got_frame, |
1395 | 37.4k | avpkt->data + bytestream2_tell(&gb), |
1396 | 37.4k | chunk_size); |
1397 | 37.4k | if (ret < 0) |
1398 | 21.7k | return ret; |
1399 | 37.4k | } |
1400 | 15.9k | bytestream2_skip(&gb, chunk_size); |
1401 | 15.9k | break; |
1402 | 50.2k | case MKTAG('V', 'P', '8', 'L'): |
1403 | 50.2k | if (!*got_frame) { |
1404 | 49.9k | ret = vp8_lossless_decode_frame(avctx, p, got_frame, |
1405 | 49.9k | avpkt->data + bytestream2_tell(&gb), |
1406 | 49.9k | chunk_size, 0); |
1407 | 49.9k | if (ret < 0) |
1408 | 18.0k | return ret; |
1409 | 31.8k | #if FF_API_CODEC_PROPS |
1410 | 31.8k | FF_DISABLE_DEPRECATION_WARNINGS |
1411 | 31.8k | avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS; |
1412 | 31.8k | FF_ENABLE_DEPRECATION_WARNINGS |
1413 | 31.8k | #endif |
1414 | 31.8k | } |
1415 | 32.1k | bytestream2_skip(&gb, chunk_size); |
1416 | 32.1k | break; |
1417 | 6.01k | case MKTAG('V', 'P', '8', 'X'): |
1418 | 6.01k | if (s->width || s->height || *got_frame) { |
1419 | 217 | av_log(avctx, AV_LOG_ERROR, "Canvas dimensions are already set\n"); |
1420 | 217 | return AVERROR_INVALIDDATA; |
1421 | 217 | } |
1422 | 5.79k | vp8x_flags = bytestream2_get_byte(&gb); |
1423 | 5.79k | bytestream2_skip(&gb, 3); |
1424 | 5.79k | s->width = bytestream2_get_le24(&gb) + 1; |
1425 | 5.79k | s->height = bytestream2_get_le24(&gb) + 1; |
1426 | 5.79k | ret = av_image_check_size(s->width, s->height, 0, avctx); |
1427 | 5.79k | if (ret < 0) |
1428 | 1.05k | return ret; |
1429 | 4.73k | break; |
1430 | 5.71k | case MKTAG('A', 'L', 'P', 'H'): { |
1431 | 5.71k | int alpha_header, filter_m, compression; |
1432 | | |
1433 | 5.71k | if (!(vp8x_flags & VP8X_FLAG_ALPHA)) { |
1434 | 4.74k | av_log(avctx, AV_LOG_WARNING, |
1435 | 4.74k | "ALPHA chunk present, but alpha bit not set in the " |
1436 | 4.74k | "VP8X header\n"); |
1437 | 4.74k | } |
1438 | 5.71k | if (chunk_size == 0) { |
1439 | 211 | av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n"); |
1440 | 211 | return AVERROR_INVALIDDATA; |
1441 | 211 | } |
1442 | 5.50k | alpha_header = bytestream2_get_byte(&gb); |
1443 | 5.50k | s->alpha_data = avpkt->data + bytestream2_tell(&gb); |
1444 | 5.50k | s->alpha_data_size = chunk_size - 1; |
1445 | 5.50k | bytestream2_skip(&gb, s->alpha_data_size); |
1446 | | |
1447 | 5.50k | filter_m = (alpha_header >> 2) & 0x03; |
1448 | 5.50k | compression = alpha_header & 0x03; |
1449 | | |
1450 | 5.50k | if (compression > ALPHA_COMPRESSION_VP8L) { |
1451 | 361 | av_log(avctx, AV_LOG_VERBOSE, |
1452 | 361 | "skipping unsupported ALPHA chunk\n"); |
1453 | 5.14k | } else { |
1454 | 5.14k | s->has_alpha = 1; |
1455 | 5.14k | s->alpha_compression = compression; |
1456 | 5.14k | s->alpha_filter = filter_m; |
1457 | 5.14k | } |
1458 | | |
1459 | 5.50k | break; |
1460 | 5.71k | } |
1461 | 15.9k | case MKTAG('E', 'X', 'I', 'F'): { |
1462 | 15.9k | AVBufferRef *exif_buf = NULL; |
1463 | | |
1464 | 15.9k | if (s->has_exif) { |
1465 | 362 | av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n"); |
1466 | 362 | goto exif_end; |
1467 | 362 | } |
1468 | | |
1469 | 15.5k | if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA)) |
1470 | 15.2k | av_log(avctx, AV_LOG_WARNING, |
1471 | 15.2k | "EXIF chunk present, but Exif bit not set in the " |
1472 | 15.2k | "VP8X header\n"); |
1473 | | |
1474 | 15.5k | exif_buf = av_buffer_alloc(chunk_size); |
1475 | 15.5k | if (!exif_buf) { |
1476 | 0 | av_log(avctx, AV_LOG_WARNING, "unable to allocate EXIF buffer\n"); |
1477 | 0 | goto exif_end; |
1478 | 0 | } |
1479 | 15.5k | s->has_exif = 1; |
1480 | 15.5k | memcpy(exif_buf->data, gb.buffer, chunk_size); |
1481 | | |
1482 | 15.5k | ret = ff_decode_exif_attach_buffer(avctx, p, &exif_buf, AV_EXIF_TIFF_HEADER); |
1483 | 15.5k | if (ret < 0) |
1484 | 9.33k | av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n"); |
1485 | | |
1486 | 15.9k | exif_end: |
1487 | 15.9k | bytestream2_skip(&gb, chunk_size); |
1488 | 15.9k | break; |
1489 | 15.5k | } |
1490 | 3.71k | case MKTAG('I', 'C', 'C', 'P'): { |
1491 | 3.71k | AVFrameSideData *sd; |
1492 | | |
1493 | 3.71k | if (s->has_iccp) { |
1494 | 696 | av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra ICCP chunk\n"); |
1495 | 696 | bytestream2_skip(&gb, chunk_size); |
1496 | 696 | break; |
1497 | 696 | } |
1498 | 3.02k | if (!(vp8x_flags & VP8X_FLAG_ICC)) |
1499 | 2.78k | av_log(avctx, AV_LOG_WARNING, |
1500 | 2.78k | "ICCP chunk present, but ICC Profile bit not set in the " |
1501 | 2.78k | "VP8X header\n"); |
1502 | | |
1503 | 3.02k | s->has_iccp = 1; |
1504 | | |
1505 | 3.02k | ret = ff_frame_new_side_data(avctx, p, AV_FRAME_DATA_ICC_PROFILE, chunk_size, &sd); |
1506 | 3.02k | if (ret < 0) |
1507 | 0 | return ret; |
1508 | | |
1509 | 3.02k | if (sd) { |
1510 | 3.02k | bytestream2_get_buffer(&gb, sd->data, chunk_size); |
1511 | 3.02k | } else { |
1512 | 0 | bytestream2_skip(&gb, chunk_size); |
1513 | 0 | } |
1514 | 3.02k | break; |
1515 | 3.02k | } |
1516 | 321 | case MKTAG('A', 'N', 'I', 'M'): |
1517 | 740 | case MKTAG('A', 'N', 'M', 'F'): |
1518 | 1.11k | case MKTAG('X', 'M', 'P', ' '): |
1519 | 1.11k | AV_WL32(chunk_str, chunk_type); |
1520 | 1.11k | av_log(avctx, AV_LOG_WARNING, "skipping unsupported chunk: %s\n", |
1521 | 1.11k | chunk_str); |
1522 | 1.11k | bytestream2_skip(&gb, chunk_size); |
1523 | 1.11k | break; |
1524 | 50.7k | default: |
1525 | 50.7k | AV_WL32(chunk_str, chunk_type); |
1526 | 50.7k | av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n", |
1527 | 50.7k | chunk_str); |
1528 | 50.7k | bytestream2_skip(&gb, chunk_size); |
1529 | 50.7k | break; |
1530 | 171k | } |
1531 | 171k | } |
1532 | | |
1533 | 79.1k | if (!*got_frame) { |
1534 | 31.7k | av_log(avctx, AV_LOG_ERROR, "image data not found\n"); |
1535 | 31.7k | return AVERROR_INVALIDDATA; |
1536 | 31.7k | } |
1537 | | |
1538 | 47.3k | return avpkt->size; |
1539 | 79.1k | } |
1540 | | |
1541 | | static av_cold int webp_decode_init(AVCodecContext *avctx) |
1542 | 6.79k | { |
1543 | 6.79k | WebPContext *s = avctx->priv_data; |
1544 | | |
1545 | 6.79k | s->pkt = av_packet_alloc(); |
1546 | 6.79k | if (!s->pkt) |
1547 | 0 | return AVERROR(ENOMEM); |
1548 | | |
1549 | 6.79k | return 0; |
1550 | 6.79k | } |
1551 | | |
1552 | | static av_cold int webp_decode_close(AVCodecContext *avctx) |
1553 | 6.79k | { |
1554 | 6.79k | WebPContext *s = avctx->priv_data; |
1555 | | |
1556 | 6.79k | av_packet_free(&s->pkt); |
1557 | | |
1558 | 6.79k | if (s->initialized) |
1559 | 3.10k | return ff_vp8_decode_free(avctx); |
1560 | | |
1561 | 3.69k | return 0; |
1562 | 6.79k | } |
1563 | | |
1564 | | const FFCodec ff_webp_decoder = { |
1565 | | .p.name = "webp", |
1566 | | CODEC_LONG_NAME("WebP image"), |
1567 | | .p.type = AVMEDIA_TYPE_VIDEO, |
1568 | | .p.id = AV_CODEC_ID_WEBP, |
1569 | | .priv_data_size = sizeof(WebPContext), |
1570 | | .init = webp_decode_init, |
1571 | | FF_CODEC_DECODE_CB(webp_decode_frame), |
1572 | | .close = webp_decode_close, |
1573 | | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, |
1574 | | .caps_internal = FF_CODEC_CAP_ICC_PROFILES | |
1575 | | FF_CODEC_CAP_USES_PROGRESSFRAMES, |
1576 | | }; |