FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exr.c
Go to the documentation of this file.
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 <zlib.h>
34 
35 #include "avcodec.h"
36 #include "bytestream.h"
37 #include "mathops.h"
38 #include "thread.h"
39 #include "libavutil/imgutils.h"
40 
41 enum ExrCompr {
42  EXR_RAW = 0,
43  EXR_RLE = 1,
44  EXR_ZIP1 = 2,
45  EXR_ZIP16 = 3,
46  EXR_PIZ = 4,
47  EXR_B44 = 6,
48  EXR_B44A = 7,
49 };
50 
51 typedef struct EXRContext {
53  int compr;
55  int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
56 
59 
61  int tmp_size;
62 } EXRContext;
63 
64 /**
65  * Converts from 32-bit float as uint32_t to uint16_t
66  *
67  * @param v 32-bit float
68  * @return normalized 16-bit unsigned int
69  */
70 static inline uint16_t exr_flt2uint(uint32_t v)
71 {
72  unsigned int exp = v >> 23;
73  // "HACK": negative values result in exp< 0, so clipping them to 0
74  // is also handled by this condition, avoids explicit check for sign bit.
75  if (exp<= 127 + 7 - 24) // we would shift out all bits anyway
76  return 0;
77  if (exp >= 127)
78  return 0xffff;
79  v &= 0x007fffff;
80  return (v + (1 << 23)) >> (127 + 7 - exp);
81 }
82 
83 /**
84  * Converts from 16-bit float as uint16_t to uint16_t
85  *
86  * @param v 16-bit float
87  * @return normalized 16-bit unsigned int
88  */
89 static inline uint16_t exr_halflt2uint(uint16_t v)
90 {
91  unsigned exp = 14 - (v >> 10);
92  if (exp >= 14) {
93  if (exp == 14) return (v >> 9) & 1;
94  else return (v & 0x8000) ? 0 : 0xffff;
95  }
96  v <<= 6;
97  return (v + (1 << 16)) >> (exp + 1);
98 }
99 
100 /**
101  * Gets the size of the header variable
102  *
103  * @param **buf the current pointer location in the header where
104  * the variable data starts
105  * @param *buf_end pointer location of the end of the buffer
106  * @return size of variable data
107  */
108 static unsigned int get_header_variable_length(const uint8_t **buf,
109  const uint8_t *buf_end)
110 {
111  unsigned int variable_buffer_data_size = bytestream_get_le32(buf);
112  if (variable_buffer_data_size >= buf_end - *buf)
113  return 0;
114  return variable_buffer_data_size;
115 }
116 
117 /**
118  * Checks if the variable name corresponds with it's data type
119  *
120  * @param *avctx the AVCodecContext
121  * @param **buf the current pointer location in the header where
122  * the variable name starts
123  * @param *buf_end pointer location of the end of the buffer
124  * @param *value_name name of the varible to check
125  * @param *value_type type of the varible to check
126  * @param minimum_length minimum length of the variable data
127  * @param variable_buffer_data_size variable length read from the header
128  * after it's checked
129  * @return negative if variable is invalid
130  */
132  const uint8_t **buf,
133  const uint8_t *buf_end,
134  const char *value_name,
135  const char *value_type,
136  unsigned int minimum_length,
137  unsigned int *variable_buffer_data_size)
138 {
139  if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) {
140  *buf += strlen(value_name)+1;
141  if (!strcmp(*buf, value_type)) {
142  *buf += strlen(value_type)+1;
143  *variable_buffer_data_size = get_header_variable_length(buf, buf_end);
144  if (!*variable_buffer_data_size)
145  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
146  if (*variable_buffer_data_size > buf_end - *buf)
147  return -1;
148  return 1;
149  }
150  *buf -= strlen(value_name)+1;
151  av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name);
152  }
153  return -1;
154 }
155 
156 static void predictor(uint8_t *src, int size)
157 {
158  uint8_t *t = src + 1;
159  uint8_t *stop = src + size;
160 
161  while (t < stop) {
162  int d = (int)t[-1] + (int)t[0] - 128;
163  t[0] = d;
164  ++t;
165  }
166 }
167 
168 static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
169 {
170  const int8_t *t1 = src;
171  const int8_t *t2 = src + (size + 1) / 2;
172  int8_t *s = dst;
173  int8_t *stop = s + size;
174 
175  while (1) {
176  if (s < stop)
177  *(s++) = *(t1++);
178  else
179  break;
180 
181  if (s < stop)
182  *(s++) = *(t2++);
183  else
184  break;
185  }
186 }
187 
188 static int rle_uncompress(const uint8_t *src, int ssize, uint8_t *dst, int dsize)
189 {
190  int8_t *d = (int8_t *)dst;
191  int8_t *s = (int8_t *)src;
192  int8_t *dend = d + dsize;
193  int count;
194 
195  while (ssize > 0) {
196  count = *s++;
197 
198  if (count < 0) {
199  count = -count;
200 
201  if ((dsize -= count ) < 0 ||
202  (ssize -= count + 1) < 0)
203  return -1;
204 
205  while (count--)
206  *d++ = *s++;
207  } else {
208  count++;
209 
210  if ((dsize -= count) < 0 ||
211  (ssize -= 2 ) < 0)
212  return -1;
213 
214  while (count--)
215  *d++ = *s;
216 
217  s++;
218  }
219  }
220 
221  return dend != d;
222 }
223 
224 static int decode_frame(AVCodecContext *avctx,
225  void *data,
226  int *got_frame,
227  AVPacket *avpkt)
228 {
229  const uint8_t *buf = avpkt->data;
230  unsigned int buf_size = avpkt->size;
231  const uint8_t *buf_end = buf + buf_size;
232 
233  const AVPixFmtDescriptor *desc;
234  EXRContext *const s = avctx->priv_data;
235  AVFrame *picture = data;
236  AVFrame *const p = &s->picture;
237  uint8_t *ptr;
238 
239  int i, x, y, stride, magic_number, version_flag, ret;
240  int w = 0;
241  int h = 0;
242  unsigned int xmin = ~0;
243  unsigned int xmax = ~0;
244  unsigned int ymin = ~0;
245  unsigned int ymax = ~0;
246  unsigned int xdelta = ~0;
247 
248  int out_line_size;
249  int bxmin, axmax;
250  int scan_lines_per_block;
251  unsigned long scan_line_size;
252  unsigned long uncompressed_size;
253 
254  unsigned int current_channel_offset = 0;
255 
256  s->channel_offsets[0] = -1;
257  s->channel_offsets[1] = -1;
258  s->channel_offsets[2] = -1;
259  s->channel_offsets[3] = -1;
260  s->bits_per_color_id = -1;
261 
262  if (buf_size < 10) {
263  av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
264  return AVERROR_INVALIDDATA;
265  }
266 
267  magic_number = bytestream_get_le32(&buf);
268  if (magic_number != 20000630) { // As per documentation of OpenEXR it's supposed to be int 20000630 little-endian
269  av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number);
270  return AVERROR_INVALIDDATA;
271  }
272 
273  version_flag = bytestream_get_le32(&buf);
274  if ((version_flag & 0x200) == 0x200) {
275  av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
276  return AVERROR_PATCHWELCOME;
277  }
278 
279  // Parse the header
280  while (buf < buf_end && buf[0]) {
281  unsigned int variable_buffer_data_size;
282  // Process the channel list
283  if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) {
284  const uint8_t *channel_list_end;
285  if (!variable_buffer_data_size)
286  return AVERROR_INVALIDDATA;
287 
288  channel_list_end = buf + variable_buffer_data_size;
289  while (channel_list_end - buf >= 19) {
290  int current_bits_per_color_id = -1;
291  int channel_index = -1;
292 
293  if (!strcmp(buf, "R"))
294  channel_index = 0;
295  else if (!strcmp(buf, "G"))
296  channel_index = 1;
297  else if (!strcmp(buf, "B"))
298  channel_index = 2;
299  else if (!strcmp(buf, "A"))
300  channel_index = 3;
301  else
302  av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
303 
304  while (bytestream_get_byte(&buf) && buf < channel_list_end)
305  continue; /* skip */
306 
307  if (channel_list_end - * &buf < 4) {
308  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
309  return AVERROR_INVALIDDATA;
310  }
311 
312  current_bits_per_color_id = bytestream_get_le32(&buf);
313  if (current_bits_per_color_id > 2) {
314  av_log(avctx, AV_LOG_ERROR, "Unknown color format\n");
315  return AVERROR_INVALIDDATA;
316  }
317 
318  if (channel_index >= 0) {
319  if (s->bits_per_color_id != -1 && s->bits_per_color_id != current_bits_per_color_id) {
320  av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n");
321  return AVERROR_INVALIDDATA;
322  }
323  s->bits_per_color_id = current_bits_per_color_id;
324  s->channel_offsets[channel_index] = current_channel_offset;
325  }
326 
327  current_channel_offset += 1 << current_bits_per_color_id;
328  buf += 12;
329  }
330 
331  /* Check if all channels are set with an offset or if the channels
332  * are causing an overflow */
333 
334  if (FFMIN3(s->channel_offsets[0],
335  s->channel_offsets[1],
336  s->channel_offsets[2]) < 0) {
337  if (s->channel_offsets[0] < 0)
338  av_log(avctx, AV_LOG_ERROR, "Missing red channel\n");
339  if (s->channel_offsets[1] < 0)
340  av_log(avctx, AV_LOG_ERROR, "Missing green channel\n");
341  if (s->channel_offsets[2] < 0)
342  av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n");
343  return AVERROR_INVALIDDATA;
344  }
345 
346  buf = channel_list_end;
347  continue;
348  }
349 
350  // Process the dataWindow variable
351  if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
352  if (!variable_buffer_data_size)
353  return AVERROR_INVALIDDATA;
354 
355  xmin = AV_RL32(buf);
356  ymin = AV_RL32(buf + 4);
357  xmax = AV_RL32(buf + 8);
358  ymax = AV_RL32(buf + 12);
359  xdelta = (xmax-xmin) + 1;
360 
361  buf += variable_buffer_data_size;
362  continue;
363  }
364 
365  // Process the displayWindow variable
366  if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
367  if (!variable_buffer_data_size)
368  return AVERROR_INVALIDDATA;
369 
370  w = AV_RL32(buf + 8) + 1;
371  h = AV_RL32(buf + 12) + 1;
372 
373  buf += variable_buffer_data_size;
374  continue;
375  }
376 
377  // Process the lineOrder variable
378  if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
379  if (!variable_buffer_data_size)
380  return AVERROR_INVALIDDATA;
381 
382  if (*buf) {
383  av_log(avctx, AV_LOG_ERROR, "Doesn't support this line order : %d\n", *buf);
384  return AVERROR_PATCHWELCOME;
385  }
386 
387  buf += variable_buffer_data_size;
388  continue;
389  }
390 
391  // Process the pixelAspectRatio variable
392  if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) {
393  if (!variable_buffer_data_size)
394  return AVERROR_INVALIDDATA;
395 
396  avctx->sample_aspect_ratio = av_d2q(av_int2float(AV_RL32(buf)), 255);
397 
398  buf += variable_buffer_data_size;
399  continue;
400  }
401 
402  // Process the compression variable
403  if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
404  if (!variable_buffer_data_size)
405  return AVERROR_INVALIDDATA;
406 
407  if (s->compr == -1)
408  s->compr = *buf;
409  else
410  av_log(avctx, AV_LOG_WARNING, "Found more than one compression attribute\n");
411 
412  buf += variable_buffer_data_size;
413  continue;
414  }
415 
416  // Check if there is enough bytes for a header
417  if (buf_end - buf <= 9) {
418  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
419  return AVERROR_INVALIDDATA;
420  }
421 
422  // Process unknown variables
423  for (i = 0; i < 2; i++) {
424  // Skip variable name/type
425  while (++buf < buf_end)
426  if (buf[0] == 0x0)
427  break;
428  }
429  buf++;
430  // Skip variable length
431  if (buf_end - buf >= 5) {
432  variable_buffer_data_size = get_header_variable_length(&buf, buf_end);
433  if (!variable_buffer_data_size) {
434  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
435  return AVERROR_INVALIDDATA;
436  }
437  buf += variable_buffer_data_size;
438  }
439  }
440 
441  if (s->compr == -1) {
442  av_log(avctx, AV_LOG_ERROR, "Missing compression attribute\n");
443  return AVERROR_INVALIDDATA;
444  }
445 
446  if (buf >= buf_end) {
447  av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n");
448  return AVERROR_INVALIDDATA;
449  }
450  buf++;
451 
452  switch (s->bits_per_color_id) {
453  case 2: // 32-bit
454  case 1: // 16-bit
455  if (s->channel_offsets[3] >= 0)
456  avctx->pix_fmt = AV_PIX_FMT_RGBA64;
457  else
458  avctx->pix_fmt = AV_PIX_FMT_RGB48;
459  break;
460  // 8-bit
461  case 0:
462  av_log_missing_feature(avctx, "8-bit OpenEXR", 1);
463  return AVERROR_PATCHWELCOME;
464  default:
465  av_log(avctx, AV_LOG_ERROR, "Unknown color format : %d\n", s->bits_per_color_id);
466  return AVERROR_INVALIDDATA;
467  }
468 
469  switch (s->compr) {
470  case EXR_RAW:
471  case EXR_RLE:
472  case EXR_ZIP1:
473  scan_lines_per_block = 1;
474  break;
475  case EXR_ZIP16:
476  scan_lines_per_block = 16;
477  break;
478  default:
479  av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
480  return AVERROR_PATCHWELCOME;
481  }
482 
483  if (s->picture.data[0])
484  ff_thread_release_buffer(avctx, &s->picture);
485  if (av_image_check_size(w, h, 0, avctx))
486  return AVERROR_INVALIDDATA;
487 
488  // Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size
489  if (xmin > xmax || ymin > ymax || xdelta != xmax - xmin + 1 || xmax >= w || ymax >= h) {
490  av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
491  return AVERROR_INVALIDDATA;
492  }
493 
494  if (w != avctx->width || h != avctx->height) {
495  avcodec_set_dimensions(avctx, w, h);
496  }
497 
498  desc = av_pix_fmt_desc_get(avctx->pix_fmt);
499  bxmin = xmin * 2 * desc->nb_components;
500  axmax = (avctx->width - (xmax + 1)) * 2 * desc->nb_components;
501  out_line_size = avctx->width * 2 * desc->nb_components;
502  scan_line_size = xdelta * current_channel_offset;
503  uncompressed_size = scan_line_size * scan_lines_per_block;
504 
505  if (s->compr != EXR_RAW) {
506  av_fast_padded_malloc(&s->uncompressed_data, &s->uncompressed_size, uncompressed_size);
507  av_fast_padded_malloc(&s->tmp, &s->tmp_size, uncompressed_size);
508  if (!s->uncompressed_data || !s->tmp)
509  return AVERROR(ENOMEM);
510  }
511 
512  if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
513  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
514  return ret;
515  }
516 
517  ptr = p->data[0];
518  stride = p->linesize[0];
519 
520  // Zero out the start if ymin is not 0
521  for (y = 0; y < ymin; y++) {
522  memset(ptr, 0, out_line_size);
523  ptr += stride;
524  }
525 
526  // Process the actual scan line blocks
527  for (y = ymin; y <= ymax; y += scan_lines_per_block) {
528  uint16_t *ptr_x = (uint16_t *)ptr;
529  if (buf_end - buf > 8) {
530  /* Read the lineoffset from the line offset table and add 8 bytes
531  to skip the coordinates and data size fields */
532  const uint64_t line_offset = bytestream_get_le64(&buf) + 8;
533  int32_t data_size;
534 
535  // Check if the buffer has the required bytes needed from the offset
536  if ((line_offset > buf_size) ||
537  (s->compr == EXR_RAW && line_offset > avpkt->size - xdelta * current_channel_offset) ||
538  (s->compr != EXR_RAW && line_offset > buf_size - (data_size = AV_RL32(avpkt->data + line_offset - 4)))) {
539  // Line offset is probably wrong and not inside the buffer
540  av_log(avctx, AV_LOG_WARNING, "Line offset for line %d is out of reach setting it to black\n", y);
541  for (i = 0; i < scan_lines_per_block && y + i <= ymax; i++, ptr += stride) {
542  ptr_x = (uint16_t *)ptr;
543  memset(ptr_x, 0, out_line_size);
544  }
545  } else {
546  const uint8_t *red_channel_buffer, *green_channel_buffer, *blue_channel_buffer, *alpha_channel_buffer = 0;
547 
548  if (scan_lines_per_block > 1)
549  uncompressed_size = scan_line_size * FFMIN(scan_lines_per_block, ymax - y + 1);
550  if ((s->compr == EXR_ZIP1 || s->compr == EXR_ZIP16) && data_size < uncompressed_size) {
551  unsigned long dest_len = uncompressed_size;
552 
553  if (uncompress(s->tmp, &dest_len, avpkt->data + line_offset, data_size) != Z_OK ||
554  dest_len != uncompressed_size) {
555  av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
556  return AVERROR(EINVAL);
557  }
558  } else if (s->compr == EXR_RLE && data_size < uncompressed_size) {
559  if (rle_uncompress(avpkt->data + line_offset, data_size, s->tmp, uncompressed_size)) {
560  av_log(avctx, AV_LOG_ERROR, "error during rle decompression\n");
561  return AVERROR(EINVAL);
562  }
563  }
564 
565  if (s->compr != EXR_RAW && data_size < uncompressed_size) {
566  predictor(s->tmp, uncompressed_size);
567  reorder_pixels(s->tmp, s->uncompressed_data, uncompressed_size);
568 
569  red_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[0];
570  green_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[1];
571  blue_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[2];
572  if (s->channel_offsets[3] >= 0)
573  alpha_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[3];
574  } else {
575  red_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[0];
576  green_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[1];
577  blue_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[2];
578  if (s->channel_offsets[3] >= 0)
579  alpha_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[3];
580  }
581 
582  for (i = 0; i < scan_lines_per_block && y + i <= ymax; i++, ptr += stride) {
583  const uint8_t *r, *g, *b, *a;
584 
585  r = red_channel_buffer;
586  g = green_channel_buffer;
587  b = blue_channel_buffer;
588  if (alpha_channel_buffer)
589  a = alpha_channel_buffer;
590 
591  ptr_x = (uint16_t *)ptr;
592 
593  // Zero out the start if xmin is not 0
594  memset(ptr_x, 0, bxmin);
595  ptr_x += xmin * desc->nb_components;
596  if (s->bits_per_color_id == 2) {
597  // 32-bit
598  for (x = 0; x < xdelta; x++) {
599  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r));
600  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g));
601  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b));
602  if (alpha_channel_buffer)
603  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
604  }
605  } else {
606  // 16-bit
607  for (x = 0; x < xdelta; x++) {
608  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r));
609  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g));
610  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b));
611  if (alpha_channel_buffer)
612  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
613  }
614  }
615 
616  // Zero out the end if xmax+1 is not w
617  memset(ptr_x, 0, axmax);
618 
619  red_channel_buffer += scan_line_size;
620  green_channel_buffer += scan_line_size;
621  blue_channel_buffer += scan_line_size;
622  if (alpha_channel_buffer)
623  alpha_channel_buffer += scan_line_size;
624  }
625  }
626  }
627  }
628 
629  // Zero out the end if ymax+1 is not h
630  for (y = ymax + 1; y < avctx->height; y++) {
631  memset(ptr, 0, out_line_size);
632  ptr += stride;
633  }
634 
635  *picture = s->picture;
636  *got_frame = 1;
637 
638  return buf_size;
639 }
640 
642 {
643  EXRContext *s = avctx->priv_data;
644 
646  avctx->coded_frame = &s->picture;
647 
648  s->compr = -1;
649 
650  return 0;
651 }
652 
654 {
655  EXRContext *s = avctx->priv_data;
656 
657  if (s->picture.data[0])
658  avctx->release_buffer(avctx, &s->picture);
659 
661  av_freep(&s->tmp);
662 
663  return 0;
664 }
665 
667  .name = "exr",
668  .type = AVMEDIA_TYPE_VIDEO,
669  .id = AV_CODEC_ID_EXR,
670  .priv_data_size = sizeof(EXRContext),
671  .init = decode_init,
672  .close = decode_end,
673  .decode = decode_frame,
674  .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
675  .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
676 };