/src/ffmpeg/libavcodec/exr.c
Line | Count | Source |
1 | | /* |
2 | | * OpenEXR (.exr) image decoder |
3 | | * Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC |
4 | | * Copyright (c) 2009 Jimmy Christensen |
5 | | * |
6 | | * B44/B44A, Tile, UINT32 added by Jokyo Images support by CNC - French National Center for Cinema |
7 | | * |
8 | | * This file is part of FFmpeg. |
9 | | * |
10 | | * FFmpeg is free software; you can redistribute it and/or |
11 | | * modify it under the terms of the GNU Lesser General Public |
12 | | * License as published by the Free Software Foundation; either |
13 | | * version 2.1 of the License, or (at your option) any later version. |
14 | | * |
15 | | * FFmpeg is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | | * Lesser General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU Lesser General Public |
21 | | * License along with FFmpeg; if not, write to the Free Software |
22 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 | | */ |
24 | | |
25 | | /** |
26 | | * @file |
27 | | * OpenEXR decoder |
28 | | * @author Jimmy Christensen |
29 | | * |
30 | | * For more information on the OpenEXR format, visit: |
31 | | * http://openexr.com/ |
32 | | */ |
33 | | |
34 | | #include <float.h> |
35 | | #include <zlib.h> |
36 | | |
37 | | #include "libavutil/avassert.h" |
38 | | #include "libavutil/common.h" |
39 | | #include "libavutil/csp.h" |
40 | | #include "libavutil/imgutils.h" |
41 | | #include "libavutil/intfloat.h" |
42 | | #include "libavutil/avstring.h" |
43 | | #include "libavutil/mem.h" |
44 | | #include "libavutil/opt.h" |
45 | | #include "libavutil/float2half.h" |
46 | | #include "libavutil/half2float.h" |
47 | | |
48 | | #include "avcodec.h" |
49 | | #include "bytestream.h" |
50 | | |
51 | | #if HAVE_BIGENDIAN |
52 | | #include "bswapdsp.h" |
53 | | #endif |
54 | | |
55 | | #include "codec_internal.h" |
56 | | #include "decode.h" |
57 | | #include "exrdsp.h" |
58 | | #include "get_bits.h" |
59 | | #include "mathops.h" |
60 | | #include "thread.h" |
61 | | |
62 | | enum ExrCompr { |
63 | | EXR_RAW, |
64 | | EXR_RLE, |
65 | | EXR_ZIP1, |
66 | | EXR_ZIP16, |
67 | | EXR_PIZ, |
68 | | EXR_PXR24, |
69 | | EXR_B44, |
70 | | EXR_B44A, |
71 | | EXR_DWAA, |
72 | | EXR_DWAB, |
73 | | EXR_UNKN, |
74 | | }; |
75 | | |
76 | | enum ExrPixelType { |
77 | | EXR_UINT, |
78 | | EXR_HALF, |
79 | | EXR_FLOAT, |
80 | | EXR_UNKNOWN, |
81 | | }; |
82 | | |
83 | | enum ExrTileLevelMode { |
84 | | EXR_TILE_LEVEL_ONE, |
85 | | EXR_TILE_LEVEL_MIPMAP, |
86 | | EXR_TILE_LEVEL_RIPMAP, |
87 | | EXR_TILE_LEVEL_UNKNOWN, |
88 | | }; |
89 | | |
90 | | enum ExrTileLevelRound { |
91 | | EXR_TILE_ROUND_UP, |
92 | | EXR_TILE_ROUND_DOWN, |
93 | | EXR_TILE_ROUND_UNKNOWN, |
94 | | }; |
95 | | |
96 | | typedef struct HuffEntry { |
97 | | uint8_t len; |
98 | | uint16_t sym; |
99 | | uint32_t code; |
100 | | } HuffEntry; |
101 | | |
102 | | typedef struct EXRChannel { |
103 | | int xsub, ysub; |
104 | | enum ExrPixelType pixel_type; |
105 | | } EXRChannel; |
106 | | |
107 | | typedef struct EXRTileAttribute { |
108 | | int32_t xSize; |
109 | | int32_t ySize; |
110 | | enum ExrTileLevelMode level_mode; |
111 | | enum ExrTileLevelRound level_round; |
112 | | } EXRTileAttribute; |
113 | | |
114 | | typedef struct EXRThreadData { |
115 | | uint8_t *uncompressed_data; |
116 | | int uncompressed_size; |
117 | | |
118 | | uint8_t *tmp; |
119 | | int tmp_size; |
120 | | |
121 | | uint8_t *bitmap; |
122 | | uint16_t *lut; |
123 | | |
124 | | uint8_t *ac_data; |
125 | | unsigned ac_size; |
126 | | |
127 | | uint8_t *dc_data; |
128 | | unsigned dc_size; |
129 | | |
130 | | uint8_t *rle_data; |
131 | | unsigned rle_size; |
132 | | |
133 | | uint8_t *rle_raw_data; |
134 | | unsigned rle_raw_size; |
135 | | |
136 | | float block[3][64]; |
137 | | |
138 | | int ysize, xsize; |
139 | | |
140 | | int channel_line_size; |
141 | | |
142 | | int run_sym; |
143 | | HuffEntry *he; |
144 | | uint64_t *freq; |
145 | | VLC vlc; |
146 | | } EXRThreadData; |
147 | | |
148 | | typedef struct EXRContext { |
149 | | AVClass *class; |
150 | | AVFrame *picture; |
151 | | AVCodecContext *avctx; |
152 | | ExrDSPContext dsp; |
153 | | |
154 | | #if HAVE_BIGENDIAN |
155 | | BswapDSPContext bbdsp; |
156 | | #endif |
157 | | |
158 | | enum ExrCompr compression; |
159 | | enum ExrPixelType pixel_type; |
160 | | int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha |
161 | | const AVPixFmtDescriptor *desc; |
162 | | |
163 | | int w, h; |
164 | | uint32_t sar; |
165 | | int32_t xmax, xmin; |
166 | | int32_t ymax, ymin; |
167 | | uint32_t xdelta, ydelta; |
168 | | |
169 | | int scan_lines_per_block; |
170 | | |
171 | | EXRTileAttribute tile_attr; /* header data attribute of tile */ |
172 | | int is_tile; /* 0 if scanline, 1 if tile */ |
173 | | int is_multipart; |
174 | | int current_part; |
175 | | |
176 | | int is_luma;/* 1 if there is an Y plane */ |
177 | | |
178 | 706k | #define M(chr) (1<<chr - 'A') |
179 | | int has_channel; ///< combination of flags representing the channel codes A-Z |
180 | | |
181 | | GetByteContext gb; |
182 | | const uint8_t *buf; |
183 | | int buf_size; |
184 | | |
185 | | EXRChannel *channels; |
186 | | int nb_channels; |
187 | | int current_channel_offset; |
188 | | uint32_t chunk_count; |
189 | | |
190 | | EXRThreadData *thread_data; |
191 | | |
192 | | const char *layer; |
193 | | int selected_part; |
194 | | |
195 | | |
196 | | uint8_t *offset_table; |
197 | | |
198 | | #if FF_API_EXR_GAMMA |
199 | | enum AVColorTransferCharacteristic apply_trc_type; |
200 | | float gamma; |
201 | | uint16_t gamma_table[65536]; |
202 | | #endif |
203 | | |
204 | | Float2HalfTables f2h_tables; |
205 | | Half2FloatTables h2f_tables; |
206 | | } EXRContext; |
207 | | |
208 | | static int zip_uncompress(const EXRContext *s, const uint8_t *src, int compressed_size, |
209 | | int uncompressed_size, EXRThreadData *td) |
210 | 14.1k | { |
211 | 14.1k | unsigned long dest_len = uncompressed_size; |
212 | | |
213 | 14.1k | if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK || |
214 | 1.28k | dest_len != uncompressed_size) |
215 | 12.9k | return AVERROR_INVALIDDATA; |
216 | | |
217 | 1.21k | av_assert1(uncompressed_size % 2 == 0); |
218 | | |
219 | 1.21k | s->dsp.predictor(td->tmp, uncompressed_size); |
220 | 1.21k | s->dsp.reorder_pixels(td->uncompressed_data, td->tmp, uncompressed_size); |
221 | | |
222 | 1.21k | return 0; |
223 | 14.1k | } |
224 | | |
225 | | static int rle(uint8_t *dst, const uint8_t *src, |
226 | | int compressed_size, int uncompressed_size) |
227 | 471 | { |
228 | 471 | uint8_t *d = dst; |
229 | 471 | const int8_t *s = src; |
230 | 471 | int ssize = compressed_size; |
231 | 471 | int dsize = uncompressed_size; |
232 | 471 | uint8_t *dend = d + dsize; |
233 | 471 | int count; |
234 | | |
235 | 99.8k | while (ssize > 0) { |
236 | 99.6k | count = *s++; |
237 | | |
238 | 99.6k | if (count < 0) { |
239 | 14.3k | count = -count; |
240 | | |
241 | 14.3k | if ((dsize -= count) < 0 || |
242 | 14.2k | (ssize -= count + 1) < 0) |
243 | 200 | return AVERROR_INVALIDDATA; |
244 | | |
245 | 148k | while (count--) |
246 | 134k | *d++ = *s++; |
247 | 85.3k | } else { |
248 | 85.3k | count++; |
249 | | |
250 | 85.3k | if ((dsize -= count) < 0 || |
251 | 85.2k | (ssize -= 2) < 0) |
252 | 163 | return AVERROR_INVALIDDATA; |
253 | | |
254 | 2.52M | while (count--) |
255 | 2.43M | *d++ = *s; |
256 | | |
257 | 85.2k | s++; |
258 | 85.2k | } |
259 | 99.6k | } |
260 | | |
261 | 108 | if (dend != d) |
262 | 108 | return AVERROR_INVALIDDATA; |
263 | | |
264 | 0 | return 0; |
265 | 108 | } |
266 | | |
267 | | static int rle_uncompress(const EXRContext *ctx, const uint8_t *src, int compressed_size, |
268 | | int uncompressed_size, EXRThreadData *td) |
269 | 471 | { |
270 | 471 | rle(td->tmp, src, compressed_size, uncompressed_size); |
271 | | |
272 | 471 | av_assert1(uncompressed_size % 2 == 0); |
273 | | |
274 | 471 | ctx->dsp.predictor(td->tmp, uncompressed_size); |
275 | 471 | ctx->dsp.reorder_pixels(td->uncompressed_data, td->tmp, uncompressed_size); |
276 | | |
277 | 471 | return 0; |
278 | 471 | } |
279 | | |
280 | 886M | #define USHORT_RANGE (1 << 16) |
281 | 29.5k | #define BITMAP_SIZE (1 << 13) |
282 | | |
283 | | static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut) |
284 | 13.5k | { |
285 | 13.5k | int i, k = 0; |
286 | | |
287 | 886M | for (i = 0; i < USHORT_RANGE; i++) |
288 | 886M | if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) |
289 | 112k | lut[k++] = i; |
290 | | |
291 | 13.5k | i = k - 1; |
292 | | |
293 | 13.5k | memset(lut + k, 0, (USHORT_RANGE - k) * 2); |
294 | | |
295 | 13.5k | return i; |
296 | 13.5k | } |
297 | | |
298 | | static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize) |
299 | 3.89k | { |
300 | 3.89k | int i; |
301 | | |
302 | 4.64G | for (i = 0; i < dsize; ++i) |
303 | 4.64G | dst[i] = lut[dst[i]]; |
304 | 3.89k | } |
305 | | |
306 | 1.35G | #define HUF_ENCBITS 16 // literal (value) bit length |
307 | 1.35G | #define HUF_ENCSIZE ((1 << HUF_ENCBITS) + 1) // encoding table size |
308 | | |
309 | | static void huf_canonical_code_table(uint64_t *freq) |
310 | 10.3k | { |
311 | 10.3k | uint64_t c, n[59] = { 0 }; |
312 | 10.3k | int i; |
313 | | |
314 | 675M | for (i = 0; i < HUF_ENCSIZE; i++) |
315 | 675M | n[freq[i]] += 1; |
316 | | |
317 | 10.3k | c = 0; |
318 | 607k | for (i = 58; i > 0; --i) { |
319 | 597k | uint64_t nc = ((c + n[i]) >> 1); |
320 | 597k | n[i] = c; |
321 | 597k | c = nc; |
322 | 597k | } |
323 | | |
324 | 675M | for (i = 0; i < HUF_ENCSIZE; ++i) { |
325 | 675M | int l = freq[i]; |
326 | | |
327 | 675M | if (l > 0) |
328 | 90.7k | freq[i] = l | (n[l]++ << 6); |
329 | 675M | } |
330 | 10.3k | } |
331 | | |
332 | 7.37M | #define SHORT_ZEROCODE_RUN 59 |
333 | 7.33M | #define LONG_ZEROCODE_RUN 63 |
334 | 67.3k | #define SHORTEST_LONG_RUN (2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN) |
335 | | #define LONGEST_LONG_RUN (255 + SHORTEST_LONG_RUN) |
336 | | |
337 | | static int huf_unpack_enc_table(GetByteContext *gb, |
338 | | int32_t im, int32_t iM, uint64_t *freq) |
339 | 11.9k | { |
340 | 11.9k | GetBitContext gbit; |
341 | 11.9k | int ret = init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb)); |
342 | 11.9k | if (ret < 0) |
343 | 0 | return ret; |
344 | | |
345 | 7.27M | for (; im <= iM; im++) { |
346 | 7.26M | int l; |
347 | 7.26M | if (get_bits_left(&gbit) < 6) |
348 | 771 | return AVERROR_INVALIDDATA; |
349 | 7.26M | l = freq[im] = get_bits(&gbit, 6); |
350 | | |
351 | 7.26M | if (l == LONG_ZEROCODE_RUN) { |
352 | 67.3k | int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN; |
353 | | |
354 | 67.3k | if (im + zerun > iM + 1) |
355 | 525 | return AVERROR_INVALIDDATA; |
356 | | |
357 | 16.5M | while (zerun--) |
358 | 16.4M | freq[im++] = 0; |
359 | | |
360 | 66.8k | im--; |
361 | 7.20M | } else if (l >= SHORT_ZEROCODE_RUN) { |
362 | 108k | int zerun = l - SHORT_ZEROCODE_RUN + 2; |
363 | | |
364 | 108k | if (im + zerun > iM + 1) |
365 | 312 | return AVERROR_INVALIDDATA; |
366 | | |
367 | 604k | while (zerun--) |
368 | 496k | freq[im++] = 0; |
369 | | |
370 | 108k | im--; |
371 | 108k | } |
372 | 7.26M | } |
373 | | |
374 | 10.3k | bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8); |
375 | 10.3k | huf_canonical_code_table(freq); |
376 | | |
377 | 10.3k | return 0; |
378 | 11.9k | } |
379 | | |
380 | | static int huf_build_dec_table(const EXRContext *s, |
381 | | EXRThreadData *td, int im, int iM) |
382 | 8.75k | { |
383 | 8.75k | int j = 0; |
384 | | |
385 | 8.75k | td->run_sym = -1; |
386 | 158k | for (int i = im; i < iM; i++) { |
387 | 150k | td->he[j].sym = i; |
388 | 150k | td->he[j].len = td->freq[i] & 63; |
389 | 150k | td->he[j].code = td->freq[i] >> 6; |
390 | 150k | if (td->he[j].len > 32) { |
391 | 578 | avpriv_request_sample(s->avctx, "Too big code length"); |
392 | 578 | return AVERROR_PATCHWELCOME; |
393 | 578 | } |
394 | 149k | if (td->he[j].len > 0) |
395 | 59.6k | j++; |
396 | 90.3k | else |
397 | 90.3k | td->run_sym = i; |
398 | 149k | } |
399 | | |
400 | 8.17k | if (im > 0) |
401 | 1.19k | td->run_sym = 0; |
402 | 6.97k | else if (iM < 65535) |
403 | 6.97k | td->run_sym = 65535; |
404 | | |
405 | 8.17k | if (td->run_sym == -1) { |
406 | 0 | avpriv_request_sample(s->avctx, "No place for run symbol"); |
407 | 0 | return AVERROR_PATCHWELCOME; |
408 | 0 | } |
409 | | |
410 | 8.17k | td->he[j].sym = td->run_sym; |
411 | 8.17k | td->he[j].len = td->freq[iM] & 63; |
412 | 8.17k | if (td->he[j].len > 32) { |
413 | 235 | avpriv_request_sample(s->avctx, "Too big code length"); |
414 | 235 | return AVERROR_PATCHWELCOME; |
415 | 235 | } |
416 | 7.94k | td->he[j].code = td->freq[iM] >> 6; |
417 | 7.94k | j++; |
418 | | |
419 | 7.94k | ff_vlc_free(&td->vlc); |
420 | 7.94k | return ff_vlc_init_sparse(&td->vlc, 12, j, |
421 | 7.94k | &td->he[0].len, sizeof(td->he[0]), sizeof(td->he[0].len), |
422 | 7.94k | &td->he[0].code, sizeof(td->he[0]), sizeof(td->he[0].code), |
423 | 7.94k | &td->he[0].sym, sizeof(td->he[0]), sizeof(td->he[0].sym), 0); |
424 | 8.17k | } |
425 | | |
426 | | static int huf_decode(VLC *vlc, GetByteContext *gb, int nbits, int run_sym, |
427 | | int no, uint16_t *out) |
428 | 5.67k | { |
429 | 5.67k | GetBitContext gbit; |
430 | 5.67k | int oe = 0; |
431 | | |
432 | 5.67k | init_get_bits(&gbit, gb->buffer, nbits); |
433 | 105M | while (get_bits_left(&gbit) > 0 && oe < no) { |
434 | 105M | uint16_t x = get_vlc2(&gbit, vlc->table, 12, 3); |
435 | | |
436 | 105M | if (x == run_sym) { |
437 | 24.7k | int run = get_bits(&gbit, 8); |
438 | 24.7k | uint16_t fill; |
439 | | |
440 | 24.7k | if (oe == 0 || oe + run > no) |
441 | 1.77k | return AVERROR_INVALIDDATA; |
442 | | |
443 | 23.0k | fill = out[oe - 1]; |
444 | | |
445 | 2.13M | while (run-- > 0) |
446 | 2.11M | out[oe++] = fill; |
447 | 105M | } else { |
448 | 105M | out[oe++] = x; |
449 | 105M | } |
450 | 105M | } |
451 | | |
452 | 3.89k | return 0; |
453 | 5.67k | } |
454 | | |
455 | | static int huf_uncompress(const EXRContext *s, |
456 | | EXRThreadData *td, |
457 | | GetByteContext *gb, |
458 | | uint16_t *dst, int dst_size) |
459 | 13.5k | { |
460 | 13.5k | int32_t im, iM; |
461 | 13.5k | uint32_t nBits; |
462 | 13.5k | int ret; |
463 | | |
464 | 13.5k | im = bytestream2_get_le32(gb); |
465 | 13.5k | iM = bytestream2_get_le32(gb); |
466 | 13.5k | bytestream2_skip(gb, 4); |
467 | 13.5k | nBits = bytestream2_get_le32(gb); |
468 | 13.5k | if (im < 0 || im >= HUF_ENCSIZE || |
469 | 12.6k | iM < 0 || iM >= HUF_ENCSIZE) |
470 | 1.61k | return AVERROR_INVALIDDATA; |
471 | | |
472 | 11.9k | bytestream2_skip(gb, 4); |
473 | | |
474 | 11.9k | if (!td->freq) |
475 | 691 | td->freq = av_malloc_array(HUF_ENCSIZE, sizeof(*td->freq)); |
476 | 11.9k | if (!td->he) |
477 | 691 | td->he = av_calloc(HUF_ENCSIZE, sizeof(*td->he)); |
478 | 11.9k | if (!td->freq || !td->he) { |
479 | 0 | ret = AVERROR(ENOMEM); |
480 | 0 | return ret; |
481 | 0 | } |
482 | | |
483 | 11.9k | memset(td->freq, 0, sizeof(*td->freq) * HUF_ENCSIZE); |
484 | 11.9k | if ((ret = huf_unpack_enc_table(gb, im, iM, td->freq)) < 0) |
485 | 1.60k | return ret; |
486 | | |
487 | 10.3k | if (nBits > 8 * bytestream2_get_bytes_left(gb)) { |
488 | 1.55k | ret = AVERROR_INVALIDDATA; |
489 | 1.55k | return ret; |
490 | 1.55k | } |
491 | | |
492 | 8.75k | if ((ret = huf_build_dec_table(s, td, im, iM)) < 0) |
493 | 3.08k | return ret; |
494 | 5.67k | return huf_decode(&td->vlc, gb, nBits, td->run_sym, dst_size, dst); |
495 | 8.75k | } |
496 | | |
497 | | static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) |
498 | 5.92G | { |
499 | 5.92G | int16_t ls = l; |
500 | 5.92G | int16_t hs = h; |
501 | 5.92G | int hi = hs; |
502 | 5.92G | int ai = ls + (hi & 1) + (hi >> 1); |
503 | 5.92G | int16_t as = ai; |
504 | 5.92G | int16_t bs = ai - hi; |
505 | | |
506 | 5.92G | *a = as; |
507 | 5.92G | *b = bs; |
508 | 5.92G | } |
509 | | |
510 | 0 | #define NBITS 16 |
511 | 0 | #define A_OFFSET (1 << (NBITS - 1)) |
512 | 0 | #define MOD_MASK ((1 << NBITS) - 1) |
513 | | |
514 | | static inline void wdec16(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) |
515 | 0 | { |
516 | 0 | int m = l; |
517 | 0 | int d = h; |
518 | 0 | int bb = (m - (d >> 1)) & MOD_MASK; |
519 | 0 | int aa = (d + bb - A_OFFSET) & MOD_MASK; |
520 | 0 | *b = bb; |
521 | 0 | *a = aa; |
522 | 0 | } |
523 | | |
524 | | static void wav_decode(uint16_t *in, int nx, int ox, |
525 | | int ny, int oy, uint16_t mx) |
526 | 14.9k | { |
527 | 14.9k | int w14 = (mx < (1 << 14)); |
528 | 14.9k | int n = (nx > ny) ? ny : nx; |
529 | 14.9k | int p = 1; |
530 | 14.9k | int p2; |
531 | | |
532 | 69.2k | while (p <= n) |
533 | 54.2k | p <<= 1; |
534 | | |
535 | 14.9k | p >>= 1; |
536 | 14.9k | p2 = p; |
537 | 14.9k | p >>= 1; |
538 | | |
539 | 54.2k | while (p >= 1) { |
540 | 39.2k | uint16_t *py = in; |
541 | 39.2k | uint16_t *ey = in + oy * (ny - p2); |
542 | 39.2k | uint16_t i00, i01, i10, i11; |
543 | 39.2k | int oy1 = oy * p; |
544 | 39.2k | int oy2 = oy * p2; |
545 | 39.2k | int ox1 = ox * p; |
546 | 39.2k | int ox2 = ox * p2; |
547 | | |
548 | 343k | for (; py <= ey; py += oy2) { |
549 | 304k | uint16_t *px = py; |
550 | 304k | uint16_t *ex = py + ox * (nx - p2); |
551 | | |
552 | 1.47G | for (; px <= ex; px += ox2) { |
553 | 1.47G | uint16_t *p01 = px + ox1; |
554 | 1.47G | uint16_t *p10 = px + oy1; |
555 | 1.47G | uint16_t *p11 = p10 + ox1; |
556 | | |
557 | 1.47G | if (w14) { |
558 | 1.47G | wdec14(*px, *p10, &i00, &i10); |
559 | 1.47G | wdec14(*p01, *p11, &i01, &i11); |
560 | 1.47G | wdec14(i00, i01, px, p01); |
561 | 1.47G | wdec14(i10, i11, p10, p11); |
562 | 1.47G | } else { |
563 | 0 | wdec16(*px, *p10, &i00, &i10); |
564 | 0 | wdec16(*p01, *p11, &i01, &i11); |
565 | 0 | wdec16(i00, i01, px, p01); |
566 | 0 | wdec16(i10, i11, p10, p11); |
567 | 0 | } |
568 | 1.47G | } |
569 | | |
570 | 304k | if (nx & p) { |
571 | 68.2k | uint16_t *p10 = px + oy1; |
572 | | |
573 | 68.2k | if (w14) |
574 | 68.2k | wdec14(*px, *p10, &i00, p10); |
575 | 0 | else |
576 | 0 | wdec16(*px, *p10, &i00, p10); |
577 | | |
578 | 68.2k | *px = i00; |
579 | 68.2k | } |
580 | 304k | } |
581 | | |
582 | 39.2k | if (ny & p) { |
583 | 516 | uint16_t *px = py; |
584 | 516 | uint16_t *ex = py + ox * (nx - p2); |
585 | | |
586 | 16.2M | for (; px <= ex; px += ox2) { |
587 | 16.2M | uint16_t *p01 = px + ox1; |
588 | | |
589 | 16.2M | if (w14) |
590 | 16.2M | wdec14(*px, *p01, &i00, p01); |
591 | 0 | else |
592 | 0 | wdec16(*px, *p01, &i00, p01); |
593 | | |
594 | 16.2M | *px = i00; |
595 | 16.2M | } |
596 | 516 | } |
597 | | |
598 | 39.2k | p2 = p; |
599 | 39.2k | p >>= 1; |
600 | 39.2k | } |
601 | 14.9k | } |
602 | | |
603 | | static int piz_uncompress(const EXRContext *s, const uint8_t *src, int ssize, |
604 | | int dsize, EXRThreadData *td) |
605 | 14.5k | { |
606 | 14.5k | GetByteContext gb; |
607 | 14.5k | uint16_t maxval, min_non_zero, max_non_zero; |
608 | 14.5k | uint16_t *ptr; |
609 | 14.5k | uint16_t *tmp = (uint16_t *)td->tmp; |
610 | 14.5k | uint16_t *out; |
611 | 14.5k | uint16_t *in; |
612 | 14.5k | int ret, i, j; |
613 | 14.5k | int pixel_half_size;/* 1 for half, 2 for float and uint32 */ |
614 | 14.5k | EXRChannel *channel; |
615 | 14.5k | int tmp_offset; |
616 | | |
617 | 14.5k | if (!td->bitmap) |
618 | 873 | td->bitmap = av_malloc(BITMAP_SIZE); |
619 | 14.5k | if (!td->lut) |
620 | 873 | td->lut = av_malloc(1 << 17); |
621 | 14.5k | if (!td->bitmap || !td->lut) { |
622 | 0 | av_freep(&td->bitmap); |
623 | 0 | av_freep(&td->lut); |
624 | 0 | return AVERROR(ENOMEM); |
625 | 0 | } |
626 | | |
627 | 14.5k | bytestream2_init(&gb, src, ssize); |
628 | 14.5k | min_non_zero = bytestream2_get_le16(&gb); |
629 | 14.5k | max_non_zero = bytestream2_get_le16(&gb); |
630 | | |
631 | 14.5k | if (max_non_zero >= BITMAP_SIZE) |
632 | 313 | return AVERROR_INVALIDDATA; |
633 | | |
634 | 14.2k | memset(td->bitmap, 0, FFMIN(min_non_zero, BITMAP_SIZE)); |
635 | 14.2k | if (min_non_zero <= max_non_zero) |
636 | 13.1k | bytestream2_get_buffer(&gb, td->bitmap + min_non_zero, |
637 | 13.1k | max_non_zero - min_non_zero + 1); |
638 | 14.2k | memset(td->bitmap + max_non_zero + 1, 0, BITMAP_SIZE - max_non_zero - 1); |
639 | | |
640 | 14.2k | if (bytestream2_get_bytes_left(&gb) < 4) |
641 | 679 | return AVERROR_INVALIDDATA; |
642 | | |
643 | 13.5k | maxval = reverse_lut(td->bitmap, td->lut); |
644 | | |
645 | 13.5k | bytestream2_skip(&gb, 4); |
646 | 13.5k | ret = huf_uncompress(s, td, &gb, tmp, dsize / sizeof(uint16_t)); |
647 | 13.5k | if (ret) |
648 | 9.62k | return ret; |
649 | | |
650 | 3.89k | ptr = tmp; |
651 | 11.5k | for (i = 0; i < s->nb_channels; i++) { |
652 | 7.69k | channel = &s->channels[i]; |
653 | | |
654 | 7.69k | if (channel->pixel_type == EXR_HALF) |
655 | 421 | pixel_half_size = 1; |
656 | 7.27k | else |
657 | 7.27k | pixel_half_size = 2; |
658 | | |
659 | 22.6k | for (j = 0; j < pixel_half_size; j++) |
660 | 14.9k | wav_decode(ptr + j, td->xsize, pixel_half_size, td->ysize, |
661 | 14.9k | td->xsize * pixel_half_size, maxval); |
662 | 7.69k | ptr += td->xsize * td->ysize * pixel_half_size; |
663 | 7.69k | } |
664 | | |
665 | 3.89k | apply_lut(td->lut, tmp, dsize / sizeof(uint16_t)); |
666 | | |
667 | 3.89k | out = (uint16_t *)td->uncompressed_data; |
668 | 103k | for (i = 0; i < td->ysize; i++) { |
669 | 100k | tmp_offset = 0; |
670 | 300k | for (j = 0; j < s->nb_channels; j++) { |
671 | 200k | channel = &s->channels[j]; |
672 | 200k | if (channel->pixel_type == EXR_HALF) |
673 | 9.53k | pixel_half_size = 1; |
674 | 190k | else |
675 | 190k | pixel_half_size = 2; |
676 | | |
677 | 200k | in = tmp + tmp_offset * td->xsize * td->ysize + i * td->xsize * pixel_half_size; |
678 | 200k | tmp_offset += pixel_half_size; |
679 | | |
680 | | #if HAVE_BIGENDIAN |
681 | | s->bbdsp.bswap16_buf(out, in, td->xsize * pixel_half_size); |
682 | | #else |
683 | 200k | memcpy(out, in, td->xsize * 2 * pixel_half_size); |
684 | 200k | #endif |
685 | 200k | out += td->xsize * pixel_half_size; |
686 | 200k | } |
687 | 100k | } |
688 | | |
689 | 3.89k | return 0; |
690 | 13.5k | } |
691 | | |
692 | | static int pxr24_uncompress(const EXRContext *s, const uint8_t *src, |
693 | | int compressed_size, int uncompressed_size, |
694 | | EXRThreadData *td) |
695 | 611 | { |
696 | 611 | unsigned long dest_len, expected_len = 0; |
697 | 611 | const uint8_t *in = td->tmp; |
698 | 611 | uint8_t *out; |
699 | 611 | int c, i, j; |
700 | | |
701 | 2.39k | for (i = 0; i < s->nb_channels; i++) { |
702 | 1.78k | if (s->channels[i].pixel_type == EXR_FLOAT) { |
703 | 1.54k | expected_len += (td->xsize * td->ysize * 3);/* PRX 24 store float in 24 bit instead of 32 */ |
704 | 1.54k | } else if (s->channels[i].pixel_type == EXR_HALF) { |
705 | 29 | expected_len += (td->xsize * td->ysize * 2); |
706 | 208 | } else {//UINT 32 |
707 | 208 | expected_len += (td->xsize * td->ysize * 4); |
708 | 208 | } |
709 | 1.78k | } |
710 | | |
711 | 611 | dest_len = expected_len; |
712 | | |
713 | 611 | if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK) { |
714 | 384 | return AVERROR_INVALIDDATA; |
715 | 384 | } else if (dest_len != expected_len) { |
716 | 66 | return AVERROR_INVALIDDATA; |
717 | 66 | } |
718 | | |
719 | 161 | out = td->uncompressed_data; |
720 | 1.44k | for (i = 0; i < td->ysize; i++) |
721 | 5.15k | for (c = 0; c < s->nb_channels; c++) { |
722 | 3.86k | EXRChannel *channel = &s->channels[c]; |
723 | 3.86k | const uint8_t *ptr[4]; |
724 | 3.86k | uint32_t pixel = 0; |
725 | | |
726 | 3.86k | switch (channel->pixel_type) { |
727 | 3.86k | case EXR_FLOAT: |
728 | 3.86k | ptr[0] = in; |
729 | 3.86k | ptr[1] = ptr[0] + td->xsize; |
730 | 3.86k | ptr[2] = ptr[1] + td->xsize; |
731 | 3.86k | in = ptr[2] + td->xsize; |
732 | | |
733 | 50.2k | for (j = 0; j < td->xsize; ++j) { |
734 | 46.3k | uint32_t diff = ((unsigned)*(ptr[0]++) << 24) | |
735 | 46.3k | (*(ptr[1]++) << 16) | |
736 | 46.3k | (*(ptr[2]++) << 8); |
737 | 46.3k | pixel += diff; |
738 | 46.3k | bytestream_put_le32(&out, pixel); |
739 | 46.3k | } |
740 | 3.86k | break; |
741 | 0 | case EXR_HALF: |
742 | 0 | ptr[0] = in; |
743 | 0 | ptr[1] = ptr[0] + td->xsize; |
744 | 0 | in = ptr[1] + td->xsize; |
745 | 0 | for (j = 0; j < td->xsize; j++) { |
746 | 0 | uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++); |
747 | |
|
748 | 0 | pixel += diff; |
749 | 0 | bytestream_put_le16(&out, pixel); |
750 | 0 | } |
751 | 0 | break; |
752 | 0 | case EXR_UINT: |
753 | 0 | ptr[0] = in; |
754 | 0 | ptr[1] = ptr[0] + td->xsize; |
755 | 0 | ptr[2] = ptr[1] + td->xsize; |
756 | 0 | ptr[3] = ptr[2] + td->xsize; |
757 | 0 | in = ptr[3] + td->xsize; |
758 | |
|
759 | 0 | for (j = 0; j < td->xsize; ++j) { |
760 | 0 | uint32_t diff = ((uint32_t)*(ptr[0]++) << 24) | |
761 | 0 | (*(ptr[1]++) << 16) | |
762 | 0 | (*(ptr[2]++) << 8 ) | |
763 | 0 | (*(ptr[3]++)); |
764 | 0 | pixel += diff; |
765 | 0 | bytestream_put_le32(&out, pixel); |
766 | 0 | } |
767 | 0 | break; |
768 | 0 | default: |
769 | 0 | return AVERROR_INVALIDDATA; |
770 | 3.86k | } |
771 | 3.86k | } |
772 | | |
773 | 161 | return 0; |
774 | 161 | } |
775 | | |
776 | | static void unpack_14(const uint8_t b[14], uint16_t s[16]) |
777 | 269k | { |
778 | 269k | uint16_t shift = (b[ 2] >> 2) & 15; |
779 | 269k | uint16_t bias = (0x20 << shift); |
780 | 269k | int i; |
781 | | |
782 | 269k | s[ 0] = (b[0] << 8) | b[1]; |
783 | | |
784 | 269k | s[ 4] = s[ 0] + ((((b[ 2] << 4) | (b[ 3] >> 4)) & 0x3f) << shift) - bias; |
785 | 269k | s[ 8] = s[ 4] + ((((b[ 3] << 2) | (b[ 4] >> 6)) & 0x3f) << shift) - bias; |
786 | 269k | s[12] = s[ 8] + ((b[ 4] & 0x3f) << shift) - bias; |
787 | | |
788 | 269k | s[ 1] = s[ 0] + ((b[ 5] >> 2) << shift) - bias; |
789 | 269k | s[ 5] = s[ 4] + ((((b[ 5] << 4) | (b[ 6] >> 4)) & 0x3f) << shift) - bias; |
790 | 269k | s[ 9] = s[ 8] + ((((b[ 6] << 2) | (b[ 7] >> 6)) & 0x3f) << shift) - bias; |
791 | 269k | s[13] = s[12] + ((b[ 7] & 0x3f) << shift) - bias; |
792 | | |
793 | 269k | s[ 2] = s[ 1] + ((b[ 8] >> 2) << shift) - bias; |
794 | 269k | s[ 6] = s[ 5] + ((((b[ 8] << 4) | (b[ 9] >> 4)) & 0x3f) << shift) - bias; |
795 | 269k | s[10] = s[ 9] + ((((b[ 9] << 2) | (b[10] >> 6)) & 0x3f) << shift) - bias; |
796 | 269k | s[14] = s[13] + ((b[10] & 0x3f) << shift) - bias; |
797 | | |
798 | 269k | s[ 3] = s[ 2] + ((b[11] >> 2) << shift) - bias; |
799 | 269k | s[ 7] = s[ 6] + ((((b[11] << 4) | (b[12] >> 4)) & 0x3f) << shift) - bias; |
800 | 269k | s[11] = s[10] + ((((b[12] << 2) | (b[13] >> 6)) & 0x3f) << shift) - bias; |
801 | 269k | s[15] = s[14] + ((b[13] & 0x3f) << shift) - bias; |
802 | | |
803 | 4.58M | for (i = 0; i < 16; ++i) { |
804 | 4.31M | if (s[i] & 0x8000) |
805 | 3.11M | s[i] &= 0x7fff; |
806 | 1.19M | else |
807 | 1.19M | s[i] = ~s[i]; |
808 | 4.31M | } |
809 | 269k | } |
810 | | |
811 | | static void unpack_3(const uint8_t b[3], uint16_t s[16]) |
812 | 155k | { |
813 | 155k | int i; |
814 | | |
815 | 155k | s[0] = (b[0] << 8) | b[1]; |
816 | | |
817 | 155k | if (s[0] & 0x8000) |
818 | 155k | s[0] &= 0x7fff; |
819 | 382 | else |
820 | 382 | s[0] = ~s[0]; |
821 | | |
822 | 2.49M | for (i = 1; i < 16; i++) |
823 | 2.33M | s[i] = s[0]; |
824 | 155k | } |
825 | | |
826 | | |
827 | | static int b44_uncompress(const EXRContext *s, const uint8_t *src, int compressed_size, |
828 | 1.95k | int uncompressed_size, EXRThreadData *td) { |
829 | 1.95k | const int8_t *sr = src; |
830 | 1.95k | int stay_to_uncompress = compressed_size; |
831 | 1.95k | int nb_b44_block_w, nb_b44_block_h; |
832 | 1.95k | int index_tl_x, index_tl_y, index_out, index_tmp; |
833 | 1.95k | uint16_t tmp_buffer[16]; /* B44 use 4x4 half float pixel */ |
834 | 1.95k | int c, iY, iX, y, x; |
835 | 1.95k | int target_channel_offset = 0; |
836 | | |
837 | | /* calc B44 block count */ |
838 | 1.95k | nb_b44_block_w = td->xsize / 4; |
839 | 1.95k | if ((td->xsize % 4) != 0) |
840 | 817 | nb_b44_block_w++; |
841 | | |
842 | 1.95k | nb_b44_block_h = td->ysize / 4; |
843 | 1.95k | if ((td->ysize % 4) != 0) |
844 | 1.33k | nb_b44_block_h++; |
845 | | |
846 | 2.41k | for (c = 0; c < s->nb_channels; c++) { |
847 | 2.32k | if (s->channels[c].pixel_type == EXR_HALF) {/* B44 only compress half float data */ |
848 | 2.39k | for (iY = 0; iY < nb_b44_block_h; iY++) { |
849 | 427k | for (iX = 0; iX < nb_b44_block_w; iX++) {/* For each B44 block */ |
850 | 426k | if (stay_to_uncompress < 3) |
851 | 1.09k | return AVERROR_INVALIDDATA; |
852 | | |
853 | 425k | if (src[compressed_size - stay_to_uncompress + 2] == 0xfc) { /* B44A block */ |
854 | 155k | unpack_3(sr, tmp_buffer); |
855 | 155k | sr += 3; |
856 | 155k | stay_to_uncompress -= 3; |
857 | 269k | } else {/* B44 Block */ |
858 | 269k | if (stay_to_uncompress < 14) |
859 | 324 | return AVERROR_INVALIDDATA; |
860 | 269k | unpack_14(sr, tmp_buffer); |
861 | 269k | sr += 14; |
862 | 269k | stay_to_uncompress -= 14; |
863 | 269k | } |
864 | | |
865 | | /* copy data to uncompress buffer (B44 block can exceed target resolution)*/ |
866 | 425k | index_tl_x = iX * 4; |
867 | 425k | index_tl_y = iY * 4; |
868 | | |
869 | 1.46M | for (y = index_tl_y; y < FFMIN(index_tl_y + 4, td->ysize); y++) { |
870 | 5.21M | for (x = index_tl_x; x < FFMIN(index_tl_x + 4, td->xsize); x++) { |
871 | 4.17M | index_out = target_channel_offset * td->xsize + y * td->channel_line_size + 2 * x; |
872 | 4.17M | index_tmp = (y-index_tl_y) * 4 + (x-index_tl_x); |
873 | 4.17M | td->uncompressed_data[index_out] = tmp_buffer[index_tmp] & 0xff; |
874 | 4.17M | td->uncompressed_data[index_out + 1] = tmp_buffer[index_tmp] >> 8; |
875 | 4.17M | } |
876 | 1.04M | } |
877 | 425k | } |
878 | 2.28k | } |
879 | 101 | target_channel_offset += 2; |
880 | 806 | } else {/* Float or UINT 32 channel */ |
881 | 806 | if (stay_to_uncompress < td->ysize * td->xsize * 4) |
882 | 447 | return AVERROR_INVALIDDATA; |
883 | | |
884 | 2.56k | for (y = 0; y < td->ysize; y++) { |
885 | 2.20k | index_out = target_channel_offset * td->xsize + y * td->channel_line_size; |
886 | 2.20k | memcpy(&td->uncompressed_data[index_out], sr, td->xsize * 4); |
887 | 2.20k | sr += td->xsize * 4; |
888 | 2.20k | } |
889 | 359 | target_channel_offset += 4; |
890 | | |
891 | 359 | stay_to_uncompress -= td->ysize * td->xsize * 4; |
892 | 359 | } |
893 | 2.32k | } |
894 | | |
895 | 91 | return 0; |
896 | 1.95k | } |
897 | | |
898 | | static int ac_uncompress(const EXRContext *s, GetByteContext *gb, float *block) |
899 | 0 | { |
900 | 0 | int ret = 0, n = 1; |
901 | |
|
902 | 0 | while (n < 64) { |
903 | 0 | uint16_t val = bytestream2_get_ne16(gb); |
904 | |
|
905 | 0 | if (val == 0xff00) { |
906 | 0 | n = 64; |
907 | 0 | } else if ((val >> 8) == 0xff) { |
908 | 0 | n += val & 0xff; |
909 | 0 | } else { |
910 | 0 | ret = n; |
911 | 0 | block[ff_zigzag_direct[n]] = av_int2float(half2float(val, &s->h2f_tables)); |
912 | 0 | n++; |
913 | 0 | } |
914 | 0 | } |
915 | |
|
916 | 0 | return ret; |
917 | 0 | } |
918 | | |
919 | | static void idct_1d(float *blk, int step) |
920 | 0 | { |
921 | 0 | const float a = .5f * cosf( M_PI / 4.f); |
922 | 0 | const float b = .5f * cosf( M_PI / 16.f); |
923 | 0 | const float c = .5f * cosf( M_PI / 8.f); |
924 | 0 | const float d = .5f * cosf(3.f*M_PI / 16.f); |
925 | 0 | const float e = .5f * cosf(5.f*M_PI / 16.f); |
926 | 0 | const float f = .5f * cosf(3.f*M_PI / 8.f); |
927 | 0 | const float g = .5f * cosf(7.f*M_PI / 16.f); |
928 | |
|
929 | 0 | float alpha[4], beta[4], theta[4], gamma[4]; |
930 | |
|
931 | 0 | alpha[0] = c * blk[2 * step]; |
932 | 0 | alpha[1] = f * blk[2 * step]; |
933 | 0 | alpha[2] = c * blk[6 * step]; |
934 | 0 | alpha[3] = f * blk[6 * step]; |
935 | |
|
936 | 0 | beta[0] = b * blk[1 * step] + d * blk[3 * step] + e * blk[5 * step] + g * blk[7 * step]; |
937 | 0 | beta[1] = d * blk[1 * step] - g * blk[3 * step] - b * blk[5 * step] - e * blk[7 * step]; |
938 | 0 | beta[2] = e * blk[1 * step] - b * blk[3 * step] + g * blk[5 * step] + d * blk[7 * step]; |
939 | 0 | beta[3] = g * blk[1 * step] - e * blk[3 * step] + d * blk[5 * step] - b * blk[7 * step]; |
940 | |
|
941 | 0 | theta[0] = a * (blk[0 * step] + blk[4 * step]); |
942 | 0 | theta[3] = a * (blk[0 * step] - blk[4 * step]); |
943 | |
|
944 | 0 | theta[1] = alpha[0] + alpha[3]; |
945 | 0 | theta[2] = alpha[1] - alpha[2]; |
946 | |
|
947 | 0 | gamma[0] = theta[0] + theta[1]; |
948 | 0 | gamma[1] = theta[3] + theta[2]; |
949 | 0 | gamma[2] = theta[3] - theta[2]; |
950 | 0 | gamma[3] = theta[0] - theta[1]; |
951 | |
|
952 | 0 | blk[0 * step] = gamma[0] + beta[0]; |
953 | 0 | blk[1 * step] = gamma[1] + beta[1]; |
954 | 0 | blk[2 * step] = gamma[2] + beta[2]; |
955 | 0 | blk[3 * step] = gamma[3] + beta[3]; |
956 | |
|
957 | 0 | blk[4 * step] = gamma[3] - beta[3]; |
958 | 0 | blk[5 * step] = gamma[2] - beta[2]; |
959 | 0 | blk[6 * step] = gamma[1] - beta[1]; |
960 | 0 | blk[7 * step] = gamma[0] - beta[0]; |
961 | 0 | } |
962 | | |
963 | | static void dct_inverse(float *block) |
964 | 0 | { |
965 | 0 | for (int i = 0; i < 8; i++) |
966 | 0 | idct_1d(block + i, 8); |
967 | |
|
968 | 0 | for (int i = 0; i < 8; i++) { |
969 | 0 | idct_1d(block, 1); |
970 | 0 | block += 8; |
971 | 0 | } |
972 | 0 | } |
973 | | |
974 | | static void convert(float y, float u, float v, |
975 | | float *b, float *g, float *r) |
976 | 0 | { |
977 | 0 | *r = y + 1.5747f * v; |
978 | 0 | *g = y - 0.1873f * u - 0.4682f * v; |
979 | 0 | *b = y + 1.8556f * u; |
980 | 0 | } |
981 | | |
982 | | static float to_linear(float x, float scale) |
983 | 0 | { |
984 | 0 | float ax = fabsf(x); |
985 | |
|
986 | 0 | if (ax <= 1.f) { |
987 | 0 | return FFSIGN(x) * powf(ax, 2.2f * scale); |
988 | 0 | } else { |
989 | 0 | const float log_base = expf(2.2f * scale); |
990 | |
|
991 | 0 | return FFSIGN(x) * powf(log_base, ax - 1.f); |
992 | 0 | } |
993 | 0 | } |
994 | | |
995 | | static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compressed_size, |
996 | | int uncompressed_size, EXRThreadData *td) |
997 | 930 | { |
998 | 930 | int64_t version, lo_usize, lo_size; |
999 | 930 | int64_t ac_size, dc_size, rle_usize, rle_csize, rle_raw_size; |
1000 | 930 | int64_t ac_count, dc_count, ac_compression; |
1001 | 930 | const int dc_w = (td->xsize + 7) >> 3; |
1002 | 930 | const int dc_h = (td->ysize + 7) >> 3; |
1003 | 930 | GetByteContext gb, agb; |
1004 | 930 | int skip, ret; |
1005 | 930 | int have_rle = 0; |
1006 | | |
1007 | 930 | if (compressed_size <= 88) |
1008 | 478 | return AVERROR_INVALIDDATA; |
1009 | | |
1010 | 452 | version = AV_RL64(src + 0); |
1011 | 452 | if (version != 2) |
1012 | 452 | return AVERROR_INVALIDDATA; |
1013 | | |
1014 | 0 | if (s->nb_channels < 3) { |
1015 | 0 | avpriv_request_sample(s->avctx, "Gray DWA"); |
1016 | 0 | return AVERROR_PATCHWELCOME; |
1017 | 0 | } |
1018 | | |
1019 | 0 | lo_usize = AV_RL64(src + 8); |
1020 | 0 | lo_size = AV_RL64(src + 16); |
1021 | 0 | ac_size = AV_RL64(src + 24); |
1022 | 0 | dc_size = AV_RL64(src + 32); |
1023 | 0 | rle_csize = AV_RL64(src + 40); |
1024 | 0 | rle_usize = AV_RL64(src + 48); |
1025 | 0 | rle_raw_size = AV_RL64(src + 56); |
1026 | 0 | ac_count = AV_RL64(src + 64); |
1027 | 0 | dc_count = AV_RL64(src + 72); |
1028 | 0 | ac_compression = AV_RL64(src + 80); |
1029 | |
|
1030 | 0 | if ( compressed_size < (uint64_t)(lo_size | ac_size | dc_size | rle_csize) || compressed_size < 88LL + lo_size + ac_size + dc_size + rle_csize |
1031 | 0 | || ac_count > (uint64_t)INT_MAX/2 |
1032 | 0 | ) |
1033 | 0 | return AVERROR_INVALIDDATA; |
1034 | | |
1035 | 0 | if (ac_size <= 0) { |
1036 | 0 | avpriv_request_sample(s->avctx, "Zero ac_size"); |
1037 | 0 | return AVERROR_INVALIDDATA; |
1038 | 0 | } |
1039 | | |
1040 | 0 | if ((uint64_t)rle_raw_size > INT_MAX) { |
1041 | 0 | avpriv_request_sample(s->avctx, "Too big rle_raw_size"); |
1042 | 0 | return AVERROR_INVALIDDATA; |
1043 | 0 | } |
1044 | | |
1045 | 0 | if (td->xsize % 8 || td->ysize % 8) { |
1046 | 0 | avpriv_request_sample(s->avctx, "odd dimensions DWA"); |
1047 | 0 | } |
1048 | |
|
1049 | 0 | bytestream2_init(&gb, src + 88, compressed_size - 88); |
1050 | 0 | skip = bytestream2_get_le16(&gb); |
1051 | 0 | if (skip < 2) |
1052 | 0 | return AVERROR_INVALIDDATA; |
1053 | | |
1054 | 0 | bytestream2_skip(&gb, skip - 2); |
1055 | |
|
1056 | 0 | if (lo_size > 0) { |
1057 | 0 | if (lo_usize > uncompressed_size) |
1058 | 0 | return AVERROR_INVALIDDATA; |
1059 | 0 | bytestream2_skip(&gb, lo_size); |
1060 | 0 | } |
1061 | | |
1062 | 0 | if (ac_size > 0) { |
1063 | 0 | unsigned long dest_len; |
1064 | 0 | GetByteContext agb = gb; |
1065 | |
|
1066 | 0 | if (ac_count > 3LL * td->xsize * s->scan_lines_per_block) |
1067 | 0 | return AVERROR_INVALIDDATA; |
1068 | | |
1069 | 0 | dest_len = ac_count * 2LL; |
1070 | |
|
1071 | 0 | av_fast_padded_malloc(&td->ac_data, &td->ac_size, dest_len); |
1072 | 0 | if (!td->ac_data) |
1073 | 0 | return AVERROR(ENOMEM); |
1074 | | |
1075 | 0 | switch (ac_compression) { |
1076 | 0 | case 0: |
1077 | 0 | ret = huf_uncompress(s, td, &agb, (int16_t *)td->ac_data, ac_count); |
1078 | 0 | if (ret < 0) |
1079 | 0 | return ret; |
1080 | 0 | break; |
1081 | 0 | case 1: |
1082 | 0 | if (uncompress(td->ac_data, &dest_len, agb.buffer, ac_size) != Z_OK || |
1083 | 0 | dest_len != ac_count * 2LL) |
1084 | 0 | return AVERROR_INVALIDDATA; |
1085 | 0 | break; |
1086 | 0 | default: |
1087 | 0 | return AVERROR_INVALIDDATA; |
1088 | 0 | } |
1089 | | |
1090 | 0 | bytestream2_skip(&gb, ac_size); |
1091 | 0 | } |
1092 | | |
1093 | 0 | { |
1094 | 0 | unsigned long dest_len; |
1095 | 0 | GetByteContext agb = gb; |
1096 | |
|
1097 | 0 | if (dc_count != dc_w * dc_h * 3) |
1098 | 0 | return AVERROR_INVALIDDATA; |
1099 | | |
1100 | 0 | dest_len = dc_count * 2LL; |
1101 | |
|
1102 | 0 | av_fast_padded_malloc(&td->dc_data, &td->dc_size, FFALIGN(dest_len, 64) * 2); |
1103 | 0 | if (!td->dc_data) |
1104 | 0 | return AVERROR(ENOMEM); |
1105 | | |
1106 | 0 | if (uncompress(td->dc_data + FFALIGN(dest_len, 64), &dest_len, agb.buffer, dc_size) != Z_OK || |
1107 | 0 | (dest_len != dc_count * 2LL)) |
1108 | 0 | return AVERROR_INVALIDDATA; |
1109 | | |
1110 | 0 | s->dsp.predictor(td->dc_data + FFALIGN(dest_len, 64), dest_len); |
1111 | 0 | s->dsp.reorder_pixels(td->dc_data, td->dc_data + FFALIGN(dest_len, 64), dest_len); |
1112 | |
|
1113 | 0 | bytestream2_skip(&gb, dc_size); |
1114 | 0 | } |
1115 | | |
1116 | 0 | if (rle_raw_size > 0 && rle_csize > 0 && rle_usize > 0) { |
1117 | 0 | unsigned long dest_len = rle_usize; |
1118 | |
|
1119 | 0 | if (2LL * td->xsize * td->ysize > rle_raw_size) |
1120 | 0 | return AVERROR_INVALIDDATA; |
1121 | | |
1122 | 0 | av_fast_padded_malloc(&td->rle_data, &td->rle_size, rle_usize); |
1123 | 0 | if (!td->rle_data) |
1124 | 0 | return AVERROR(ENOMEM); |
1125 | | |
1126 | 0 | av_fast_padded_malloc(&td->rle_raw_data, &td->rle_raw_size, rle_raw_size); |
1127 | 0 | if (!td->rle_raw_data) |
1128 | 0 | return AVERROR(ENOMEM); |
1129 | | |
1130 | 0 | if (uncompress(td->rle_data, &dest_len, gb.buffer, rle_csize) != Z_OK || |
1131 | 0 | (dest_len != rle_usize)) |
1132 | 0 | return AVERROR_INVALIDDATA; |
1133 | | |
1134 | 0 | ret = rle(td->rle_raw_data, td->rle_data, rle_usize, rle_raw_size); |
1135 | 0 | if (ret < 0) |
1136 | 0 | return ret; |
1137 | 0 | bytestream2_skip(&gb, rle_csize); |
1138 | |
|
1139 | 0 | have_rle = 1; |
1140 | 0 | } |
1141 | | |
1142 | 0 | bytestream2_init(&agb, td->ac_data, ac_count * 2); |
1143 | |
|
1144 | 0 | for (int y = 0; y < td->ysize; y += 8) { |
1145 | 0 | for (int x = 0; x < td->xsize; x += 8) { |
1146 | 0 | const int o = s->nb_channels == 4; |
1147 | 0 | float *yb = td->block[0]; |
1148 | 0 | float *ub = td->block[1]; |
1149 | 0 | float *vb = td->block[2]; |
1150 | 0 | int bw = FFMIN(8, td->xsize - x); |
1151 | 0 | int bh = FFMIN(8, td->ysize - y); |
1152 | |
|
1153 | 0 | memset(td->block, 0, sizeof(td->block)); |
1154 | |
|
1155 | 0 | for (int j = 0; j < 3; j++) { |
1156 | 0 | float *block = td->block[j]; |
1157 | 0 | const int idx = (x >> 3) + (y >> 3) * dc_w + dc_w * dc_h * j; |
1158 | 0 | uint16_t *dc = (uint16_t *)td->dc_data; |
1159 | 0 | union av_intfloat32 dc_val; |
1160 | |
|
1161 | 0 | dc_val.i = half2float(dc[idx], &s->h2f_tables); |
1162 | |
|
1163 | 0 | block[0] = dc_val.f; |
1164 | 0 | ac_uncompress(s, &agb, block); |
1165 | 0 | dct_inverse(block); |
1166 | 0 | } |
1167 | |
|
1168 | 0 | if (s->pixel_type == EXR_HALF) { |
1169 | 0 | uint16_t *bo = ((uint16_t *)td->uncompressed_data) + |
1170 | 0 | y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x; |
1171 | 0 | uint16_t *go = ((uint16_t *)td->uncompressed_data) + |
1172 | 0 | y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x; |
1173 | 0 | uint16_t *ro = ((uint16_t *)td->uncompressed_data) + |
1174 | 0 | y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x; |
1175 | |
|
1176 | 0 | for (int yy = 0; yy < bh; yy++) { |
1177 | 0 | for (int xx = 0; xx < bw; xx++) { |
1178 | 0 | const int idx = xx + yy * 8; |
1179 | 0 | float b, g, r; |
1180 | |
|
1181 | 0 | convert(yb[idx], ub[idx], vb[idx], &b, &g, &r); |
1182 | |
|
1183 | 0 | bo[xx] = float2half(av_float2int(to_linear(b, 1.f)), &s->f2h_tables); |
1184 | 0 | go[xx] = float2half(av_float2int(to_linear(g, 1.f)), &s->f2h_tables); |
1185 | 0 | ro[xx] = float2half(av_float2int(to_linear(r, 1.f)), &s->f2h_tables); |
1186 | 0 | } |
1187 | |
|
1188 | 0 | bo += td->xsize * s->nb_channels; |
1189 | 0 | go += td->xsize * s->nb_channels; |
1190 | 0 | ro += td->xsize * s->nb_channels; |
1191 | 0 | } |
1192 | 0 | } else { |
1193 | 0 | float *bo = ((float *)td->uncompressed_data) + |
1194 | 0 | y * td->xsize * s->nb_channels + td->xsize * (o + 0) + x; |
1195 | 0 | float *go = ((float *)td->uncompressed_data) + |
1196 | 0 | y * td->xsize * s->nb_channels + td->xsize * (o + 1) + x; |
1197 | 0 | float *ro = ((float *)td->uncompressed_data) + |
1198 | 0 | y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x; |
1199 | |
|
1200 | 0 | for (int yy = 0; yy < bh; yy++) { |
1201 | 0 | for (int xx = 0; xx < bw; xx++) { |
1202 | 0 | const int idx = xx + yy * 8; |
1203 | |
|
1204 | 0 | convert(yb[idx], ub[idx], vb[idx], &bo[xx], &go[xx], &ro[xx]); |
1205 | |
|
1206 | 0 | bo[xx] = to_linear(bo[xx], 1.f); |
1207 | 0 | go[xx] = to_linear(go[xx], 1.f); |
1208 | 0 | ro[xx] = to_linear(ro[xx], 1.f); |
1209 | 0 | } |
1210 | |
|
1211 | 0 | bo += td->xsize * s->nb_channels; |
1212 | 0 | go += td->xsize * s->nb_channels; |
1213 | 0 | ro += td->xsize * s->nb_channels; |
1214 | 0 | } |
1215 | 0 | } |
1216 | 0 | } |
1217 | 0 | } |
1218 | |
|
1219 | 0 | if (s->nb_channels < 4) |
1220 | 0 | return 0; |
1221 | | |
1222 | 0 | if (s->pixel_type == EXR_HALF) { |
1223 | 0 | for (int y = 0; y < td->ysize && have_rle; y++) { |
1224 | 0 | uint16_t *ao = ((uint16_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels; |
1225 | 0 | uint8_t *ai0 = td->rle_raw_data + y * td->xsize; |
1226 | 0 | uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2; |
1227 | |
|
1228 | 0 | for (int x = 0; x < td->xsize; x++) |
1229 | 0 | ao[x] = ai0[x] | (ai1[x] << 8); |
1230 | 0 | } |
1231 | 0 | } else { |
1232 | 0 | for (int y = 0; y < td->ysize && have_rle; y++) { |
1233 | 0 | uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels; |
1234 | 0 | uint8_t *ai0 = td->rle_raw_data + y * td->xsize; |
1235 | 0 | uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2; |
1236 | |
|
1237 | 0 | for (int x = 0; x < td->xsize; x++) { |
1238 | 0 | uint16_t ha = ai0[x] | (ai1[x] << 8); |
1239 | |
|
1240 | 0 | ao[x] = half2float(ha, &s->h2f_tables); |
1241 | 0 | } |
1242 | 0 | } |
1243 | 0 | } |
1244 | |
|
1245 | 0 | return 0; |
1246 | 0 | } |
1247 | | |
1248 | | static int decode_block(AVCodecContext *avctx, void *tdata, |
1249 | | int jobnr, int threadnr) |
1250 | 1.79M | { |
1251 | 1.79M | const EXRContext *s = avctx->priv_data; |
1252 | 1.79M | AVFrame *const p = s->picture; |
1253 | 1.79M | EXRThreadData *td = &s->thread_data[threadnr]; |
1254 | 1.79M | const uint8_t *channel_buffer[4] = { 0 }; |
1255 | 1.79M | const uint8_t *buf = s->buf; |
1256 | 1.79M | uint64_t line_offset, uncompressed_size; |
1257 | 1.79M | uint8_t *ptr; |
1258 | 1.79M | uint32_t data_size; |
1259 | 1.79M | int line, col = 0; |
1260 | 1.79M | uint64_t tile_x, tile_y, tile_level_x, tile_level_y; |
1261 | 1.79M | const uint8_t *src; |
1262 | 1.79M | int step = s->desc->comp[0].step; |
1263 | 1.79M | int bxmin = 0, axmax = 0, window_xoffset = 0; |
1264 | 1.79M | int window_xmin, window_xmax, window_ymin, window_ymax; |
1265 | 1.79M | int data_xoffset, data_yoffset, data_window_offset, xsize, ysize; |
1266 | 1.79M | int i, x, buf_size = s->buf_size; |
1267 | 1.79M | int c, rgb_channel_count; |
1268 | 1.79M | #if FF_API_EXR_GAMMA |
1269 | 1.79M | float one_gamma = 1.0f / s->gamma; |
1270 | 1.79M | av_csp_trc_function trc_func = av_csp_trc_func_from_id(s->apply_trc_type); |
1271 | 1.79M | #endif |
1272 | 1.79M | int ret; |
1273 | | |
1274 | 1.79M | line_offset = AV_RL64(s->gb.buffer + jobnr * 8); |
1275 | | |
1276 | 1.79M | if (s->is_tile) { |
1277 | 256k | if (buf_size < 20 || line_offset > buf_size - 20) |
1278 | 205k | return AVERROR_INVALIDDATA; |
1279 | | |
1280 | 50.9k | src = buf + line_offset + 20; |
1281 | 50.9k | if (s->is_multipart) |
1282 | 45.7k | src += 4; |
1283 | | |
1284 | 50.9k | tile_x = AV_RL32(src - 20); |
1285 | 50.9k | tile_y = AV_RL32(src - 16); |
1286 | 50.9k | tile_level_x = AV_RL32(src - 12); |
1287 | 50.9k | tile_level_y = AV_RL32(src - 8); |
1288 | | |
1289 | 50.9k | data_size = AV_RL32(src - 4); |
1290 | 50.9k | if (data_size <= 0 || data_size > buf_size - line_offset - 20) |
1291 | 44.8k | return AVERROR_INVALIDDATA; |
1292 | | |
1293 | 6.08k | if (tile_level_x || tile_level_y) { /* tile level, is not the full res level */ |
1294 | 3.95k | avpriv_report_missing_feature(s->avctx, "Subres tile before full res tile"); |
1295 | 3.95k | return AVERROR_PATCHWELCOME; |
1296 | 3.95k | } |
1297 | | |
1298 | 2.13k | if (tile_x && s->tile_attr.xSize + (int64_t)FFMAX(s->xmin, 0) >= INT_MAX / tile_x ) |
1299 | 278 | return AVERROR_INVALIDDATA; |
1300 | 1.85k | if (tile_y && s->tile_attr.ySize + (int64_t)FFMAX(s->ymin, 0) >= INT_MAX / tile_y ) |
1301 | 493 | return AVERROR_INVALIDDATA; |
1302 | | |
1303 | 1.36k | line = s->ymin + s->tile_attr.ySize * tile_y; |
1304 | 1.36k | col = s->tile_attr.xSize * tile_x; |
1305 | | |
1306 | 1.36k | if (line < s->ymin || line > s->ymax || |
1307 | 1.16k | s->xmin + col < s->xmin || s->xmin + col > s->xmax) |
1308 | 273 | return AVERROR_INVALIDDATA; |
1309 | | |
1310 | 1.09k | td->ysize = FFMIN(s->tile_attr.ySize, s->ydelta - tile_y * s->tile_attr.ySize); |
1311 | 1.09k | td->xsize = FFMIN(s->tile_attr.xSize, s->xdelta - tile_x * s->tile_attr.xSize); |
1312 | | |
1313 | 1.09k | if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX || |
1314 | 548 | av_image_check_size2(td->xsize, td->ysize, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx) < 0) |
1315 | 768 | return AVERROR_INVALIDDATA; |
1316 | | |
1317 | 322 | td->channel_line_size = td->xsize * s->current_channel_offset;/* uncompress size of one line */ |
1318 | 322 | uncompressed_size = td->channel_line_size * (uint64_t)td->ysize;/* uncompress size of the block */ |
1319 | 1.53M | } else { |
1320 | 1.53M | if (buf_size < 8 || line_offset > buf_size - 8) |
1321 | 1.27M | return AVERROR_INVALIDDATA; |
1322 | | |
1323 | 262k | src = buf + line_offset + 8; |
1324 | 262k | if (s->is_multipart) |
1325 | 58.9k | src += 4; |
1326 | 262k | line = AV_RL32(src - 8); |
1327 | | |
1328 | 262k | if (line < s->ymin || line > s->ymax) |
1329 | 207k | return AVERROR_INVALIDDATA; |
1330 | | |
1331 | 54.4k | data_size = AV_RL32(src - 4); |
1332 | 54.4k | if (data_size <= 0 || data_size > buf_size - line_offset - 8) |
1333 | 18.4k | return AVERROR_INVALIDDATA; |
1334 | | |
1335 | 36.0k | td->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1); /* s->ydelta - line ?? */ |
1336 | 36.0k | td->xsize = s->xdelta; |
1337 | | |
1338 | 36.0k | if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX || |
1339 | 35.7k | av_image_check_size2(td->xsize, td->ysize, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx) < 0) |
1340 | 1.05k | return AVERROR_INVALIDDATA; |
1341 | | |
1342 | 34.9k | td->channel_line_size = td->xsize * s->current_channel_offset;/* uncompress size of one line */ |
1343 | 34.9k | uncompressed_size = td->channel_line_size * (uint64_t)td->ysize;/* uncompress size of the block */ |
1344 | | |
1345 | 34.9k | if ((s->compression == EXR_RAW && (data_size != uncompressed_size || |
1346 | 3 | line_offset > buf_size - uncompressed_size)) || |
1347 | 34.8k | (s->compression != EXR_RAW && (data_size > uncompressed_size || |
1348 | 34.5k | line_offset > buf_size - data_size))) { |
1349 | 378 | return AVERROR_INVALIDDATA; |
1350 | 378 | } |
1351 | 34.9k | } |
1352 | | |
1353 | 34.8k | window_xmin = FFMIN(avctx->width, FFMAX(0, s->xmin + col)); |
1354 | 34.8k | window_xmax = FFMIN(avctx->width, FFMAX(0, s->xmin + col + td->xsize)); |
1355 | 34.8k | window_ymin = FFMIN(avctx->height, FFMAX(0, line )); |
1356 | 34.8k | window_ymax = FFMIN(avctx->height, FFMAX(0, line + td->ysize)); |
1357 | 34.8k | xsize = window_xmax - window_xmin; |
1358 | 34.8k | ysize = window_ymax - window_ymin; |
1359 | | |
1360 | | /* tile or scanline not visible skip decoding */ |
1361 | 34.8k | if (xsize <= 0 || ysize <= 0) |
1362 | 1.79k | return 0; |
1363 | | |
1364 | | /* is the first tile or is a scanline */ |
1365 | 33.1k | if(col == 0) { |
1366 | 33.1k | window_xmin = 0; |
1367 | | /* pixels to add at the left of the display window */ |
1368 | 33.1k | window_xoffset = FFMAX(0, s->xmin); |
1369 | | /* bytes to add at the left of the display window */ |
1370 | 33.1k | bxmin = window_xoffset * step; |
1371 | 33.1k | } |
1372 | | |
1373 | | /* is the last tile or is a scanline */ |
1374 | 33.1k | if(col + td->xsize == s->xdelta) { |
1375 | 33.0k | window_xmax = avctx->width; |
1376 | | /* bytes to add at the right of the display window */ |
1377 | 33.0k | axmax = FFMAX(0, (avctx->width - (s->xmax + 1))) * step; |
1378 | 33.0k | } |
1379 | | |
1380 | 33.1k | if (avctx->max_pixels && uncompressed_size > avctx->max_pixels * 16LL) |
1381 | 13 | return AVERROR_INVALIDDATA; |
1382 | | |
1383 | 33.0k | if (data_size < uncompressed_size || s->is_tile) { /* td->tmp is use for tile reorganization */ |
1384 | 32.7k | av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size); |
1385 | 32.7k | if (!td->tmp) |
1386 | 0 | return AVERROR(ENOMEM); |
1387 | 32.7k | } |
1388 | | |
1389 | 33.0k | if (data_size < uncompressed_size) { |
1390 | 32.7k | av_fast_padded_malloc(&td->uncompressed_data, |
1391 | 32.7k | &td->uncompressed_size, uncompressed_size + 64);/* Force 64 padding for AVX2 reorder_pixels dst */ |
1392 | | |
1393 | 32.7k | if (!td->uncompressed_data) |
1394 | 0 | return AVERROR(ENOMEM); |
1395 | | |
1396 | 32.7k | ret = AVERROR_INVALIDDATA; |
1397 | 32.7k | switch (s->compression) { |
1398 | 88 | case EXR_ZIP1: |
1399 | 14.1k | case EXR_ZIP16: |
1400 | 14.1k | ret = zip_uncompress(s, src, data_size, uncompressed_size, td); |
1401 | 14.1k | break; |
1402 | 14.5k | case EXR_PIZ: |
1403 | 14.5k | ret = piz_uncompress(s, src, data_size, uncompressed_size, td); |
1404 | 14.5k | break; |
1405 | 611 | case EXR_PXR24: |
1406 | 611 | ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td); |
1407 | 611 | break; |
1408 | 471 | case EXR_RLE: |
1409 | 471 | ret = rle_uncompress(s, src, data_size, uncompressed_size, td); |
1410 | 471 | break; |
1411 | 1.44k | case EXR_B44: |
1412 | 1.95k | case EXR_B44A: |
1413 | 1.95k | ret = b44_uncompress(s, src, data_size, uncompressed_size, td); |
1414 | 1.95k | break; |
1415 | 723 | case EXR_DWAA: |
1416 | 930 | case EXR_DWAB: |
1417 | 930 | ret = dwa_uncompress(s, src, data_size, uncompressed_size, td); |
1418 | 930 | break; |
1419 | 32.7k | } |
1420 | 32.7k | if (ret < 0) { |
1421 | 26.8k | av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n"); |
1422 | 26.8k | return ret; |
1423 | 26.8k | } |
1424 | 5.83k | src = td->uncompressed_data; |
1425 | 5.83k | } |
1426 | | |
1427 | | /* offsets to crop data outside display window */ |
1428 | 6.20k | data_xoffset = FFABS(FFMIN(0, s->xmin + col)) * (s->pixel_type == EXR_HALF ? 2 : 4); |
1429 | 6.20k | data_yoffset = FFABS(FFMIN(0, line)); |
1430 | 6.20k | data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset; |
1431 | | |
1432 | 6.20k | if (s->channel_offsets[3] >= 0) |
1433 | 159 | channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset; |
1434 | 6.20k | if (!s->is_luma) { |
1435 | 2.92k | channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset; |
1436 | 2.92k | channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset; |
1437 | 2.92k | channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset; |
1438 | 2.92k | rgb_channel_count = 3; |
1439 | 3.28k | } else { /* put y data in the first channel_buffer and if needed, alpha in the second */ |
1440 | 3.28k | channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset; |
1441 | 3.28k | if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR)) |
1442 | 3.28k | channel_buffer[1] = channel_buffer[3]; |
1443 | 3.28k | rgb_channel_count = 1; |
1444 | 3.28k | } |
1445 | | |
1446 | 6.20k | if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) { |
1447 | 16.6k | for (c = 0; c < s->desc->nb_components; c++) { |
1448 | 11.3k | int plane = s->desc->comp[c].plane; |
1449 | 11.3k | ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset; |
1450 | | |
1451 | 61.6k | for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) { |
1452 | 50.3k | const uint8_t *src = channel_buffer[c]; |
1453 | 50.3k | uint8_t *ptr_x = ptr + window_xoffset * step; |
1454 | | |
1455 | | // Zero out the start if xmin is not 0 |
1456 | 50.3k | if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c) |
1457 | 50.1k | memset(ptr, 0, bxmin); |
1458 | | |
1459 | 50.3k | if (s->pixel_type == EXR_FLOAT) { |
1460 | | // 32-bit |
1461 | 46.3k | #if FF_API_EXR_GAMMA |
1462 | 46.3k | if (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))) { |
1463 | 0 | for (int x = 0; x < xsize; x++, ptr_x += step) { |
1464 | 0 | float f = av_int2float(bytestream_get_le32(&src)); |
1465 | 0 | AV_WN32A(ptr_x, av_float2int(trc_func(f))); |
1466 | 0 | } |
1467 | 46.3k | } else if (one_gamma != 1.f) { |
1468 | 0 | for (int x = 0; x < xsize; x++, ptr_x += step) { |
1469 | 0 | float f = av_int2float(bytestream_get_le32(&src)); |
1470 | 0 | if (f > 0.0f && c < 3) /* avoid negative values */ |
1471 | 0 | f = powf(f, one_gamma); |
1472 | 0 | AV_WN32A(ptr_x, av_float2int(f)); |
1473 | 0 | } |
1474 | 0 | } else |
1475 | 46.3k | #endif |
1476 | 9.86M | for (int x = 0; x < xsize; x++, ptr_x += step) |
1477 | 9.82M | AV_WN32A(ptr_x, bytestream_get_le32(&src)); |
1478 | 46.3k | } else if (s->pixel_type == EXR_HALF) { |
1479 | | // 16-bit |
1480 | 3.95k | #if FF_API_EXR_GAMMA |
1481 | 3.95k | if (one_gamma != 1.f || (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR)))) { |
1482 | 0 | for (int x = 0; x < xsize; x++, ptr_x += step) |
1483 | 0 | AV_WN16A(ptr_x, s->gamma_table[bytestream_get_le16(&src)]); |
1484 | 0 | } else |
1485 | 3.95k | #endif |
1486 | 9.96M | for (int x = 0; x < xsize; x++, ptr_x += step) |
1487 | 9.96M | AV_WN16A(ptr_x, bytestream_get_le16(&src)); |
1488 | 3.95k | } |
1489 | | |
1490 | | // Zero out the end if xmax+1 is not w |
1491 | 50.3k | if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c) |
1492 | 50.1k | memset(ptr_x, 0, axmax); |
1493 | 50.3k | channel_buffer[c] += td->channel_line_size; |
1494 | 50.3k | } |
1495 | 11.3k | } |
1496 | 5.30k | } else { |
1497 | | |
1498 | 895 | av_assert1(s->pixel_type == EXR_UINT); |
1499 | 895 | ptr = p->data[0] + window_ymin * p->linesize[0] + (window_xmin * s->desc->nb_components * 2); |
1500 | | |
1501 | 4.88k | for (i = 0; i < ysize; i++, ptr += p->linesize[0]) { |
1502 | | |
1503 | 3.98k | const uint8_t * a; |
1504 | 3.98k | const uint8_t *rgb[3]; |
1505 | 3.98k | uint16_t *ptr_x; |
1506 | | |
1507 | 7.97k | for (c = 0; c < rgb_channel_count; c++) { |
1508 | 3.98k | rgb[c] = channel_buffer[c]; |
1509 | 3.98k | } |
1510 | | |
1511 | 3.98k | if (channel_buffer[3]) |
1512 | 0 | a = channel_buffer[3]; |
1513 | | |
1514 | 3.98k | ptr_x = (uint16_t *) ptr; |
1515 | | |
1516 | | // Zero out the start if xmin is not 0 |
1517 | 3.98k | memset(ptr_x, 0, bxmin); |
1518 | 3.98k | ptr_x += window_xoffset * s->desc->nb_components; |
1519 | | |
1520 | 10.6M | for (x = 0; x < xsize; x++) { |
1521 | 21.2M | for (c = 0; c < rgb_channel_count; c++) { |
1522 | 10.6M | *ptr_x++ = bytestream_get_le32(&rgb[c]) >> 16; |
1523 | 10.6M | } |
1524 | | |
1525 | 10.6M | if (channel_buffer[3]) |
1526 | 0 | *ptr_x++ = bytestream_get_le32(&a) >> 16; |
1527 | 10.6M | } |
1528 | | |
1529 | | // Zero out the end if xmax+1 is not w |
1530 | 3.98k | memset(ptr_x, 0, axmax); |
1531 | | |
1532 | 3.98k | channel_buffer[0] += td->channel_line_size; |
1533 | 3.98k | channel_buffer[1] += td->channel_line_size; |
1534 | 3.98k | channel_buffer[2] += td->channel_line_size; |
1535 | 3.98k | if (channel_buffer[3]) |
1536 | 0 | channel_buffer[3] += td->channel_line_size; |
1537 | 3.98k | } |
1538 | 895 | } |
1539 | | |
1540 | 6.20k | return 0; |
1541 | 33.0k | } |
1542 | | |
1543 | | static void skip_header_chunk(EXRContext *s) |
1544 | 4.67k | { |
1545 | 4.67k | GetByteContext *gb = &s->gb; |
1546 | | |
1547 | 11.1k | while (bytestream2_get_bytes_left(gb) > 0) { |
1548 | 8.08k | if (!bytestream2_peek_byte(gb)) |
1549 | 1.60k | break; |
1550 | | |
1551 | | // Process unknown variables |
1552 | 19.4k | for (int i = 0; i < 2; i++) // value_name and value_type |
1553 | 108k | while (bytestream2_get_byte(gb) != 0); |
1554 | | |
1555 | | // Skip variable length |
1556 | 6.47k | bytestream2_skip(gb, bytestream2_get_le32(gb)); |
1557 | 6.47k | } |
1558 | 4.67k | } |
1559 | | |
1560 | | /** |
1561 | | * Check if the variable name corresponds to its data type. |
1562 | | * |
1563 | | * @param s the EXRContext |
1564 | | * @param value_name name of the variable to check |
1565 | | * @param value_type type of the variable to check |
1566 | | * @param minimum_length minimum length of the variable data |
1567 | | * |
1568 | | * @return bytes to read containing variable data |
1569 | | * -1 if variable is not found |
1570 | | * 0 if buffer ended prematurely |
1571 | | */ |
1572 | | static int check_header_variable(EXRContext *s, |
1573 | | const char *value_name, |
1574 | | const char *value_type, |
1575 | | unsigned int minimum_length) |
1576 | 5.51M | { |
1577 | 5.51M | GetByteContext *gb = &s->gb; |
1578 | 5.51M | int var_size = -1; |
1579 | | |
1580 | 5.51M | if (bytestream2_get_bytes_left(gb) >= minimum_length && |
1581 | 5.32M | !strcmp(gb->buffer, value_name)) { |
1582 | | // found value_name, jump to value_type (null terminated strings) |
1583 | 333k | gb->buffer += strlen(value_name) + 1; |
1584 | 333k | if (!strcmp(gb->buffer, value_type)) { |
1585 | 318k | gb->buffer += strlen(value_type) + 1; |
1586 | 318k | var_size = bytestream2_get_le32(gb); |
1587 | | // don't go read past boundaries |
1588 | 318k | if (var_size > bytestream2_get_bytes_left(gb)) |
1589 | 11.0k | var_size = 0; |
1590 | 318k | } else { |
1591 | | // value_type not found, reset the buffer |
1592 | 14.5k | gb->buffer -= strlen(value_name) + 1; |
1593 | 14.5k | av_log(s->avctx, AV_LOG_WARNING, |
1594 | 14.5k | "Unknown data type %s for header variable %s.\n", |
1595 | 14.5k | value_type, value_name); |
1596 | 14.5k | } |
1597 | 333k | } |
1598 | | |
1599 | 5.51M | return var_size; |
1600 | 5.51M | } |
1601 | | |
1602 | | static int decode_header(EXRContext *s, AVFrame *frame) |
1603 | 203k | { |
1604 | 203k | AVDictionary *metadata = NULL; |
1605 | 203k | GetByteContext *gb = &s->gb; |
1606 | 203k | int magic_number, version, flags; |
1607 | 203k | int layer_match = 0; |
1608 | 203k | int ret; |
1609 | 203k | int dup_channels = 0; |
1610 | | |
1611 | 203k | s->current_channel_offset = 0; |
1612 | 203k | s->xmin = ~0; |
1613 | 203k | s->xmax = ~0; |
1614 | 203k | s->ymin = ~0; |
1615 | 203k | s->ymax = ~0; |
1616 | 203k | s->xdelta = ~0; |
1617 | 203k | s->ydelta = ~0; |
1618 | 203k | s->channel_offsets[0] = -1; |
1619 | 203k | s->channel_offsets[1] = -1; |
1620 | 203k | s->channel_offsets[2] = -1; |
1621 | 203k | s->channel_offsets[3] = -1; |
1622 | 203k | s->pixel_type = EXR_UNKNOWN; |
1623 | 203k | s->compression = EXR_UNKN; |
1624 | 203k | s->nb_channels = 0; |
1625 | 203k | s->w = 0; |
1626 | 203k | s->h = 0; |
1627 | 203k | s->tile_attr.xSize = -1; |
1628 | 203k | s->tile_attr.ySize = -1; |
1629 | 203k | s->is_tile = 0; |
1630 | 203k | s->is_multipart = 0; |
1631 | 203k | s->is_luma = 0; |
1632 | 203k | s->has_channel = 0; |
1633 | 203k | s->current_part = 0; |
1634 | | |
1635 | 203k | if (bytestream2_get_bytes_left(gb) < 10) { |
1636 | 34.0k | av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n"); |
1637 | 34.0k | return AVERROR_INVALIDDATA; |
1638 | 34.0k | } |
1639 | | |
1640 | 169k | magic_number = bytestream2_get_le32(gb); |
1641 | 169k | if (magic_number != 20000630) { |
1642 | | /* As per documentation of OpenEXR, it is supposed to be |
1643 | | * int 20000630 little-endian */ |
1644 | 50.9k | av_log(s->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", magic_number); |
1645 | 50.9k | return AVERROR_INVALIDDATA; |
1646 | 50.9k | } |
1647 | | |
1648 | 118k | version = bytestream2_get_byte(gb); |
1649 | 118k | if (version != 2) { |
1650 | 884 | avpriv_report_missing_feature(s->avctx, "Version %d", version); |
1651 | 884 | return AVERROR_PATCHWELCOME; |
1652 | 884 | } |
1653 | | |
1654 | 117k | flags = bytestream2_get_le24(gb); |
1655 | | |
1656 | 117k | if (flags & 0x02) |
1657 | 37.5k | s->is_tile = 1; |
1658 | 117k | if (flags & 0x10) |
1659 | 43.2k | s->is_multipart = 1; |
1660 | 117k | if (flags & 0x08) { |
1661 | 3.74k | avpriv_report_missing_feature(s->avctx, "deep data"); |
1662 | 3.74k | return AVERROR_PATCHWELCOME; |
1663 | 3.74k | } |
1664 | | |
1665 | | // Parse the header |
1666 | 756k | while (bytestream2_get_bytes_left(gb) > 0) { |
1667 | 730k | int var_size; |
1668 | | |
1669 | 730k | while (s->is_multipart && s->current_part < s->selected_part && |
1670 | 0 | bytestream2_get_bytes_left(gb) > 0) { |
1671 | 0 | if (bytestream2_peek_byte(gb)) { |
1672 | 0 | skip_header_chunk(s); |
1673 | 0 | } else { |
1674 | 0 | bytestream2_skip(gb, 1); |
1675 | 0 | if (!bytestream2_peek_byte(gb)) |
1676 | 0 | break; |
1677 | 0 | } |
1678 | 0 | bytestream2_skip(gb, 1); |
1679 | 0 | s->current_part++; |
1680 | 0 | } |
1681 | | |
1682 | 730k | if (!bytestream2_peek_byte(gb)) { |
1683 | 59.5k | if (!s->is_multipart) |
1684 | 48.3k | break; |
1685 | 11.2k | bytestream2_skip(gb, 1); |
1686 | 11.2k | if (s->current_part == s->selected_part) { |
1687 | 17.6k | while (bytestream2_get_bytes_left(gb) > 0) { |
1688 | 11.0k | if (bytestream2_peek_byte(gb)) { |
1689 | 4.67k | skip_header_chunk(s); |
1690 | 6.36k | } else { |
1691 | 6.36k | bytestream2_skip(gb, 1); |
1692 | 6.36k | if (!bytestream2_peek_byte(gb)) |
1693 | 4.62k | break; |
1694 | 6.36k | } |
1695 | 11.0k | } |
1696 | 11.2k | } |
1697 | 11.2k | if (!bytestream2_peek_byte(gb)) |
1698 | 11.2k | break; |
1699 | 0 | s->current_part++; |
1700 | 0 | } |
1701 | | |
1702 | 670k | if ((var_size = check_header_variable(s, "channels", |
1703 | 670k | "chlist", 38)) >= 0) { |
1704 | 65.7k | GetByteContext ch_gb; |
1705 | 65.7k | if (!var_size) { |
1706 | 1.64k | ret = AVERROR_INVALIDDATA; |
1707 | 1.64k | goto fail; |
1708 | 1.64k | } |
1709 | | |
1710 | 64.1k | bytestream2_init(&ch_gb, gb->buffer, var_size); |
1711 | | |
1712 | 196k | while (bytestream2_get_bytes_left(&ch_gb) >= 19) { |
1713 | 140k | EXRChannel *channel; |
1714 | 140k | enum ExrPixelType current_pixel_type; |
1715 | 140k | int channel_index = -1; |
1716 | 140k | int xsub, ysub; |
1717 | | |
1718 | 140k | if (strcmp(s->layer, "") != 0) { |
1719 | 0 | if (strncmp(ch_gb.buffer, s->layer, strlen(s->layer)) == 0) { |
1720 | 0 | layer_match = 1; |
1721 | 0 | av_log(s->avctx, AV_LOG_INFO, |
1722 | 0 | "Channel match layer : %s.\n", ch_gb.buffer); |
1723 | 0 | ch_gb.buffer += strlen(s->layer); |
1724 | 0 | if (*ch_gb.buffer == '.') |
1725 | 0 | ch_gb.buffer++; /* skip dot if not given */ |
1726 | 0 | } else { |
1727 | 0 | layer_match = 0; |
1728 | 0 | av_log(s->avctx, AV_LOG_INFO, |
1729 | 0 | "Channel doesn't match layer : %s.\n", ch_gb.buffer); |
1730 | 0 | } |
1731 | 140k | } else { |
1732 | 140k | layer_match = 1; |
1733 | 140k | } |
1734 | | |
1735 | 140k | if (layer_match) { /* only search channel if the layer match is valid */ |
1736 | 140k | if (strlen(ch_gb.buffer) == 1) { |
1737 | 113k | int ch_chr = av_toupper(*ch_gb.buffer); |
1738 | 113k | if (ch_chr >= 'A' && ch_chr <= 'Z') |
1739 | 113k | s->has_channel |= M(ch_chr); |
1740 | 113k | av_log(s->avctx, AV_LOG_DEBUG, "%c\n", ch_chr); |
1741 | 113k | } |
1742 | | |
1743 | 140k | if (!av_strcasecmp(ch_gb.buffer, "R") || |
1744 | 114k | !av_strcasecmp(ch_gb.buffer, "X") || |
1745 | 113k | !av_strcasecmp(ch_gb.buffer, "U")) { |
1746 | 26.6k | channel_index = 0; |
1747 | 113k | } else if (!av_strcasecmp(ch_gb.buffer, "G") || |
1748 | 86.1k | !av_strcasecmp(ch_gb.buffer, "V")) { |
1749 | 27.5k | channel_index = 1; |
1750 | 85.9k | } else if (!av_strcasecmp(ch_gb.buffer, "Y")) { |
1751 | 30.1k | channel_index = 1; |
1752 | 55.7k | } else if (!av_strcasecmp(ch_gb.buffer, "B") || |
1753 | 28.6k | !av_strcasecmp(ch_gb.buffer, "Z") || |
1754 | 28.3k | !av_strcasecmp(ch_gb.buffer, "W")) { |
1755 | 27.6k | channel_index = 2; |
1756 | 28.1k | } else if (!av_strcasecmp(ch_gb.buffer, "A")) { |
1757 | 1.11k | channel_index = 3; |
1758 | 27.0k | } else { |
1759 | 27.0k | av_log(s->avctx, AV_LOG_WARNING, |
1760 | 27.0k | "Unsupported channel %.256s.\n", ch_gb.buffer); |
1761 | 27.0k | } |
1762 | 140k | } |
1763 | | |
1764 | | /* skip until you get a 0 */ |
1765 | 369k | while (bytestream2_get_bytes_left(&ch_gb) > 0 && |
1766 | 369k | bytestream2_get_byte(&ch_gb)) |
1767 | 229k | continue; |
1768 | | |
1769 | 140k | if (bytestream2_get_bytes_left(&ch_gb) < 4) { |
1770 | 492 | av_log(s->avctx, AV_LOG_ERROR, "Incomplete header.\n"); |
1771 | 492 | ret = AVERROR_INVALIDDATA; |
1772 | 492 | goto fail; |
1773 | 492 | } |
1774 | | |
1775 | 139k | current_pixel_type = bytestream2_get_le32(&ch_gb); |
1776 | 139k | if (current_pixel_type >= EXR_UNKNOWN) { |
1777 | 3.53k | avpriv_report_missing_feature(s->avctx, "Pixel type %d", |
1778 | 3.53k | current_pixel_type); |
1779 | 3.53k | ret = AVERROR_PATCHWELCOME; |
1780 | 3.53k | goto fail; |
1781 | 3.53k | } |
1782 | | |
1783 | 136k | bytestream2_skip(&ch_gb, 4); |
1784 | 136k | xsub = bytestream2_get_le32(&ch_gb); |
1785 | 136k | ysub = bytestream2_get_le32(&ch_gb); |
1786 | | |
1787 | 136k | if (xsub != 1 || ysub != 1) { |
1788 | 3.60k | avpriv_report_missing_feature(s->avctx, |
1789 | 3.60k | "Subsampling %dx%d", |
1790 | 3.60k | xsub, ysub); |
1791 | 3.60k | ret = AVERROR_PATCHWELCOME; |
1792 | 3.60k | goto fail; |
1793 | 3.60k | } |
1794 | | |
1795 | 132k | if (channel_index >= 0 && s->channel_offsets[channel_index] == -1) { /* channel has not been previously assigned */ |
1796 | 104k | if (s->pixel_type != EXR_UNKNOWN && |
1797 | 49.7k | s->pixel_type != current_pixel_type) { |
1798 | 218 | av_log(s->avctx, AV_LOG_ERROR, |
1799 | 218 | "RGB channels not of the same depth.\n"); |
1800 | 218 | ret = AVERROR_INVALIDDATA; |
1801 | 218 | goto fail; |
1802 | 218 | } |
1803 | 104k | s->pixel_type = current_pixel_type; |
1804 | 104k | s->channel_offsets[channel_index] = s->current_channel_offset; |
1805 | 104k | } else if (channel_index >= 0) { |
1806 | 4.27k | av_log(s->avctx, AV_LOG_WARNING, |
1807 | 4.27k | "Multiple channels with index %d.\n", channel_index); |
1808 | 4.27k | if (++dup_channels > 10) { |
1809 | 88 | ret = AVERROR_INVALIDDATA; |
1810 | 88 | goto fail; |
1811 | 88 | } |
1812 | 4.27k | } |
1813 | | |
1814 | 132k | av_assert0(s->nb_channels < INT_MAX); // Impossible due to size of the bitstream |
1815 | 132k | EXRChannel *new_channels = av_realloc_array(s->channels, |
1816 | 132k | s->nb_channels + 1, |
1817 | 132k | sizeof(EXRChannel)); |
1818 | 132k | if (!new_channels) { |
1819 | 0 | ret = AVERROR(ENOMEM); |
1820 | 0 | goto fail; |
1821 | 0 | } |
1822 | 132k | s->nb_channels ++; |
1823 | 132k | s->channels = new_channels; |
1824 | | |
1825 | 132k | channel = &s->channels[s->nb_channels - 1]; |
1826 | 132k | channel->pixel_type = current_pixel_type; |
1827 | 132k | channel->xsub = xsub; |
1828 | 132k | channel->ysub = ysub; |
1829 | | |
1830 | 132k | if (current_pixel_type == EXR_HALF) { |
1831 | 6.09k | s->current_channel_offset += 2; |
1832 | 126k | } else {/* Float or UINT32 */ |
1833 | 126k | s->current_channel_offset += 4; |
1834 | 126k | } |
1835 | 132k | } |
1836 | 56.1k | if (!((M('R') + M('G') + M('B')) & ~s->has_channel)) { |
1837 | 25.3k | s->is_luma = 0; |
1838 | 30.8k | } else if (!((M('X') + M('Y') + M('Z')) & ~s->has_channel)) { |
1839 | 0 | s->is_luma = 0; |
1840 | 30.8k | } else if (!((M('Y') + M('U') + M('V')) & ~s->has_channel)) { |
1841 | 0 | s->is_luma = 0; |
1842 | 30.8k | } else if (!((M('Y') ) & ~s->has_channel) && |
1843 | 29.8k | !((M('R') + M('G') + M('B') + M('U') + M('V') + M('X') + M('Z')) & s->has_channel)) { |
1844 | 29.5k | s->is_luma = 1; |
1845 | 29.5k | } else { |
1846 | 1.31k | avpriv_request_sample(s->avctx, "Uncommon channel combination"); |
1847 | 1.31k | ret = AVERROR_PATCHWELCOME; |
1848 | 1.31k | goto fail; |
1849 | 1.31k | } |
1850 | | |
1851 | | /* Check if all channels are set with an offset or if the channels |
1852 | | * are causing an overflow */ |
1853 | 54.8k | if (!s->is_luma) {/* if we expected to have at least 3 channels */ |
1854 | 25.3k | if (FFMIN3(s->channel_offsets[0], |
1855 | 25.3k | s->channel_offsets[1], |
1856 | 25.3k | s->channel_offsets[2]) < 0) { |
1857 | 0 | if (s->channel_offsets[0] < 0) |
1858 | 0 | av_log(s->avctx, AV_LOG_ERROR, "Missing red channel.\n"); |
1859 | 0 | if (s->channel_offsets[1] < 0) |
1860 | 0 | av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n"); |
1861 | 0 | if (s->channel_offsets[2] < 0) |
1862 | 0 | av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n"); |
1863 | 0 | ret = AVERROR_INVALIDDATA; |
1864 | 0 | goto fail; |
1865 | 0 | } |
1866 | 25.3k | } |
1867 | | |
1868 | | // skip one last byte and update main gb |
1869 | 54.8k | gb->buffer = ch_gb.buffer + 1; |
1870 | 54.8k | continue; |
1871 | 604k | } else if ((var_size = check_header_variable(s, "dataWindow", "box2i", |
1872 | 604k | 31)) >= 0) { |
1873 | 55.0k | int xmin, ymin, xmax, ymax; |
1874 | 55.0k | if (!var_size) { |
1875 | 649 | ret = AVERROR_INVALIDDATA; |
1876 | 649 | goto fail; |
1877 | 649 | } |
1878 | | |
1879 | 54.3k | xmin = bytestream2_get_le32(gb); |
1880 | 54.3k | ymin = bytestream2_get_le32(gb); |
1881 | 54.3k | xmax = bytestream2_get_le32(gb); |
1882 | 54.3k | ymax = bytestream2_get_le32(gb); |
1883 | | |
1884 | 54.3k | if (xmin > xmax || ymin > ymax || |
1885 | 52.7k | ymax == INT_MAX || xmax == INT_MAX || |
1886 | 52.2k | (unsigned)xmax - xmin >= INT_MAX || |
1887 | 51.4k | (unsigned)ymax - ymin >= INT_MAX) { |
1888 | 3.16k | ret = AVERROR_INVALIDDATA; |
1889 | 3.16k | goto fail; |
1890 | 3.16k | } |
1891 | 51.2k | s->xmin = xmin; |
1892 | 51.2k | s->xmax = xmax; |
1893 | 51.2k | s->ymin = ymin; |
1894 | 51.2k | s->ymax = ymax; |
1895 | 51.2k | s->xdelta = (s->xmax - s->xmin) + 1; |
1896 | 51.2k | s->ydelta = (s->ymax - s->ymin) + 1; |
1897 | | |
1898 | 51.2k | continue; |
1899 | 549k | } else if ((var_size = check_header_variable(s, "displayWindow", |
1900 | 549k | "box2i", 34)) >= 0) { |
1901 | 49.7k | int32_t sx, sy, dx, dy; |
1902 | | |
1903 | 49.7k | if (!var_size) { |
1904 | 574 | ret = AVERROR_INVALIDDATA; |
1905 | 574 | goto fail; |
1906 | 574 | } |
1907 | | |
1908 | 49.1k | sx = bytestream2_get_le32(gb); |
1909 | 49.1k | sy = bytestream2_get_le32(gb); |
1910 | 49.1k | dx = bytestream2_get_le32(gb); |
1911 | 49.1k | dy = bytestream2_get_le32(gb); |
1912 | | |
1913 | 49.1k | s->w = (unsigned)dx - sx + 1; |
1914 | 49.1k | s->h = (unsigned)dy - sy + 1; |
1915 | | |
1916 | 49.1k | continue; |
1917 | 500k | } else if ((var_size = check_header_variable(s, "lineOrder", |
1918 | 500k | "lineOrder", 25)) >= 0) { |
1919 | 20.7k | int line_order; |
1920 | 20.7k | if (!var_size) { |
1921 | 880 | ret = AVERROR_INVALIDDATA; |
1922 | 880 | goto fail; |
1923 | 880 | } |
1924 | | |
1925 | 19.9k | line_order = bytestream2_get_byte(gb); |
1926 | 19.9k | av_log(s->avctx, AV_LOG_DEBUG, "line order: %d.\n", line_order); |
1927 | 19.9k | if (line_order > 2) { |
1928 | 253 | av_log(s->avctx, AV_LOG_ERROR, "Unknown line order.\n"); |
1929 | 253 | ret = AVERROR_INVALIDDATA; |
1930 | 253 | goto fail; |
1931 | 253 | } |
1932 | | |
1933 | 19.6k | continue; |
1934 | 479k | } else if ((var_size = check_header_variable(s, "pixelAspectRatio", |
1935 | 479k | "float", 31)) >= 0) { |
1936 | 18.2k | if (!var_size) { |
1937 | 1.65k | ret = AVERROR_INVALIDDATA; |
1938 | 1.65k | goto fail; |
1939 | 1.65k | } |
1940 | | |
1941 | 16.6k | s->sar = bytestream2_get_le32(gb); |
1942 | | |
1943 | 16.6k | continue; |
1944 | 461k | } else if ((var_size = check_header_variable(s, "compression", |
1945 | 461k | "compression", 29)) >= 0) { |
1946 | 56.3k | if (!var_size) { |
1947 | 550 | ret = AVERROR_INVALIDDATA; |
1948 | 550 | goto fail; |
1949 | 550 | } |
1950 | | |
1951 | 55.7k | if (s->compression == EXR_UNKN) |
1952 | 53.1k | s->compression = bytestream2_get_byte(gb); |
1953 | 2.59k | else { |
1954 | 2.59k | bytestream2_skip(gb, 1); |
1955 | 2.59k | av_log(s->avctx, AV_LOG_WARNING, |
1956 | 2.59k | "Found more than one compression attribute.\n"); |
1957 | 2.59k | } |
1958 | | |
1959 | 55.7k | continue; |
1960 | 404k | } else if ((var_size = check_header_variable(s, "tiles", |
1961 | 404k | "tiledesc", 22)) >= 0) { |
1962 | 10.3k | uint8_t tileLevel; |
1963 | | |
1964 | 10.3k | if (!s->is_tile) |
1965 | 526 | av_log(s->avctx, AV_LOG_WARNING, |
1966 | 526 | "Found tile attribute and scanline flags. Exr will be interpreted as scanline.\n"); |
1967 | | |
1968 | 10.3k | s->tile_attr.xSize = bytestream2_get_le32(gb); |
1969 | 10.3k | s->tile_attr.ySize = bytestream2_get_le32(gb); |
1970 | | |
1971 | 10.3k | tileLevel = bytestream2_get_byte(gb); |
1972 | 10.3k | s->tile_attr.level_mode = tileLevel & 0x0f; |
1973 | 10.3k | s->tile_attr.level_round = (tileLevel >> 4) & 0x0f; |
1974 | | |
1975 | 10.3k | if (s->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN) { |
1976 | 402 | avpriv_report_missing_feature(s->avctx, "Tile level mode %d", |
1977 | 402 | s->tile_attr.level_mode); |
1978 | 402 | ret = AVERROR_PATCHWELCOME; |
1979 | 402 | goto fail; |
1980 | 402 | } |
1981 | | |
1982 | 9.92k | if (s->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) { |
1983 | 548 | avpriv_report_missing_feature(s->avctx, "Tile level round %d", |
1984 | 548 | s->tile_attr.level_round); |
1985 | 548 | ret = AVERROR_PATCHWELCOME; |
1986 | 548 | goto fail; |
1987 | 548 | } |
1988 | | |
1989 | 9.37k | continue; |
1990 | 394k | } else if ((var_size = check_header_variable(s, "writer", |
1991 | 394k | "string", 1)) >= 0) { |
1992 | 18.0k | uint8_t key[256] = { 0 }; |
1993 | | |
1994 | 18.0k | bytestream2_get_buffer(gb, key, FFMIN(sizeof(key) - 1, var_size)); |
1995 | 18.0k | av_dict_set(&metadata, "writer", key, 0); |
1996 | | |
1997 | 18.0k | continue; |
1998 | 376k | } else if ((var_size = check_header_variable(s, "framesPerSecond", |
1999 | 376k | "rational", 33)) >= 0) { |
2000 | 19.1k | if (!var_size) { |
2001 | 263 | ret = AVERROR_INVALIDDATA; |
2002 | 263 | goto fail; |
2003 | 263 | } |
2004 | | |
2005 | 18.9k | s->avctx->framerate.num = bytestream2_get_le32(gb); |
2006 | 18.9k | s->avctx->framerate.den = bytestream2_get_le32(gb); |
2007 | | |
2008 | 18.9k | continue; |
2009 | 357k | } else if ((var_size = check_header_variable(s, "chunkCount", |
2010 | 357k | "int", 23)) >= 0) { |
2011 | | |
2012 | 201 | s->chunk_count = bytestream2_get_le32(gb); |
2013 | | |
2014 | 201 | continue; |
2015 | 356k | } else if ((var_size = check_header_variable(s, "type", |
2016 | 356k | "string", 16)) >= 0) { |
2017 | 2.17k | uint8_t key[256] = { 0 }; |
2018 | | |
2019 | 2.17k | bytestream2_get_buffer(gb, key, FFMIN(sizeof(key) - 1, var_size)); |
2020 | 2.17k | if (strncmp("scanlineimage", key, var_size) && |
2021 | 1.47k | strncmp("tiledimage", key, var_size)) { |
2022 | 931 | ret = AVERROR_PATCHWELCOME; |
2023 | 931 | goto fail; |
2024 | 931 | } |
2025 | | |
2026 | 1.24k | continue; |
2027 | 354k | } else if ((var_size = check_header_variable(s, "preview", |
2028 | 354k | "preview", 16)) >= 0) { |
2029 | 1.48k | uint32_t pw = bytestream2_get_le32(gb); |
2030 | 1.48k | uint32_t ph = bytestream2_get_le32(gb); |
2031 | 1.48k | uint64_t psize = pw * (uint64_t)ph; |
2032 | 1.48k | if (psize > INT64_MAX / 4) { |
2033 | 227 | ret = AVERROR_INVALIDDATA; |
2034 | 227 | goto fail; |
2035 | 227 | } |
2036 | 1.25k | psize *= 4; |
2037 | | |
2038 | 1.25k | if ((int64_t)psize >= bytestream2_get_bytes_left(gb)) { |
2039 | 877 | ret = AVERROR_INVALIDDATA; |
2040 | 877 | goto fail; |
2041 | 877 | } |
2042 | | |
2043 | 381 | bytestream2_skip(gb, psize); |
2044 | | |
2045 | 381 | continue; |
2046 | 1.25k | } |
2047 | | |
2048 | | // Check if there are enough bytes for a header |
2049 | 353k | if (bytestream2_get_bytes_left(gb) <= 9) { |
2050 | 6.27k | av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n"); |
2051 | 6.27k | ret = AVERROR_INVALIDDATA; |
2052 | 6.27k | goto fail; |
2053 | 6.27k | } |
2054 | | |
2055 | | // Process unknown variables |
2056 | 347k | { |
2057 | 347k | uint8_t name[256] = { 0 }; |
2058 | 347k | uint8_t type[256] = { 0 }; |
2059 | 347k | uint8_t value[8192] = { 0 }; |
2060 | 347k | int i = 0, size; |
2061 | | |
2062 | 5.70M | while (bytestream2_get_bytes_left(gb) > 0 && |
2063 | 5.70M | bytestream2_peek_byte(gb) && i < 255) { |
2064 | 5.35M | name[i++] = bytestream2_get_byte(gb); |
2065 | 5.35M | } |
2066 | | |
2067 | 347k | bytestream2_skip(gb, 1); |
2068 | 347k | i = 0; |
2069 | 2.84M | while (bytestream2_get_bytes_left(gb) > 0 && |
2070 | 2.84M | bytestream2_peek_byte(gb) && i < 255) { |
2071 | 2.50M | type[i++] = bytestream2_get_byte(gb); |
2072 | 2.50M | } |
2073 | 347k | bytestream2_skip(gb, 1); |
2074 | 347k | size = bytestream2_get_le32(gb); |
2075 | | |
2076 | 347k | bytestream2_get_buffer(gb, value, FFMIN(sizeof(value) - 1, size)); |
2077 | 347k | if (size > sizeof(value) - 1) |
2078 | 17.4k | bytestream2_skip(gb, size - (sizeof(value) - 1)); |
2079 | 347k | if (!strcmp(type, "string")) |
2080 | 125k | av_dict_set(&metadata, name, value, 0); |
2081 | 347k | } |
2082 | 347k | } |
2083 | | |
2084 | 85.6k | if (s->compression == EXR_UNKN) { |
2085 | 34.3k | av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n"); |
2086 | 34.3k | ret = AVERROR_INVALIDDATA; |
2087 | 34.3k | goto fail; |
2088 | 34.3k | } |
2089 | | |
2090 | 51.2k | if (s->is_tile) { |
2091 | 3.79k | if (s->tile_attr.xSize < 1 || s->tile_attr.ySize < 1) { |
2092 | 819 | av_log(s->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n"); |
2093 | 819 | ret = AVERROR_INVALIDDATA; |
2094 | 819 | goto fail; |
2095 | 819 | } |
2096 | 3.79k | } |
2097 | | |
2098 | 50.4k | if (bytestream2_get_bytes_left(gb) <= 0) { |
2099 | 4.68k | av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n"); |
2100 | 4.68k | ret = AVERROR_INVALIDDATA; |
2101 | 4.68k | goto fail; |
2102 | 4.68k | } |
2103 | | |
2104 | 45.7k | frame->metadata = metadata; |
2105 | | |
2106 | | // aaand we are done |
2107 | 45.7k | bytestream2_skip(gb, 1); |
2108 | 45.7k | return 0; |
2109 | 68.0k | fail: |
2110 | 68.0k | av_dict_free(&metadata); |
2111 | 68.0k | return ret; |
2112 | 50.4k | } |
2113 | | |
2114 | | static int decode_frame(AVCodecContext *avctx, AVFrame *picture, |
2115 | | int *got_frame, AVPacket *avpkt) |
2116 | 203k | { |
2117 | 203k | EXRContext *s = avctx->priv_data; |
2118 | 203k | GetByteContext *gb = &s->gb; |
2119 | 203k | uint8_t *ptr; |
2120 | | |
2121 | 203k | int i, y, ret, ymax; |
2122 | 203k | int planes; |
2123 | 203k | int out_line_size; |
2124 | 203k | int nb_blocks; /* nb scanline or nb tile */ |
2125 | 203k | uint64_t start_offset_table; |
2126 | 203k | uint64_t start_next_scanline; |
2127 | | |
2128 | 203k | bytestream2_init(gb, avpkt->data, avpkt->size); |
2129 | | |
2130 | 203k | if ((ret = decode_header(s, picture)) < 0) |
2131 | 157k | return ret; |
2132 | | |
2133 | 45.7k | if (s->compression == EXR_DWAA || |
2134 | 44.7k | s->compression == EXR_DWAB) { |
2135 | 4.60k | for (int i = 0; i<s->nb_channels; i++) { |
2136 | 3.11k | EXRChannel *channel = &s->channels[i]; |
2137 | 3.11k | if (channel->pixel_type != s->pixel_type) { |
2138 | 68 | avpriv_request_sample(s->avctx, "mixed pixel type DWA"); |
2139 | 68 | return AVERROR_PATCHWELCOME; |
2140 | 68 | } |
2141 | 3.11k | } |
2142 | 1.55k | } |
2143 | | |
2144 | 45.6k | switch (s->pixel_type) { |
2145 | 1.10k | case EXR_HALF: |
2146 | 1.10k | if (s->channel_offsets[3] >= 0) { |
2147 | 126 | if (!s->is_luma) { |
2148 | 118 | avctx->pix_fmt = AV_PIX_FMT_GBRAPF16; |
2149 | 118 | } else { |
2150 | 8 | avctx->pix_fmt = AV_PIX_FMT_YAF16; |
2151 | 8 | } |
2152 | 974 | } else { |
2153 | 974 | if (!s->is_luma) { |
2154 | 449 | avctx->pix_fmt = AV_PIX_FMT_GBRPF16; |
2155 | 525 | } else { |
2156 | 525 | avctx->pix_fmt = AV_PIX_FMT_GRAYF16; |
2157 | 525 | } |
2158 | 974 | } |
2159 | 1.10k | break; |
2160 | 38.4k | case EXR_FLOAT: |
2161 | 38.4k | if (s->channel_offsets[3] >= 0) { |
2162 | 490 | if (!s->is_luma) { |
2163 | 343 | avctx->pix_fmt = AV_PIX_FMT_GBRAPF32; |
2164 | 343 | } else { |
2165 | 147 | avctx->pix_fmt = AV_PIX_FMT_YAF32; |
2166 | 147 | } |
2167 | 37.9k | } else { |
2168 | 37.9k | if (!s->is_luma) { |
2169 | 18.1k | avctx->pix_fmt = AV_PIX_FMT_GBRPF32; |
2170 | 19.8k | } else { |
2171 | 19.8k | avctx->pix_fmt = AV_PIX_FMT_GRAYF32; |
2172 | 19.8k | } |
2173 | 37.9k | } |
2174 | 38.4k | break; |
2175 | 4.61k | case EXR_UINT: |
2176 | 4.61k | if (s->channel_offsets[3] >= 0) { |
2177 | 72 | if (!s->is_luma) { |
2178 | 0 | avctx->pix_fmt = AV_PIX_FMT_RGBA64; |
2179 | 72 | } else { |
2180 | 72 | avctx->pix_fmt = AV_PIX_FMT_YA16; |
2181 | 72 | } |
2182 | 4.54k | } else { |
2183 | 4.54k | if (!s->is_luma) { |
2184 | 0 | avctx->pix_fmt = AV_PIX_FMT_RGB48; |
2185 | 4.54k | } else { |
2186 | 4.54k | avctx->pix_fmt = AV_PIX_FMT_GRAY16; |
2187 | 4.54k | } |
2188 | 4.54k | } |
2189 | 4.61k | break; |
2190 | 1.47k | default: |
2191 | 1.47k | av_log(avctx, AV_LOG_ERROR, "Missing channel list.\n"); |
2192 | 1.47k | return AVERROR_INVALIDDATA; |
2193 | 45.6k | } |
2194 | | |
2195 | 44.1k | if (s->channel_offsets[3] >= 0) |
2196 | 688 | avctx->alpha_mode = AVALPHA_MODE_PREMULTIPLIED; |
2197 | | |
2198 | 44.1k | #if FF_API_EXR_GAMMA |
2199 | 44.1k | if (s->apply_trc_type != AVCOL_TRC_UNSPECIFIED) |
2200 | 0 | avctx->color_trc = s->apply_trc_type; |
2201 | 44.1k | else if (s->gamma > 0.9999f && s->gamma < 1.0001f) |
2202 | 44.1k | #endif |
2203 | 44.1k | avctx->color_trc = AVCOL_TRC_LINEAR; |
2204 | | |
2205 | 44.1k | switch (s->compression) { |
2206 | 2.12k | case EXR_RAW: |
2207 | 2.65k | case EXR_RLE: |
2208 | 2.68k | case EXR_ZIP1: |
2209 | 2.68k | s->scan_lines_per_block = 1; |
2210 | 2.68k | break; |
2211 | 585 | case EXR_PXR24: |
2212 | 17.8k | case EXR_ZIP16: |
2213 | 17.8k | s->scan_lines_per_block = 16; |
2214 | 17.8k | break; |
2215 | 21.8k | case EXR_PIZ: |
2216 | 22.2k | case EXR_B44: |
2217 | 22.3k | case EXR_B44A: |
2218 | 22.9k | case EXR_DWAA: |
2219 | 22.9k | s->scan_lines_per_block = 32; |
2220 | 22.9k | break; |
2221 | 398 | case EXR_DWAB: |
2222 | 398 | s->scan_lines_per_block = 256; |
2223 | 398 | break; |
2224 | 286 | default: |
2225 | 286 | avpriv_report_missing_feature(avctx, "Compression %d", s->compression); |
2226 | 286 | return AVERROR_PATCHWELCOME; |
2227 | 44.1k | } |
2228 | | |
2229 | | /* Verify the xmin, xmax, ymin and ymax before setting the actual image size. |
2230 | | * It's possible for the data window can larger or outside the display window */ |
2231 | 43.8k | if (s->xmin > s->xmax || s->ymin > s->ymax || |
2232 | 43.8k | s->ydelta == 0xFFFFFFFF || s->xdelta == 0xFFFFFFFF) { |
2233 | 1.97k | av_log(avctx, AV_LOG_ERROR, "Wrong or missing size information.\n"); |
2234 | 1.97k | return AVERROR_INVALIDDATA; |
2235 | 1.97k | } |
2236 | | |
2237 | 41.9k | if ((ret = ff_set_dimensions(avctx, s->w, s->h)) < 0) |
2238 | 3.00k | return ret; |
2239 | | |
2240 | 38.9k | ff_set_sar(s->avctx, av_d2q(av_int2float(s->sar), 255)); |
2241 | | |
2242 | 38.9k | if (avctx->skip_frame >= AVDISCARD_ALL) |
2243 | 458 | return avpkt->size; |
2244 | | |
2245 | 38.4k | s->desc = av_pix_fmt_desc_get(avctx->pix_fmt); |
2246 | 38.4k | if (!s->desc) |
2247 | 0 | return AVERROR_INVALIDDATA; |
2248 | | |
2249 | 38.4k | planes = av_pix_fmt_count_planes(avctx->pix_fmt); |
2250 | 38.4k | out_line_size = avctx->width * s->desc->comp[0].step; |
2251 | | |
2252 | 38.4k | if (s->is_tile) { |
2253 | 1.31k | if (s->tile_attr.ySize <= 0 || s->tile_attr.xSize <= 0) |
2254 | 0 | return AVERROR_INVALIDDATA; |
2255 | 1.31k | nb_blocks = ((s->xdelta + s->tile_attr.xSize - 1) / s->tile_attr.xSize) * |
2256 | 1.31k | ((s->ydelta + s->tile_attr.ySize - 1) / s->tile_attr.ySize); |
2257 | 37.1k | } else { /* scanline */ |
2258 | 37.1k | nb_blocks = (s->ydelta + s->scan_lines_per_block - 1) / |
2259 | 37.1k | s->scan_lines_per_block; |
2260 | 37.1k | } |
2261 | | |
2262 | 38.4k | if ((ret = ff_thread_get_buffer(avctx, picture, 0)) < 0) |
2263 | 18 | return ret; |
2264 | | |
2265 | 38.4k | if (bytestream2_get_bytes_left(gb)/8 < nb_blocks) |
2266 | 536 | return AVERROR_INVALIDDATA; |
2267 | | |
2268 | | // check offset table and recreate it if need |
2269 | 37.9k | if (!s->is_tile && bytestream2_peek_le64(gb) == 0) { |
2270 | 4.52k | PutByteContext offset_table_writer; |
2271 | | |
2272 | 4.52k | av_log(s->avctx, AV_LOG_DEBUG, "recreating invalid scanline offset table\n"); |
2273 | | |
2274 | 4.52k | s->offset_table = av_realloc_f(s->offset_table, nb_blocks, 8); |
2275 | 4.52k | if (!s->offset_table) |
2276 | 0 | return AVERROR(ENOMEM); |
2277 | | |
2278 | 4.52k | start_offset_table = bytestream2_tell(gb); |
2279 | 4.52k | start_next_scanline = start_offset_table + nb_blocks * 8; |
2280 | 4.52k | bytestream2_init_writer(&offset_table_writer, s->offset_table, nb_blocks * 8); |
2281 | | |
2282 | 705k | for (y = 0; y < nb_blocks; y++) { |
2283 | | /* write offset of prev scanline in offset table */ |
2284 | 701k | bytestream2_put_le64(&offset_table_writer, start_next_scanline); |
2285 | | |
2286 | | /* get len of next scanline */ |
2287 | 701k | bytestream2_seek(gb, start_next_scanline + 4, SEEK_SET);/* skip line number */ |
2288 | 701k | start_next_scanline += (bytestream2_get_le32(gb) + 8); |
2289 | 701k | } |
2290 | 4.52k | bytestream2_init(gb, s->offset_table, nb_blocks * 8); |
2291 | 4.52k | } |
2292 | | |
2293 | | // save pointer we are going to use in decode_block |
2294 | 37.9k | s->buf = avpkt->data; |
2295 | 37.9k | s->buf_size = avpkt->size; |
2296 | | |
2297 | | // Zero out the start if ymin is not 0 |
2298 | 111k | for (i = 0; i < planes; i++) { |
2299 | 73.3k | ptr = picture->data[i]; |
2300 | 863k | for (y = 0; y < FFMIN(s->ymin, s->h); y++) { |
2301 | 790k | memset(ptr, 0, out_line_size); |
2302 | 790k | ptr += picture->linesize[i]; |
2303 | 790k | } |
2304 | 73.3k | } |
2305 | | |
2306 | 37.9k | s->picture = picture; |
2307 | | |
2308 | 37.9k | avctx->execute2(avctx, decode_block, s->thread_data, NULL, nb_blocks); |
2309 | | |
2310 | 37.9k | ymax = FFMAX(0, s->ymax + 1); |
2311 | | // Zero out the end if ymax+1 is not h |
2312 | 37.9k | if (ymax < avctx->height) |
2313 | 37.9k | for (i = 0; i < planes; i++) { |
2314 | 20.6k | ptr = picture->data[i] + (ymax * picture->linesize[i]); |
2315 | 75.9M | for (y = ymax; y < avctx->height; y++) { |
2316 | 75.9M | memset(ptr, 0, out_line_size); |
2317 | 75.9M | ptr += picture->linesize[i]; |
2318 | 75.9M | } |
2319 | 20.6k | } |
2320 | | |
2321 | 37.9k | picture->pict_type = AV_PICTURE_TYPE_I; |
2322 | 37.9k | *got_frame = 1; |
2323 | | |
2324 | 37.9k | return avpkt->size; |
2325 | 37.9k | } |
2326 | | |
2327 | | static av_cold int decode_init(AVCodecContext *avctx) |
2328 | 6.54k | { |
2329 | 6.54k | EXRContext *s = avctx->priv_data; |
2330 | 6.54k | #if FF_API_EXR_GAMMA |
2331 | 6.54k | uint32_t i; |
2332 | 6.54k | union av_intfloat32 t; |
2333 | 6.54k | float one_gamma = 1.0f / s->gamma; |
2334 | 6.54k | av_csp_trc_function trc_func = NULL; |
2335 | 6.54k | #endif |
2336 | | |
2337 | 6.54k | ff_init_float2half_tables(&s->f2h_tables); |
2338 | 6.54k | ff_init_half2float_tables(&s->h2f_tables); |
2339 | | |
2340 | 6.54k | s->avctx = avctx; |
2341 | | |
2342 | 6.54k | ff_exrdsp_init(&s->dsp); |
2343 | | |
2344 | | #if HAVE_BIGENDIAN |
2345 | | ff_bswapdsp_init(&s->bbdsp); |
2346 | | #endif |
2347 | | |
2348 | 6.54k | #if FF_API_EXR_GAMMA |
2349 | 6.54k | trc_func = av_csp_trc_func_from_id(s->apply_trc_type); |
2350 | 6.54k | if (trc_func) { |
2351 | 0 | for (i = 0; i < 65536; ++i) { |
2352 | 0 | t.i = half2float(i, &s->h2f_tables); |
2353 | 0 | t.f = trc_func(t.f); |
2354 | 0 | s->gamma_table[i] = float2half(av_float2int(t.f), &s->f2h_tables); |
2355 | 0 | } |
2356 | 6.54k | } else if (one_gamma != 1.0f) { |
2357 | 0 | for (i = 0; i < 65536; ++i) { |
2358 | 0 | t.i = half2float(i, &s->h2f_tables); |
2359 | | /* If negative value we reuse half value */ |
2360 | 0 | if (t.f <= 0.0f) { |
2361 | 0 | s->gamma_table[i] = i; |
2362 | 0 | } else { |
2363 | 0 | t.f = powf(t.f, one_gamma); |
2364 | 0 | s->gamma_table[i] = float2half(t.i, &s->f2h_tables); |
2365 | 0 | } |
2366 | 0 | } |
2367 | 0 | } |
2368 | 6.54k | #endif |
2369 | | |
2370 | | // allocate thread data, used for non EXR_RAW compression types |
2371 | 6.54k | s->thread_data = av_calloc(avctx->thread_count, sizeof(*s->thread_data)); |
2372 | 6.54k | if (!s->thread_data) |
2373 | 0 | return AVERROR(ENOMEM); |
2374 | | |
2375 | 6.54k | return 0; |
2376 | 6.54k | } |
2377 | | |
2378 | | static av_cold int decode_end(AVCodecContext *avctx) |
2379 | 6.54k | { |
2380 | 6.54k | EXRContext *s = avctx->priv_data; |
2381 | 6.54k | int i; |
2382 | 13.0k | for (i = 0; i < avctx->thread_count; i++) { |
2383 | 6.54k | EXRThreadData *td = &s->thread_data[i]; |
2384 | 6.54k | av_freep(&td->uncompressed_data); |
2385 | 6.54k | av_freep(&td->tmp); |
2386 | 6.54k | av_freep(&td->bitmap); |
2387 | 6.54k | av_freep(&td->lut); |
2388 | 6.54k | av_freep(&td->he); |
2389 | 6.54k | av_freep(&td->freq); |
2390 | 6.54k | av_freep(&td->ac_data); |
2391 | 6.54k | av_freep(&td->dc_data); |
2392 | 6.54k | av_freep(&td->rle_data); |
2393 | 6.54k | av_freep(&td->rle_raw_data); |
2394 | 6.54k | ff_vlc_free(&td->vlc); |
2395 | 6.54k | } |
2396 | | |
2397 | 6.54k | av_freep(&s->thread_data); |
2398 | 6.54k | av_freep(&s->channels); |
2399 | 6.54k | av_freep(&s->offset_table); |
2400 | | |
2401 | 6.54k | return 0; |
2402 | 6.54k | } |
2403 | | |
2404 | | #define OFFSET(x) offsetof(EXRContext, x) |
2405 | | #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM |
2406 | | static const AVOption options[] = { |
2407 | | { "layer", "Set the decoding layer", OFFSET(layer), |
2408 | | AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD }, |
2409 | | { "part", "Set the decoding part", OFFSET(selected_part), |
2410 | | AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, |
2411 | | #if FF_API_EXR_GAMMA |
2412 | | { "gamma", "Set the float gamma value when decoding (deprecated, use a scaler)", OFFSET(gamma), |
2413 | | AV_OPT_TYPE_FLOAT, { .dbl = 1.0f }, 0.001, FLT_MAX, VD | AV_OPT_FLAG_DEPRECATED }, |
2414 | | |
2415 | | // XXX: Note the abuse of the enum using AVCOL_TRC_UNSPECIFIED to subsume the existing gamma option |
2416 | | { "apply_trc", "color transfer characteristics to apply to EXR linear input (deprecated, use a scaler)", OFFSET(apply_trc_type), |
2417 | | AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, AVCOL_TRC_NB-1, VD | AV_OPT_FLAG_DEPRECATED, .unit = "apply_trc_type"}, |
2418 | | { "bt709", "BT.709", 0, |
2419 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2420 | | { "gamma", "gamma", 0, |
2421 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2422 | | { "gamma22", "BT.470 M", 0, |
2423 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2424 | | { "gamma28", "BT.470 BG", 0, |
2425 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2426 | | { "smpte170m", "SMPTE 170 M", 0, |
2427 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2428 | | { "smpte240m", "SMPTE 240 M", 0, |
2429 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2430 | | { "linear", "Linear", 0, |
2431 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2432 | | { "log", "Log", 0, |
2433 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2434 | | { "log_sqrt", "Log square root", 0, |
2435 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2436 | | { "iec61966_2_4", "IEC 61966-2-4", 0, |
2437 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2438 | | { "bt1361", "BT.1361", 0, |
2439 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2440 | | { "iec61966_2_1", "IEC 61966-2-1", 0, |
2441 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2442 | | { "bt2020_10bit", "BT.2020 - 10 bit", 0, |
2443 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2444 | | { "bt2020_12bit", "BT.2020 - 12 bit", 0, |
2445 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2446 | | { "smpte2084", "SMPTE ST 2084", 0, |
2447 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST2084 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2448 | | { "smpte428_1", "SMPTE ST 428-1", 0, |
2449 | | AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST428_1 }, INT_MIN, INT_MAX, VD, .unit = "apply_trc_type"}, |
2450 | | #endif |
2451 | | |
2452 | | { NULL }, |
2453 | | }; |
2454 | | |
2455 | | static const AVClass exr_class = { |
2456 | | .class_name = "EXR", |
2457 | | .item_name = av_default_item_name, |
2458 | | .option = options, |
2459 | | .version = LIBAVUTIL_VERSION_INT, |
2460 | | }; |
2461 | | |
2462 | | const FFCodec ff_exr_decoder = { |
2463 | | .p.name = "exr", |
2464 | | CODEC_LONG_NAME("OpenEXR image"), |
2465 | | .p.type = AVMEDIA_TYPE_VIDEO, |
2466 | | .p.id = AV_CODEC_ID_EXR, |
2467 | | .priv_data_size = sizeof(EXRContext), |
2468 | | .init = decode_init, |
2469 | | .close = decode_end, |
2470 | | FF_CODEC_DECODE_CB(decode_frame), |
2471 | | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | |
2472 | | AV_CODEC_CAP_SLICE_THREADS, |
2473 | | .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, |
2474 | | .p.priv_class = &exr_class, |
2475 | | }; |