Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | * OpenEXR (.exr) image decoder |
||
3 | * Copyright (c) 2009 Jimmy Christensen |
||
4 | * |
||
5 | * This file is part of FFmpeg. |
||
6 | * |
||
7 | * FFmpeg is free software; you can redistribute it and/or |
||
8 | * modify it under the terms of the GNU Lesser General Public |
||
9 | * License as published by the Free Software Foundation; either |
||
10 | * version 2.1 of the License, or (at your option) any later version. |
||
11 | * |
||
12 | * FFmpeg is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
15 | * Lesser General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU Lesser General Public |
||
18 | * License along with FFmpeg; if not, write to the Free Software |
||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
20 | */ |
||
21 | |||
22 | /** |
||
23 | * @file |
||
24 | * OpenEXR decoder |
||
25 | * @author Jimmy Christensen |
||
26 | * |
||
27 | * For more information on the OpenEXR format, visit: |
||
28 | * http://openexr.com/ |
||
29 | * |
||
30 | * exr_flt2uint() and exr_halflt2uint() is credited to Reimar Döffinger |
||
31 | */ |
||
32 | |||
33 | #include |
||
34 | |||
35 | #include "get_bits.h" |
||
36 | #include "avcodec.h" |
||
37 | #include "bytestream.h" |
||
38 | #include "mathops.h" |
||
39 | #include "thread.h" |
||
40 | #include "libavutil/imgutils.h" |
||
41 | #include "libavutil/avassert.h" |
||
42 | |||
43 | enum ExrCompr { |
||
44 | EXR_RAW = 0, |
||
45 | EXR_RLE = 1, |
||
46 | EXR_ZIP1 = 2, |
||
47 | EXR_ZIP16 = 3, |
||
48 | EXR_PIZ = 4, |
||
49 | EXR_PXR24 = 5, |
||
50 | EXR_B44 = 6, |
||
51 | EXR_B44A = 7, |
||
52 | }; |
||
53 | |||
54 | enum ExrPixelType { |
||
55 | EXR_UINT, |
||
56 | EXR_HALF, |
||
57 | EXR_FLOAT |
||
58 | }; |
||
59 | |||
60 | typedef struct EXRChannel { |
||
61 | int xsub, ysub; |
||
62 | enum ExrPixelType pixel_type; |
||
63 | } EXRChannel; |
||
64 | |||
65 | typedef struct EXRThreadData { |
||
66 | uint8_t *uncompressed_data; |
||
67 | int uncompressed_size; |
||
68 | |||
69 | uint8_t *tmp; |
||
70 | int tmp_size; |
||
71 | |||
72 | uint8_t *bitmap; |
||
73 | uint16_t *lut; |
||
74 | } EXRThreadData; |
||
75 | |||
76 | typedef struct EXRContext { |
||
77 | AVFrame *picture; |
||
78 | int compr; |
||
79 | enum ExrPixelType pixel_type; |
||
80 | int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha |
||
81 | const AVPixFmtDescriptor *desc; |
||
82 | |||
83 | uint32_t xmax, xmin; |
||
84 | uint32_t ymax, ymin; |
||
85 | uint32_t xdelta, ydelta; |
||
86 | |||
87 | int ysize; |
||
88 | |||
89 | uint64_t scan_line_size; |
||
90 | int scan_lines_per_block; |
||
91 | |||
92 | const uint8_t *buf, *table; |
||
93 | int buf_size; |
||
94 | |||
95 | EXRChannel *channels; |
||
96 | int nb_channels; |
||
97 | |||
98 | EXRThreadData *thread_data; |
||
99 | int thread_data_size; |
||
100 | } EXRContext; |
||
101 | |||
102 | /** |
||
103 | * Converts from 32-bit float as uint32_t to uint16_t |
||
104 | * |
||
105 | * @param v 32-bit float |
||
106 | * @return normalized 16-bit unsigned int |
||
107 | */ |
||
108 | static inline uint16_t exr_flt2uint(uint32_t v) |
||
109 | { |
||
110 | unsigned int exp = v >> 23; |
||
111 | // "HACK": negative values result in exp< 0, so clipping them to 0 |
||
112 | // is also handled by this condition, avoids explicit check for sign bit. |
||
113 | if (exp<= 127 + 7 - 24) // we would shift out all bits anyway |
||
114 | return 0; |
||
115 | if (exp >= 127) |
||
116 | return 0xffff; |
||
117 | v &= 0x007fffff; |
||
118 | return (v + (1 << 23)) >> (127 + 7 - exp); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * Converts from 16-bit float as uint16_t to uint16_t |
||
123 | * |
||
124 | * @param v 16-bit float |
||
125 | * @return normalized 16-bit unsigned int |
||
126 | */ |
||
127 | static inline uint16_t exr_halflt2uint(uint16_t v) |
||
128 | { |
||
129 | unsigned exp = 14 - (v >> 10); |
||
130 | if (exp >= 14) { |
||
131 | if (exp == 14) return (v >> 9) & 1; |
||
132 | else return (v & 0x8000) ? 0 : 0xffff; |
||
133 | } |
||
134 | v <<= 6; |
||
135 | return (v + (1 << 16)) >> (exp + 1); |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Gets the size of the header variable |
||
140 | * |
||
141 | * @param **buf the current pointer location in the header where |
||
142 | * the variable data starts |
||
143 | * @param *buf_end pointer location of the end of the buffer |
||
144 | * @return size of variable data |
||
145 | */ |
||
146 | static unsigned int get_header_variable_length(const uint8_t **buf, |
||
147 | const uint8_t *buf_end) |
||
148 | { |
||
149 | unsigned int variable_buffer_data_size = bytestream_get_le32(buf); |
||
150 | if (variable_buffer_data_size >= buf_end - *buf) |
||
151 | return 0; |
||
152 | return variable_buffer_data_size; |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * Checks if the variable name corresponds with it's data type |
||
157 | * |
||
158 | * @param *avctx the AVCodecContext |
||
159 | * @param **buf the current pointer location in the header where |
||
160 | * the variable name starts |
||
161 | * @param *buf_end pointer location of the end of the buffer |
||
162 | * @param *value_name name of the varible to check |
||
163 | * @param *value_type type of the varible to check |
||
164 | * @param minimum_length minimum length of the variable data |
||
165 | * @param variable_buffer_data_size variable length read from the header |
||
166 | * after it's checked |
||
167 | * @return negative if variable is invalid |
||
168 | */ |
||
169 | static int check_header_variable(AVCodecContext *avctx, |
||
170 | const uint8_t **buf, |
||
171 | const uint8_t *buf_end, |
||
172 | const char *value_name, |
||
173 | const char *value_type, |
||
174 | unsigned int minimum_length, |
||
175 | unsigned int *variable_buffer_data_size) |
||
176 | { |
||
177 | if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) { |
||
178 | *buf += strlen(value_name)+1; |
||
179 | if (!strcmp(*buf, value_type)) { |
||
180 | *buf += strlen(value_type)+1; |
||
181 | *variable_buffer_data_size = get_header_variable_length(buf, buf_end); |
||
182 | if (!*variable_buffer_data_size) |
||
183 | av_log(avctx, AV_LOG_ERROR, "Incomplete header\n"); |
||
184 | return 1; |
||
185 | } |
||
186 | *buf -= strlen(value_name)+1; |
||
187 | av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name); |
||
188 | } |
||
189 | return -1; |
||
190 | } |
||
191 | |||
192 | static void predictor(uint8_t *src, int size) |
||
193 | { |
||
194 | uint8_t *t = src + 1; |
||
195 | uint8_t *stop = src + size; |
||
196 | |||
197 | while (t < stop) { |
||
198 | int d = (int)t[-1] + (int)t[0] - 128; |
||
199 | t[0] = d; |
||
200 | ++t; |
||
201 | } |
||
202 | } |
||
203 | |||
204 | static void reorder_pixels(uint8_t *src, uint8_t *dst, int size) |
||
205 | { |
||
206 | const int8_t *t1 = src; |
||
207 | const int8_t *t2 = src + (size + 1) / 2; |
||
208 | int8_t *s = dst; |
||
209 | int8_t *stop = s + size; |
||
210 | |||
211 | while (1) { |
||
212 | if (s < stop) |
||
213 | *(s++) = *(t1++); |
||
214 | else |
||
215 | break; |
||
216 | |||
217 | if (s < stop) |
||
218 | *(s++) = *(t2++); |
||
219 | else |
||
220 | break; |
||
221 | } |
||
222 | } |
||
223 | |||
224 | static int zip_uncompress(const uint8_t *src, int compressed_size, |
||
225 | int uncompressed_size, EXRThreadData *td) |
||
226 | { |
||
227 | unsigned long dest_len = uncompressed_size; |
||
228 | |||
229 | if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK || |
||
230 | dest_len != uncompressed_size) |
||
231 | return AVERROR(EINVAL); |
||
232 | |||
233 | predictor(td->tmp, uncompressed_size); |
||
234 | reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); |
||
235 | |||
236 | return 0; |
||
237 | } |
||
238 | |||
239 | static int rle_uncompress(const uint8_t *src, int compressed_size, |
||
240 | int uncompressed_size, EXRThreadData *td) |
||
241 | { |
||
242 | int8_t *d = (int8_t *)td->tmp; |
||
243 | const int8_t *s = (const int8_t *)src; |
||
244 | int ssize = compressed_size; |
||
245 | int dsize = uncompressed_size; |
||
246 | int8_t *dend = d + dsize; |
||
247 | int count; |
||
248 | |||
249 | while (ssize > 0) { |
||
250 | count = *s++; |
||
251 | |||
252 | if (count < 0) { |
||
253 | count = -count; |
||
254 | |||
255 | if ((dsize -= count ) < 0 || |
||
256 | (ssize -= count + 1) < 0) |
||
257 | return -1; |
||
258 | |||
259 | while (count--) |
||
260 | *d++ = *s++; |
||
261 | } else { |
||
262 | count++; |
||
263 | |||
264 | if ((dsize -= count) < 0 || |
||
265 | (ssize -= 2 ) < 0) |
||
266 | return -1; |
||
267 | |||
268 | while (count--) |
||
269 | *d++ = *s; |
||
270 | |||
271 | s++; |
||
272 | } |
||
273 | } |
||
274 | |||
275 | if (dend != d) |
||
276 | return AVERROR_INVALIDDATA; |
||
277 | |||
278 | predictor(td->tmp, uncompressed_size); |
||
279 | reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size); |
||
280 | |||
281 | return 0; |
||
282 | } |
||
283 | |||
284 | #define USHORT_RANGE (1 << 16) |
||
285 | #define BITMAP_SIZE (1 << 13) |
||
286 | |||
287 | static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut) |
||
288 | { |
||
289 | int i, k = 0; |
||
290 | |||
291 | for (i = 0; i < USHORT_RANGE; i++) { |
||
292 | if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) |
||
293 | lut[k++] = i; |
||
294 | } |
||
295 | |||
296 | i = k - 1; |
||
297 | |||
298 | memset(lut + k, 0, (USHORT_RANGE - k) * 2); |
||
299 | |||
300 | return i; |
||
301 | } |
||
302 | |||
303 | static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize) |
||
304 | { |
||
305 | int i; |
||
306 | |||
307 | for (i = 0; i < dsize; ++i) |
||
308 | dst[i] = lut[dst[i]]; |
||
309 | } |
||
310 | |||
311 | #define HUF_ENCBITS 16 // literal (value) bit length |
||
312 | #define HUF_DECBITS 14 // decoding bit size (>= 8) |
||
313 | |||
314 | #define HUF_ENCSIZE ((1 << HUF_ENCBITS) + 1) // encoding table size |
||
315 | #define HUF_DECSIZE (1 << HUF_DECBITS) // decoding table size |
||
316 | #define HUF_DECMASK (HUF_DECSIZE - 1) |
||
317 | |||
318 | typedef struct HufDec { |
||
319 | int len; |
||
320 | int lit; |
||
321 | int *p; |
||
322 | } HufDec; |
||
323 | |||
324 | static void huf_canonical_code_table(uint64_t *hcode) |
||
325 | { |
||
326 | uint64_t c, n[59] = { 0 }; |
||
327 | int i; |
||
328 | |||
329 | for (i = 0; i < HUF_ENCSIZE; ++i) |
||
330 | n[hcode[i]] += 1; |
||
331 | |||
332 | c = 0; |
||
333 | for (i = 58; i > 0; --i) { |
||
334 | uint64_t nc = ((c + n[i]) >> 1); |
||
335 | n[i] = c; |
||
336 | c = nc; |
||
337 | } |
||
338 | |||
339 | for (i = 0; i < HUF_ENCSIZE; ++i) { |
||
340 | int l = hcode[i]; |
||
341 | |||
342 | if (l > 0) |
||
343 | hcode[i] = l | (n[l]++ << 6); |
||
344 | } |
||
345 | } |
||
346 | |||
347 | #define SHORT_ZEROCODE_RUN 59 |
||
348 | #define LONG_ZEROCODE_RUN 63 |
||
349 | #define SHORTEST_LONG_RUN (2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN) |
||
350 | #define LONGEST_LONG_RUN (255 + SHORTEST_LONG_RUN) |
||
351 | |||
352 | static int huf_unpack_enc_table(GetByteContext *gb, |
||
353 | int32_t im, int32_t iM, uint64_t *hcode) |
||
354 | { |
||
355 | GetBitContext gbit; |
||
356 | |||
357 | init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb)); |
||
358 | |||
359 | for (; im <= iM; im++) { |
||
360 | uint64_t l = hcode[im] = get_bits(&gbit, 6); |
||
361 | |||
362 | if (l == LONG_ZEROCODE_RUN) { |
||
363 | int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN; |
||
364 | |||
365 | if (im + zerun > iM + 1) |
||
366 | return AVERROR_INVALIDDATA; |
||
367 | |||
368 | while (zerun--) |
||
369 | hcode[im++] = 0; |
||
370 | |||
371 | im--; |
||
372 | } else if (l >= (uint64_t) SHORT_ZEROCODE_RUN) { |
||
373 | int zerun = l - SHORT_ZEROCODE_RUN + 2; |
||
374 | |||
375 | if (im + zerun > iM + 1) |
||
376 | return AVERROR_INVALIDDATA; |
||
377 | |||
378 | while (zerun--) |
||
379 | hcode[im++] = 0; |
||
380 | |||
381 | im--; |
||
382 | } |
||
383 | } |
||
384 | |||
385 | bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8); |
||
386 | huf_canonical_code_table(hcode); |
||
387 | |||
388 | return 0; |
||
389 | } |
||
390 | |||
391 | static int huf_build_dec_table(const uint64_t *hcode, int im, |
||
392 | int iM, HufDec *hdecod) |
||
393 | { |
||
394 | for (; im <= iM; im++) { |
||
395 | uint64_t c = hcode[im] >> 6; |
||
396 | int i, l = hcode[im] & 63; |
||
397 | |||
398 | if (c >> l) |
||
399 | return AVERROR_INVALIDDATA; |
||
400 | |||
401 | if (l > HUF_DECBITS) { |
||
402 | HufDec *pl = hdecod + (c >> (l - HUF_DECBITS)); |
||
403 | if (pl->len) |
||
404 | return AVERROR_INVALIDDATA; |
||
405 | |||
406 | pl->lit++; |
||
407 | |||
408 | pl->p = av_realloc_f(pl->p, pl->lit, sizeof(int)); |
||
409 | if (!pl->p) |
||
410 | return AVERROR(ENOMEM); |
||
411 | |||
412 | pl->p[pl->lit - 1] = im; |
||
413 | } else if (l) { |
||
414 | HufDec *pl = hdecod + (c << (HUF_DECBITS - l)); |
||
415 | |||
416 | for (i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++) { |
||
417 | if (pl->len || pl->p) |
||
418 | return AVERROR_INVALIDDATA; |
||
419 | pl->len = l; |
||
420 | pl->lit = im; |
||
421 | } |
||
422 | } |
||
423 | } |
||
424 | |||
425 | return 0; |
||
426 | } |
||
427 | |||
428 | #define get_char(c, lc, gb) { \ |
||
429 | c = (c << 8) | bytestream2_get_byte(gb); \ |
||
430 | lc += 8; \ |
||
431 | } |
||
432 | |||
433 | #define get_code(po, rlc, c, lc, gb, out, oe) { \ |
||
434 | if (po == rlc) { \ |
||
435 | if (lc < 8) \ |
||
436 | get_char(c, lc, gb); \ |
||
437 | lc -= 8; \ |
||
438 | \ |
||
439 | cs = c >> lc; \ |
||
440 | \ |
||
441 | if (out + cs > oe) \ |
||
442 | return AVERROR_INVALIDDATA; \ |
||
443 | \ |
||
444 | s = out[-1]; \ |
||
445 | \ |
||
446 | while (cs-- > 0) \ |
||
447 | *out++ = s; \ |
||
448 | } else if (out < oe) { \ |
||
449 | *out++ = po; \ |
||
450 | } else { \ |
||
451 | return AVERROR_INVALIDDATA; \ |
||
452 | } \ |
||
453 | } |
||
454 | |||
455 | static int huf_decode(const uint64_t *hcode, const HufDec *hdecod, |
||
456 | GetByteContext *gb, int nbits, |
||
457 | int rlc, int no, uint16_t *out) |
||
458 | { |
||
459 | uint64_t c = 0; |
||
460 | uint16_t *outb = out; |
||
461 | uint16_t *oe = out + no; |
||
462 | const uint8_t *ie = gb->buffer + (nbits + 7) / 8; // input byte size |
||
463 | uint8_t cs, s; |
||
464 | int i, lc = 0; |
||
465 | |||
466 | while (gb->buffer < ie) { |
||
467 | get_char(c, lc, gb); |
||
468 | |||
469 | while (lc >= HUF_DECBITS) { |
||
470 | const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK]; |
||
471 | |||
472 | if (pl.len) { |
||
473 | lc -= pl.len; |
||
474 | get_code(pl.lit, rlc, c, lc, gb, out, oe); |
||
475 | } else { |
||
476 | int j; |
||
477 | |||
478 | if (!pl.p) |
||
479 | return AVERROR_INVALIDDATA; |
||
480 | |||
481 | for (j = 0; j < pl.lit; j++) { |
||
482 | int l = hcode[pl.p[j]] & 63; |
||
483 | |||
484 | while (lc < l && bytestream2_get_bytes_left(gb) > 0) |
||
485 | get_char(c, lc, gb); |
||
486 | |||
487 | if (lc >= l) { |
||
488 | if ((hcode[pl.p[j]] >> 6) == |
||
489 | ((c >> (lc - l)) & ((1LL << l) - 1))) { |
||
490 | lc -= l; |
||
491 | get_code(pl.p[j], rlc, c, lc, gb, out, oe); |
||
492 | break; |
||
493 | } |
||
494 | } |
||
495 | } |
||
496 | |||
497 | if (j == pl.lit) |
||
498 | return AVERROR_INVALIDDATA; |
||
499 | } |
||
500 | } |
||
501 | } |
||
502 | |||
503 | i = (8 - nbits) & 7; |
||
504 | c >>= i; |
||
505 | lc -= i; |
||
506 | |||
507 | while (lc > 0) { |
||
508 | const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK]; |
||
509 | |||
510 | if (pl.len) { |
||
511 | lc -= pl.len; |
||
512 | get_code(pl.lit, rlc, c, lc, gb, out, oe); |
||
513 | } else { |
||
514 | return AVERROR_INVALIDDATA; |
||
515 | } |
||
516 | } |
||
517 | |||
518 | if (out - outb != no) |
||
519 | return AVERROR_INVALIDDATA; |
||
520 | return 0; |
||
521 | } |
||
522 | |||
523 | static int huf_uncompress(GetByteContext *gb, |
||
524 | uint16_t *dst, int dst_size) |
||
525 | { |
||
526 | int32_t src_size, im, iM; |
||
527 | uint32_t nBits; |
||
528 | uint64_t *freq; |
||
529 | HufDec *hdec; |
||
530 | int ret, i; |
||
531 | |||
532 | src_size = bytestream2_get_le32(gb); |
||
533 | im = bytestream2_get_le32(gb); |
||
534 | iM = bytestream2_get_le32(gb); |
||
535 | bytestream2_skip(gb, 4); |
||
536 | nBits = bytestream2_get_le32(gb); |
||
537 | if (im < 0 || im >= HUF_ENCSIZE || |
||
538 | iM < 0 || iM >= HUF_ENCSIZE || |
||
539 | src_size < 0) |
||
540 | return AVERROR_INVALIDDATA; |
||
541 | |||
542 | bytestream2_skip(gb, 4); |
||
543 | |||
544 | freq = av_calloc(HUF_ENCSIZE, sizeof(*freq)); |
||
545 | hdec = av_calloc(HUF_DECSIZE, sizeof(*hdec)); |
||
546 | if (!freq || !hdec) { |
||
547 | ret = AVERROR(ENOMEM); |
||
548 | goto fail; |
||
549 | } |
||
550 | |||
551 | if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0) |
||
552 | goto fail; |
||
553 | |||
554 | if (nBits > 8 * bytestream2_get_bytes_left(gb)) { |
||
555 | ret = AVERROR_INVALIDDATA; |
||
556 | goto fail; |
||
557 | } |
||
558 | |||
559 | if ((ret = huf_build_dec_table(freq, im, iM, hdec)) < 0) |
||
560 | goto fail; |
||
561 | ret = huf_decode(freq, hdec, gb, nBits, iM, dst_size, dst); |
||
562 | |||
563 | fail: |
||
564 | for (i = 0; i < HUF_DECSIZE; i++) { |
||
565 | if (hdec) |
||
566 | av_freep(&hdec[i].p); |
||
567 | } |
||
568 | |||
569 | av_free(freq); |
||
570 | av_free(hdec); |
||
571 | |||
572 | return ret; |
||
573 | } |
||
574 | |||
575 | static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) |
||
576 | { |
||
577 | int16_t ls = l; |
||
578 | int16_t hs = h; |
||
579 | int hi = hs; |
||
580 | int ai = ls + (hi & 1) + (hi >> 1); |
||
581 | int16_t as = ai; |
||
582 | int16_t bs = ai - hi; |
||
583 | |||
584 | *a = as; |
||
585 | *b = bs; |
||
586 | } |
||
587 | |||
588 | #define NBITS 16 |
||
589 | #define A_OFFSET (1 << (NBITS - 1)) |
||
590 | #define MOD_MASK ((1 << NBITS) - 1) |
||
591 | |||
592 | static inline void wdec16(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b) |
||
593 | { |
||
594 | int m = l; |
||
595 | int d = h; |
||
596 | int bb = (m - (d >> 1)) & MOD_MASK; |
||
597 | int aa = (d + bb - A_OFFSET) & MOD_MASK; |
||
598 | *b = bb; |
||
599 | *a = aa; |
||
600 | } |
||
601 | |||
602 | static void wav_decode(uint16_t *in, int nx, int ox, |
||
603 | int ny, int oy, uint16_t mx) |
||
604 | { |
||
605 | int w14 = (mx < (1 << 14)); |
||
606 | int n = (nx > ny) ? ny: nx; |
||
607 | int p = 1; |
||
608 | int p2; |
||
609 | |||
610 | while (p <= n) |
||
611 | p <<= 1; |
||
612 | |||
613 | p >>= 1; |
||
614 | p2 = p; |
||
615 | p >>= 1; |
||
616 | |||
617 | while (p >= 1) { |
||
618 | uint16_t *py = in; |
||
619 | uint16_t *ey = in + oy * (ny - p2); |
||
620 | uint16_t i00, i01, i10, i11; |
||
621 | int oy1 = oy * p; |
||
622 | int oy2 = oy * p2; |
||
623 | int ox1 = ox * p; |
||
624 | int ox2 = ox * p2; |
||
625 | |||
626 | for (; py <= ey; py += oy2) { |
||
627 | uint16_t *px = py; |
||
628 | uint16_t *ex = py + ox * (nx - p2); |
||
629 | |||
630 | for (; px <= ex; px += ox2) { |
||
631 | uint16_t *p01 = px + ox1; |
||
632 | uint16_t *p10 = px + oy1; |
||
633 | uint16_t *p11 = p10 + ox1; |
||
634 | |||
635 | if (w14) { |
||
636 | wdec14(*px, *p10, &i00, &i10); |
||
637 | wdec14(*p01, *p11, &i01, &i11); |
||
638 | wdec14(i00, i01, px, p01); |
||
639 | wdec14(i10, i11, p10, p11); |
||
640 | } else { |
||
641 | wdec16(*px, *p10, &i00, &i10); |
||
642 | wdec16(*p01, *p11, &i01, &i11); |
||
643 | wdec16(i00, i01, px, p01); |
||
644 | wdec16(i10, i11, p10, p11); |
||
645 | } |
||
646 | } |
||
647 | |||
648 | if (nx & p) { |
||
649 | uint16_t *p10 = px + oy1; |
||
650 | |||
651 | if (w14) |
||
652 | wdec14(*px, *p10, &i00, p10); |
||
653 | else |
||
654 | wdec16(*px, *p10, &i00, p10); |
||
655 | |||
656 | *px = i00; |
||
657 | } |
||
658 | } |
||
659 | |||
660 | if (ny & p) { |
||
661 | uint16_t *px = py; |
||
662 | uint16_t *ex = py + ox * (nx - p2); |
||
663 | |||
664 | for (; px <= ex; px += ox2) { |
||
665 | uint16_t *p01 = px + ox1; |
||
666 | |||
667 | if (w14) |
||
668 | wdec14(*px, *p01, &i00, p01); |
||
669 | else |
||
670 | wdec16(*px, *p01, &i00, p01); |
||
671 | |||
672 | *px = i00; |
||
673 | } |
||
674 | } |
||
675 | |||
676 | p2 = p; |
||
677 | p >>= 1; |
||
678 | } |
||
679 | } |
||
680 | |||
681 | static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, int dsize, EXRThreadData *td) |
||
682 | { |
||
683 | GetByteContext gb; |
||
684 | uint16_t maxval, min_non_zero, max_non_zero; |
||
685 | uint16_t *ptr, *tmp = (uint16_t *)td->tmp; |
||
686 | int8_t *out; |
||
687 | int ret, i, j; |
||
688 | |||
689 | if (!td->bitmap) |
||
690 | td->bitmap = av_malloc(BITMAP_SIZE); |
||
691 | if (!td->lut) |
||
692 | td->lut = av_malloc(1 << 17); |
||
693 | if (!td->bitmap || !td->lut) |
||
694 | return AVERROR(ENOMEM); |
||
695 | |||
696 | bytestream2_init(&gb, src, ssize); |
||
697 | min_non_zero = bytestream2_get_le16(&gb); |
||
698 | max_non_zero = bytestream2_get_le16(&gb); |
||
699 | |||
700 | if (max_non_zero >= BITMAP_SIZE) |
||
701 | return AVERROR_INVALIDDATA; |
||
702 | |||
703 | memset(td->bitmap, 0, FFMIN(min_non_zero, BITMAP_SIZE)); |
||
704 | if (min_non_zero <= max_non_zero) |
||
705 | bytestream2_get_buffer(&gb, td->bitmap + min_non_zero, |
||
706 | max_non_zero - min_non_zero + 1); |
||
707 | memset(td->bitmap + max_non_zero, 0, BITMAP_SIZE - max_non_zero); |
||
708 | |||
709 | maxval = reverse_lut(td->bitmap, td->lut); |
||
710 | |||
711 | ret = huf_uncompress(&gb, tmp, dsize / sizeof(int16_t)); |
||
712 | if (ret) |
||
713 | return ret; |
||
714 | |||
715 | ptr = tmp; |
||
716 | for (i = 0; i < s->nb_channels; i++) { |
||
717 | EXRChannel *channel = &s->channels[i]; |
||
718 | int size = channel->pixel_type; |
||
719 | |||
720 | for (j = 0; j < size; j++) |
||
721 | wav_decode(ptr + j, s->xdelta, size, s->ysize, s->xdelta * size, maxval); |
||
722 | ptr += s->xdelta * s->ysize * size; |
||
723 | } |
||
724 | |||
725 | apply_lut(td->lut, tmp, dsize / sizeof(int16_t)); |
||
726 | |||
727 | out = td->uncompressed_data; |
||
728 | for (i = 0; i < s->ysize; i++) { |
||
729 | for (j = 0; j < s->nb_channels; j++) { |
||
730 | uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta; |
||
731 | memcpy(out, in, s->xdelta * 2); |
||
732 | out += s->xdelta * 2; |
||
733 | } |
||
734 | } |
||
735 | |||
736 | return 0; |
||
737 | } |
||
738 | |||
739 | static int pxr24_uncompress(EXRContext *s, const uint8_t *src, |
||
740 | int compressed_size, int uncompressed_size, |
||
741 | EXRThreadData *td) |
||
742 | { |
||
743 | unsigned long dest_len = uncompressed_size; |
||
744 | const uint8_t *in = td->tmp; |
||
745 | uint8_t *out; |
||
746 | int c, i, j; |
||
747 | |||
748 | if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK || |
||
749 | dest_len != uncompressed_size) |
||
750 | return AVERROR(EINVAL); |
||
751 | |||
752 | out = td->uncompressed_data; |
||
753 | for (i = 0; i < s->ysize; i++) { |
||
754 | for (c = 0; c < s->nb_channels; c++) { |
||
755 | EXRChannel *channel = &s->channels[c]; |
||
756 | const uint8_t *ptr[4]; |
||
757 | uint32_t pixel = 0; |
||
758 | |||
759 | switch (channel->pixel_type) { |
||
760 | case EXR_FLOAT: |
||
761 | ptr[0] = in; |
||
762 | ptr[1] = ptr[0] + s->xdelta; |
||
763 | ptr[2] = ptr[1] + s->xdelta; |
||
764 | in = ptr[2] + s->xdelta; |
||
765 | |||
766 | for (j = 0; j < s->xdelta; ++j) { |
||
767 | uint32_t diff = (*(ptr[0]++) << 24) | |
||
768 | (*(ptr[1]++) << 16) | |
||
769 | (*(ptr[2]++) << 8); |
||
770 | pixel += diff; |
||
771 | bytestream_put_le32(&out, pixel); |
||
772 | } |
||
773 | break; |
||
774 | case EXR_HALF: |
||
775 | ptr[0] = in; |
||
776 | ptr[1] = ptr[0] + s->xdelta; |
||
777 | in = ptr[1] + s->xdelta; |
||
778 | for (j = 0; j < s->xdelta; j++) { |
||
779 | uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++); |
||
780 | |||
781 | pixel += diff; |
||
782 | bytestream_put_le16(&out, pixel); |
||
783 | } |
||
784 | break; |
||
785 | default: |
||
786 | av_assert1(0); |
||
787 | } |
||
788 | } |
||
789 | } |
||
790 | |||
791 | return 0; |
||
792 | } |
||
793 | |||
794 | static int decode_block(AVCodecContext *avctx, void *tdata, |
||
795 | int jobnr, int threadnr) |
||
796 | { |
||
797 | EXRContext *s = avctx->priv_data; |
||
798 | AVFrame *const p = s->picture; |
||
799 | EXRThreadData *td = &s->thread_data[threadnr]; |
||
800 | const uint8_t *channel_buffer[4] = { 0 }; |
||
801 | const uint8_t *buf = s->buf; |
||
802 | uint64_t line_offset, uncompressed_size; |
||
803 | uint32_t xdelta = s->xdelta; |
||
804 | uint16_t *ptr_x; |
||
805 | uint8_t *ptr; |
||
806 | int32_t data_size, line; |
||
807 | const uint8_t *src; |
||
808 | int axmax = (avctx->width - (s->xmax + 1)) * 2 * s->desc->nb_components; |
||
809 | int bxmin = s->xmin * 2 * s->desc->nb_components; |
||
810 | int i, x, buf_size = s->buf_size; |
||
811 | int av_unused ret; |
||
812 | |||
813 | line_offset = AV_RL64(s->table + jobnr * 8); |
||
814 | // Check if the buffer has the required bytes needed from the offset |
||
815 | if (line_offset > buf_size - 8) |
||
816 | return AVERROR_INVALIDDATA; |
||
817 | |||
818 | src = buf + line_offset + 8; |
||
819 | line = AV_RL32(src - 8); |
||
820 | if (line < s->ymin || line > s->ymax) |
||
821 | return AVERROR_INVALIDDATA; |
||
822 | |||
823 | data_size = AV_RL32(src - 4); |
||
824 | if (data_size <= 0 || data_size > buf_size) |
||
825 | return AVERROR_INVALIDDATA; |
||
826 | |||
827 | s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1); |
||
828 | uncompressed_size = s->scan_line_size * s->ysize; |
||
829 | if ((s->compr == EXR_RAW && (data_size != uncompressed_size || |
||
830 | line_offset > buf_size - uncompressed_size)) || |
||
831 | (s->compr != EXR_RAW && (data_size > uncompressed_size || |
||
832 | line_offset > buf_size - data_size))) { |
||
833 | return AVERROR_INVALIDDATA; |
||
834 | } |
||
835 | |||
836 | if (data_size < uncompressed_size) { |
||
837 | av_fast_padded_malloc(&td->uncompressed_data, &td->uncompressed_size, uncompressed_size); |
||
838 | av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size); |
||
839 | if (!td->uncompressed_data || !td->tmp) |
||
840 | return AVERROR(ENOMEM); |
||
841 | |||
842 | switch (s->compr) { |
||
843 | case EXR_ZIP1: |
||
844 | case EXR_ZIP16: |
||
845 | ret = zip_uncompress(src, data_size, uncompressed_size, td); |
||
846 | break; |
||
847 | case EXR_PIZ: |
||
848 | ret = piz_uncompress(s, src, data_size, uncompressed_size, td); |
||
849 | break; |
||
850 | case EXR_PXR24: |
||
851 | ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td); |
||
852 | break; |
||
853 | case EXR_RLE: |
||
854 | ret = rle_uncompress(src, data_size, uncompressed_size, td); |
||
855 | } |
||
856 | |||
857 | src = td->uncompressed_data; |
||
858 | } |
||
859 | |||
860 | channel_buffer[0] = src + xdelta * s->channel_offsets[0]; |
||
861 | channel_buffer[1] = src + xdelta * s->channel_offsets[1]; |
||
862 | channel_buffer[2] = src + xdelta * s->channel_offsets[2]; |
||
863 | if (s->channel_offsets[3] >= 0) |
||
864 | channel_buffer[3] = src + xdelta * s->channel_offsets[3]; |
||
865 | |||
866 | ptr = p->data[0] + line * p->linesize[0]; |
||
867 | for (i = 0; i < s->scan_lines_per_block && line + i <= s->ymax; i++, ptr += p->linesize[0]) { |
||
868 | const uint8_t *r, *g, *b, *a; |
||
869 | |||
870 | r = channel_buffer[0]; |
||
871 | g = channel_buffer[1]; |
||
872 | b = channel_buffer[2]; |
||
873 | if (channel_buffer[3]) |
||
874 | a = channel_buffer[3]; |
||
875 | |||
876 | ptr_x = (uint16_t *)ptr; |
||
877 | |||
878 | // Zero out the start if xmin is not 0 |
||
879 | memset(ptr_x, 0, bxmin); |
||
880 | ptr_x += s->xmin * s->desc->nb_components; |
||
881 | if (s->pixel_type == EXR_FLOAT) { |
||
882 | // 32-bit |
||
883 | for (x = 0; x < xdelta; x++) { |
||
884 | *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r)); |
||
885 | *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g)); |
||
886 | *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b)); |
||
887 | if (channel_buffer[3]) |
||
888 | *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a)); |
||
889 | } |
||
890 | } else { |
||
891 | // 16-bit |
||
892 | for (x = 0; x < xdelta; x++) { |
||
893 | *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r)); |
||
894 | *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g)); |
||
895 | *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b)); |
||
896 | if (channel_buffer[3]) |
||
897 | *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a)); |
||
898 | } |
||
899 | } |
||
900 | |||
901 | // Zero out the end if xmax+1 is not w |
||
902 | memset(ptr_x, 0, axmax); |
||
903 | |||
904 | channel_buffer[0] += s->scan_line_size; |
||
905 | channel_buffer[1] += s->scan_line_size; |
||
906 | channel_buffer[2] += s->scan_line_size; |
||
907 | if (channel_buffer[3]) |
||
908 | channel_buffer[3] += s->scan_line_size; |
||
909 | } |
||
910 | |||
911 | return 0; |
||
912 | } |
||
913 | |||
914 | static int decode_frame(AVCodecContext *avctx, |
||
915 | void *data, |
||
916 | int *got_frame, |
||
917 | AVPacket *avpkt) |
||
918 | { |
||
919 | const uint8_t *buf = avpkt->data; |
||
920 | unsigned int buf_size = avpkt->size; |
||
921 | const uint8_t *buf_end = buf + buf_size; |
||
922 | |||
923 | EXRContext *const s = avctx->priv_data; |
||
924 | ThreadFrame frame = { .f = data }; |
||
925 | AVFrame *picture = data; |
||
926 | uint8_t *ptr; |
||
927 | |||
928 | int i, y, magic_number, version, flags, ret; |
||
929 | int w = 0; |
||
930 | int h = 0; |
||
931 | |||
932 | int out_line_size; |
||
933 | int scan_line_blocks; |
||
934 | |||
935 | unsigned int current_channel_offset = 0; |
||
936 | |||
937 | s->xmin = ~0; |
||
938 | s->xmax = ~0; |
||
939 | s->ymin = ~0; |
||
940 | s->ymax = ~0; |
||
941 | s->xdelta = ~0; |
||
942 | s->ydelta = ~0; |
||
943 | s->channel_offsets[0] = -1; |
||
944 | s->channel_offsets[1] = -1; |
||
945 | s->channel_offsets[2] = -1; |
||
946 | s->channel_offsets[3] = -1; |
||
947 | s->pixel_type = -1; |
||
948 | s->nb_channels = 0; |
||
949 | s->compr = -1; |
||
950 | s->buf = buf; |
||
951 | s->buf_size = buf_size; |
||
952 | |||
953 | if (buf_size < 10) { |
||
954 | av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n"); |
||
955 | return AVERROR_INVALIDDATA; |
||
956 | } |
||
957 | |||
958 | magic_number = bytestream_get_le32(&buf); |
||
959 | if (magic_number != 20000630) { // As per documentation of OpenEXR it's supposed to be int 20000630 little-endian |
||
960 | av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number); |
||
961 | return AVERROR_INVALIDDATA; |
||
962 | } |
||
963 | |||
964 | version = bytestream_get_byte(&buf); |
||
965 | if (version != 2) { |
||
966 | avpriv_report_missing_feature(avctx, "Version %d", version); |
||
967 | return AVERROR_PATCHWELCOME; |
||
968 | } |
||
969 | |||
970 | flags = bytestream_get_le24(&buf); |
||
971 | if (flags & 0x2) { |
||
972 | avpriv_report_missing_feature(avctx, "Tile support"); |
||
973 | return AVERROR_PATCHWELCOME; |
||
974 | } |
||
975 | |||
976 | // Parse the header |
||
977 | while (buf < buf_end && buf[0]) { |
||
978 | unsigned int variable_buffer_data_size; |
||
979 | // Process the channel list |
||
980 | if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) { |
||
981 | const uint8_t *channel_list_end; |
||
982 | if (!variable_buffer_data_size) |
||
983 | return AVERROR_INVALIDDATA; |
||
984 | |||
985 | channel_list_end = buf + variable_buffer_data_size; |
||
986 | while (channel_list_end - buf >= 19) { |
||
987 | EXRChannel *channel; |
||
988 | enum ExrPixelType current_pixel_type; |
||
989 | int channel_index = -1; |
||
990 | int xsub, ysub; |
||
991 | |||
992 | if (!strcmp(buf, "R")) |
||
993 | channel_index = 0; |
||
994 | else if (!strcmp(buf, "G")) |
||
995 | channel_index = 1; |
||
996 | else if (!strcmp(buf, "B")) |
||
997 | channel_index = 2; |
||
998 | else if (!strcmp(buf, "A")) |
||
999 | channel_index = 3; |
||
1000 | else |
||
1001 | av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf); |
||
1002 | |||
1003 | while (bytestream_get_byte(&buf) && buf < channel_list_end) |
||
1004 | continue; /* skip */ |
||
1005 | |||
1006 | if (channel_list_end - * &buf < 4) { |
||
1007 | av_log(avctx, AV_LOG_ERROR, "Incomplete header\n"); |
||
1008 | return AVERROR_INVALIDDATA; |
||
1009 | } |
||
1010 | |||
1011 | current_pixel_type = bytestream_get_le32(&buf); |
||
1012 | if (current_pixel_type > 2) { |
||
1013 | av_log(avctx, AV_LOG_ERROR, "Unknown pixel type\n"); |
||
1014 | return AVERROR_INVALIDDATA; |
||
1015 | } |
||
1016 | |||
1017 | buf += 4; |
||
1018 | xsub = bytestream_get_le32(&buf); |
||
1019 | ysub = bytestream_get_le32(&buf); |
||
1020 | if (xsub != 1 || ysub != 1) { |
||
1021 | avpriv_report_missing_feature(avctx, "Subsampling %dx%d", xsub, ysub); |
||
1022 | return AVERROR_PATCHWELCOME; |
||
1023 | } |
||
1024 | |||
1025 | if (channel_index >= 0) { |
||
1026 | if (s->pixel_type != -1 && s->pixel_type != current_pixel_type) { |
||
1027 | av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n"); |
||
1028 | return AVERROR_INVALIDDATA; |
||
1029 | } |
||
1030 | s->pixel_type = current_pixel_type; |
||
1031 | s->channel_offsets[channel_index] = current_channel_offset; |
||
1032 | } |
||
1033 | |||
1034 | s->channels = av_realloc_f(s->channels, ++s->nb_channels, sizeof(EXRChannel)); |
||
1035 | if (!s->channels) |
||
1036 | return AVERROR(ENOMEM); |
||
1037 | channel = &s->channels[s->nb_channels - 1]; |
||
1038 | channel->pixel_type = current_pixel_type; |
||
1039 | channel->xsub = xsub; |
||
1040 | channel->ysub = ysub; |
||
1041 | |||
1042 | current_channel_offset += 1 << current_pixel_type; |
||
1043 | } |
||
1044 | |||
1045 | /* Check if all channels are set with an offset or if the channels |
||
1046 | * are causing an overflow */ |
||
1047 | |||
1048 | if (FFMIN3(s->channel_offsets[0], |
||
1049 | s->channel_offsets[1], |
||
1050 | s->channel_offsets[2]) < 0) { |
||
1051 | if (s->channel_offsets[0] < 0) |
||
1052 | av_log(avctx, AV_LOG_ERROR, "Missing red channel\n"); |
||
1053 | if (s->channel_offsets[1] < 0) |
||
1054 | av_log(avctx, AV_LOG_ERROR, "Missing green channel\n"); |
||
1055 | if (s->channel_offsets[2] < 0) |
||
1056 | av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n"); |
||
1057 | return AVERROR_INVALIDDATA; |
||
1058 | } |
||
1059 | |||
1060 | buf = channel_list_end; |
||
1061 | continue; |
||
1062 | } else if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) { |
||
1063 | if (!variable_buffer_data_size) |
||
1064 | return AVERROR_INVALIDDATA; |
||
1065 | |||
1066 | s->xmin = AV_RL32(buf); |
||
1067 | s->ymin = AV_RL32(buf + 4); |
||
1068 | s->xmax = AV_RL32(buf + 8); |
||
1069 | s->ymax = AV_RL32(buf + 12); |
||
1070 | s->xdelta = (s->xmax - s->xmin) + 1; |
||
1071 | s->ydelta = (s->ymax - s->ymin) + 1; |
||
1072 | |||
1073 | buf += variable_buffer_data_size; |
||
1074 | continue; |
||
1075 | } else if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) { |
||
1076 | if (!variable_buffer_data_size) |
||
1077 | return AVERROR_INVALIDDATA; |
||
1078 | |||
1079 | w = AV_RL32(buf + 8) + 1; |
||
1080 | h = AV_RL32(buf + 12) + 1; |
||
1081 | |||
1082 | buf += variable_buffer_data_size; |
||
1083 | continue; |
||
1084 | } else if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) { |
||
1085 | if (!variable_buffer_data_size) |
||
1086 | return AVERROR_INVALIDDATA; |
||
1087 | |||
1088 | av_log(avctx, AV_LOG_DEBUG, "line order : %d\n", *buf); |
||
1089 | if (*buf > 2) { |
||
1090 | av_log(avctx, AV_LOG_ERROR, "Unknown line order\n"); |
||
1091 | return AVERROR_INVALIDDATA; |
||
1092 | } |
||
1093 | |||
1094 | buf += variable_buffer_data_size; |
||
1095 | continue; |
||
1096 | } else if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) { |
||
1097 | if (!variable_buffer_data_size) |
||
1098 | return AVERROR_INVALIDDATA; |
||
1099 | |||
1100 | avctx->sample_aspect_ratio = av_d2q(av_int2float(AV_RL32(buf)), 255); |
||
1101 | |||
1102 | buf += variable_buffer_data_size; |
||
1103 | continue; |
||
1104 | } else if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) { |
||
1105 | if (!variable_buffer_data_size) |
||
1106 | return AVERROR_INVALIDDATA; |
||
1107 | |||
1108 | if (s->compr == -1) |
||
1109 | s->compr = *buf; |
||
1110 | else |
||
1111 | av_log(avctx, AV_LOG_WARNING, "Found more than one compression attribute\n"); |
||
1112 | |||
1113 | buf += variable_buffer_data_size; |
||
1114 | continue; |
||
1115 | } |
||
1116 | |||
1117 | // Check if there is enough bytes for a header |
||
1118 | if (buf_end - buf <= 9) { |
||
1119 | av_log(avctx, AV_LOG_ERROR, "Incomplete header\n"); |
||
1120 | return AVERROR_INVALIDDATA; |
||
1121 | } |
||
1122 | |||
1123 | // Process unknown variables |
||
1124 | for (i = 0; i < 2; i++) { |
||
1125 | // Skip variable name/type |
||
1126 | while (++buf < buf_end) |
||
1127 | if (buf[0] == 0x0) |
||
1128 | break; |
||
1129 | } |
||
1130 | buf++; |
||
1131 | // Skip variable length |
||
1132 | if (buf_end - buf >= 5) { |
||
1133 | variable_buffer_data_size = get_header_variable_length(&buf, buf_end); |
||
1134 | if (!variable_buffer_data_size) { |
||
1135 | av_log(avctx, AV_LOG_ERROR, "Incomplete header\n"); |
||
1136 | return AVERROR_INVALIDDATA; |
||
1137 | } |
||
1138 | buf += variable_buffer_data_size; |
||
1139 | } |
||
1140 | } |
||
1141 | |||
1142 | if (s->compr == -1) { |
||
1143 | av_log(avctx, AV_LOG_ERROR, "Missing compression attribute\n"); |
||
1144 | return AVERROR_INVALIDDATA; |
||
1145 | } |
||
1146 | |||
1147 | if (buf >= buf_end) { |
||
1148 | av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n"); |
||
1149 | return AVERROR_INVALIDDATA; |
||
1150 | } |
||
1151 | buf++; |
||
1152 | |||
1153 | switch (s->pixel_type) { |
||
1154 | case EXR_FLOAT: |
||
1155 | case EXR_HALF: |
||
1156 | if (s->channel_offsets[3] >= 0) |
||
1157 | avctx->pix_fmt = AV_PIX_FMT_RGBA64; |
||
1158 | else |
||
1159 | avctx->pix_fmt = AV_PIX_FMT_RGB48; |
||
1160 | break; |
||
1161 | case EXR_UINT: |
||
1162 | avpriv_request_sample(avctx, "32-bit unsigned int"); |
||
1163 | return AVERROR_PATCHWELCOME; |
||
1164 | default: |
||
1165 | av_log(avctx, AV_LOG_ERROR, "Missing channel list\n"); |
||
1166 | return AVERROR_INVALIDDATA; |
||
1167 | } |
||
1168 | |||
1169 | switch (s->compr) { |
||
1170 | case EXR_RAW: |
||
1171 | case EXR_RLE: |
||
1172 | case EXR_ZIP1: |
||
1173 | s->scan_lines_per_block = 1; |
||
1174 | break; |
||
1175 | case EXR_PXR24: |
||
1176 | case EXR_ZIP16: |
||
1177 | s->scan_lines_per_block = 16; |
||
1178 | break; |
||
1179 | case EXR_PIZ: |
||
1180 | s->scan_lines_per_block = 32; |
||
1181 | break; |
||
1182 | default: |
||
1183 | avpriv_report_missing_feature(avctx, "Compression %d", s->compr); |
||
1184 | return AVERROR_PATCHWELCOME; |
||
1185 | } |
||
1186 | |||
1187 | if (av_image_check_size(w, h, 0, avctx)) |
||
1188 | return AVERROR_INVALIDDATA; |
||
1189 | |||
1190 | // Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size |
||
1191 | if (s->xmin > s->xmax || |
||
1192 | s->ymin > s->ymax || |
||
1193 | s->xdelta != s->xmax - s->xmin + 1 || |
||
1194 | s->xmax >= w || s->ymax >= h) { |
||
1195 | av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n"); |
||
1196 | return AVERROR_INVALIDDATA; |
||
1197 | } |
||
1198 | |||
1199 | if (w != avctx->width || h != avctx->height) { |
||
1200 | avcodec_set_dimensions(avctx, w, h); |
||
1201 | } |
||
1202 | |||
1203 | s->desc = av_pix_fmt_desc_get(avctx->pix_fmt); |
||
1204 | out_line_size = avctx->width * 2 * s->desc->nb_components; |
||
1205 | s->scan_line_size = s->xdelta * current_channel_offset; |
||
1206 | scan_line_blocks = (s->ydelta + s->scan_lines_per_block - 1) / s->scan_lines_per_block; |
||
1207 | |||
1208 | if (s->compr != EXR_RAW) { |
||
1209 | size_t thread_data_size, prev_size; |
||
1210 | EXRThreadData *m; |
||
1211 | |||
1212 | prev_size = s->thread_data_size; |
||
1213 | if (av_size_mult(avctx->thread_count, sizeof(EXRThreadData), &thread_data_size)) |
||
1214 | return AVERROR(EINVAL); |
||
1215 | |||
1216 | m = av_fast_realloc(s->thread_data, &s->thread_data_size, thread_data_size); |
||
1217 | if (!m) |
||
1218 | return AVERROR(ENOMEM); |
||
1219 | s->thread_data = m; |
||
1220 | memset(s->thread_data + prev_size, 0, s->thread_data_size - prev_size); |
||
1221 | } |
||
1222 | |||
1223 | if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) |
||
1224 | return ret; |
||
1225 | |||
1226 | if (buf_end - buf < scan_line_blocks * 8) |
||
1227 | return AVERROR_INVALIDDATA; |
||
1228 | s->table = buf; |
||
1229 | ptr = picture->data[0]; |
||
1230 | |||
1231 | // Zero out the start if ymin is not 0 |
||
1232 | for (y = 0; y < s->ymin; y++) { |
||
1233 | memset(ptr, 0, out_line_size); |
||
1234 | ptr += picture->linesize[0]; |
||
1235 | } |
||
1236 | |||
1237 | s->picture = picture; |
||
1238 | avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks); |
||
1239 | |||
1240 | // Zero out the end if ymax+1 is not h |
||
1241 | for (y = s->ymax + 1; y < avctx->height; y++) { |
||
1242 | memset(ptr, 0, out_line_size); |
||
1243 | ptr += picture->linesize[0]; |
||
1244 | } |
||
1245 | |||
1246 | picture->pict_type = AV_PICTURE_TYPE_I; |
||
1247 | *got_frame = 1; |
||
1248 | |||
1249 | return buf_size; |
||
1250 | } |
||
1251 | |||
1252 | static av_cold int decode_end(AVCodecContext *avctx) |
||
1253 | { |
||
1254 | EXRContext *s = avctx->priv_data; |
||
1255 | int i; |
||
1256 | |||
1257 | for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) { |
||
1258 | EXRThreadData *td = &s->thread_data[i]; |
||
1259 | av_freep(&td->uncompressed_data); |
||
1260 | av_freep(&td->tmp); |
||
1261 | av_freep(&td->bitmap); |
||
1262 | av_freep(&td->lut); |
||
1263 | } |
||
1264 | |||
1265 | av_freep(&s->thread_data); |
||
1266 | s->thread_data_size = 0; |
||
1267 | av_freep(&s->channels); |
||
1268 | |||
1269 | return 0; |
||
1270 | } |
||
1271 | |||
1272 | AVCodec ff_exr_decoder = { |
||
1273 | .name = "exr", |
||
1274 | .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"), |
||
1275 | .type = AVMEDIA_TYPE_VIDEO, |
||
1276 | .id = AV_CODEC_ID_EXR, |
||
1277 | .priv_data_size = sizeof(EXRContext), |
||
1278 | .close = decode_end, |
||
1279 | .decode = decode_frame, |
||
1280 | .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS, |
||
1281 | };>>>>>>>=>>>>>><>>>>>>>=>>>=>>><>>><>><>><>>>>>>>>=>><>=>=>=>=><=>=>><>>><>><>>>>>>>><>><>>>>>>><>><>><>=>=>><>>>><>><>>><>>><>><>>>>>>>>>><>=><=>><>=>> |