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 #include "libavutil/avassert.h"
41 
42 enum ExrCompr {
43  EXR_RAW = 0,
44  EXR_RLE = 1,
45  EXR_ZIP1 = 2,
46  EXR_ZIP16 = 3,
47  EXR_PIZ = 4,
48  EXR_PXR24 = 5,
49  EXR_B44 = 6,
50  EXR_B44A = 7,
51 };
52 
57 };
58 
59 typedef struct EXRChannel {
60  int xsub, ysub;
62 } EXRChannel;
63 
64 typedef struct EXRThreadData {
67 
69  int tmp_size;
71 
72 typedef struct EXRContext {
74  int compr;
76  int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
78 
79  uint32_t xmax, xmin;
80  uint32_t ymax, ymin;
81  uint32_t xdelta, ydelta;
82 
83  int ysize;
84 
85  uint64_t scan_line_size;
87 
88  const uint8_t *buf, *table;
89  int buf_size;
90 
93 
96 } EXRContext;
97 
98 /**
99  * Converts from 32-bit float as uint32_t to uint16_t
100  *
101  * @param v 32-bit float
102  * @return normalized 16-bit unsigned int
103  */
104 static inline uint16_t exr_flt2uint(uint32_t v)
105 {
106  unsigned int exp = v >> 23;
107  // "HACK": negative values result in exp< 0, so clipping them to 0
108  // is also handled by this condition, avoids explicit check for sign bit.
109  if (exp<= 127 + 7 - 24) // we would shift out all bits anyway
110  return 0;
111  if (exp >= 127)
112  return 0xffff;
113  v &= 0x007fffff;
114  return (v + (1 << 23)) >> (127 + 7 - exp);
115 }
116 
117 /**
118  * Converts from 16-bit float as uint16_t to uint16_t
119  *
120  * @param v 16-bit float
121  * @return normalized 16-bit unsigned int
122  */
123 static inline uint16_t exr_halflt2uint(uint16_t v)
124 {
125  unsigned exp = 14 - (v >> 10);
126  if (exp >= 14) {
127  if (exp == 14) return (v >> 9) & 1;
128  else return (v & 0x8000) ? 0 : 0xffff;
129  }
130  v <<= 6;
131  return (v + (1 << 16)) >> (exp + 1);
132 }
133 
134 /**
135  * Gets the size of the header variable
136  *
137  * @param **buf the current pointer location in the header where
138  * the variable data starts
139  * @param *buf_end pointer location of the end of the buffer
140  * @return size of variable data
141  */
142 static unsigned int get_header_variable_length(const uint8_t **buf,
143  const uint8_t *buf_end)
144 {
145  unsigned int variable_buffer_data_size = bytestream_get_le32(buf);
146  if (variable_buffer_data_size >= buf_end - *buf)
147  return 0;
148  return variable_buffer_data_size;
149 }
150 
151 /**
152  * Checks if the variable name corresponds with it's data type
153  *
154  * @param *avctx the AVCodecContext
155  * @param **buf the current pointer location in the header where
156  * the variable name starts
157  * @param *buf_end pointer location of the end of the buffer
158  * @param *value_name name of the varible to check
159  * @param *value_type type of the varible to check
160  * @param minimum_length minimum length of the variable data
161  * @param variable_buffer_data_size variable length read from the header
162  * after it's checked
163  * @return negative if variable is invalid
164  */
166  const uint8_t **buf,
167  const uint8_t *buf_end,
168  const char *value_name,
169  const char *value_type,
170  unsigned int minimum_length,
171  unsigned int *variable_buffer_data_size)
172 {
173  if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) {
174  *buf += strlen(value_name)+1;
175  if (!strcmp(*buf, value_type)) {
176  *buf += strlen(value_type)+1;
177  *variable_buffer_data_size = get_header_variable_length(buf, buf_end);
178  if (!*variable_buffer_data_size)
179  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
180  return 1;
181  }
182  *buf -= strlen(value_name)+1;
183  av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name);
184  }
185  return -1;
186 }
187 
188 static void predictor(uint8_t *src, int size)
189 {
190  uint8_t *t = src + 1;
191  uint8_t *stop = src + size;
192 
193  while (t < stop) {
194  int d = (int)t[-1] + (int)t[0] - 128;
195  t[0] = d;
196  ++t;
197  }
198 }
199 
200 static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
201 {
202  const int8_t *t1 = src;
203  const int8_t *t2 = src + (size + 1) / 2;
204  int8_t *s = dst;
205  int8_t *stop = s + size;
206 
207  while (1) {
208  if (s < stop)
209  *(s++) = *(t1++);
210  else
211  break;
212 
213  if (s < stop)
214  *(s++) = *(t2++);
215  else
216  break;
217  }
218 }
219 
220 static int zip_uncompress(const uint8_t *src, int compressed_size,
221  int uncompressed_size, EXRThreadData *td)
222 {
223  unsigned long dest_len = uncompressed_size;
224 
225  if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
226  dest_len != uncompressed_size)
227  return AVERROR(EINVAL);
228 
229  predictor(td->tmp, uncompressed_size);
230  reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
231 
232  return 0;
233 }
234 
235 static int rle_uncompress(const uint8_t *src, int compressed_size,
236  int uncompressed_size, EXRThreadData *td)
237 {
238  int8_t *d = (int8_t *)td->tmp;
239  const int8_t *s = (const int8_t *)src;
240  int ssize = compressed_size;
241  int dsize = uncompressed_size;
242  int8_t *dend = d + dsize;
243  int count;
244 
245  while (ssize > 0) {
246  count = *s++;
247 
248  if (count < 0) {
249  count = -count;
250 
251  if ((dsize -= count ) < 0 ||
252  (ssize -= count + 1) < 0)
253  return -1;
254 
255  while (count--)
256  *d++ = *s++;
257  } else {
258  count++;
259 
260  if ((dsize -= count) < 0 ||
261  (ssize -= 2 ) < 0)
262  return -1;
263 
264  while (count--)
265  *d++ = *s;
266 
267  s++;
268  }
269  }
270 
271  if (dend != d)
272  return AVERROR_INVALIDDATA;
273 
274  predictor(td->tmp, uncompressed_size);
275  reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
276 
277  return 0;
278 }
279 
281  int compressed_size, int uncompressed_size,
282  EXRThreadData *td)
283 {
284  unsigned long dest_len = uncompressed_size;
285  const uint8_t *in = td->tmp;
286  uint8_t *out;
287  int c, i, j;
288 
289  if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
290  dest_len != uncompressed_size)
291  return AVERROR(EINVAL);
292 
293  out = td->uncompressed_data;
294  for (i = 0; i < s->ysize; i++) {
295  for (c = 0; c < s->nb_channels; c++) {
296  EXRChannel *channel = &s->channels[c];
297  const uint8_t *ptr[4];
298  uint32_t pixel = 0;
299 
300  switch (channel->pixel_type) {
301  case EXR_FLOAT:
302  ptr[0] = in;
303  ptr[1] = ptr[0] + s->xdelta;
304  ptr[2] = ptr[1] + s->xdelta;
305  in = ptr[2] + s->xdelta;
306 
307  for (j = 0; j < s->xdelta; ++j) {
308  uint32_t diff = (*(ptr[0]++) << 24) |
309  (*(ptr[1]++) << 16) |
310  (*(ptr[2]++) << 8);
311  pixel += diff;
312  bytestream_put_le32(&out, pixel);
313  }
314  break;
315  case EXR_HALF:
316  ptr[0] = in;
317  ptr[1] = ptr[0] + s->xdelta;
318  in = ptr[1] + s->xdelta;
319  for (j = 0; j < s->xdelta; j++) {
320  uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++);
321 
322  pixel += diff;
323  bytestream_put_le16(&out, pixel);
324  }
325  break;
326  default:
327  av_assert1(0);
328  }
329  }
330  }
331 
332  return 0;
333 }
334 
335 static int decode_block(AVCodecContext *avctx, void *tdata,
336  int jobnr, int threadnr)
337 {
338  EXRContext *s = avctx->priv_data;
339  AVFrame *const p = s->picture;
340  EXRThreadData *td = &s->thread_data[threadnr];
341  const uint8_t *channel_buffer[4] = { 0 };
342  const uint8_t *buf = s->buf;
343  uint64_t line_offset, uncompressed_size;
344  uint32_t xdelta = s->xdelta;
345  uint16_t *ptr_x;
346  uint8_t *ptr;
347  int32_t data_size, line;
348  const uint8_t *src;
349  int axmax = (avctx->width - (s->xmax + 1)) * 2 * s->desc->nb_components;
350  int bxmin = s->xmin * 2 * s->desc->nb_components;
351  int i, x, buf_size = s->buf_size;
352  int av_unused ret;
353 
354  line_offset = AV_RL64(s->table + jobnr * 8);
355  // Check if the buffer has the required bytes needed from the offset
356  if (line_offset > buf_size - 8)
357  return AVERROR_INVALIDDATA;
358 
359  src = buf + line_offset + 8;
360  line = AV_RL32(src - 8);
361  if (line < s->ymin || line > s->ymax)
362  return AVERROR_INVALIDDATA;
363 
364  data_size = AV_RL32(src - 4);
365  if (data_size <= 0 || data_size > buf_size)
366  return AVERROR_INVALIDDATA;
367 
368  s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1);
369  uncompressed_size = s->scan_line_size * s->ysize;
370  if ((s->compr == EXR_RAW && (data_size != uncompressed_size ||
371  line_offset > buf_size - uncompressed_size)) ||
372  (s->compr != EXR_RAW && (data_size > uncompressed_size ||
373  line_offset > buf_size - data_size))) {
374  return AVERROR_INVALIDDATA;
375  }
376 
377  if (data_size < uncompressed_size) {
378  av_fast_padded_malloc(&td->uncompressed_data, &td->uncompressed_size, uncompressed_size);
379  av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size);
380  if (!td->uncompressed_data || !td->tmp)
381  return AVERROR(ENOMEM);
382 
383  switch (s->compr) {
384  case EXR_ZIP1:
385  case EXR_ZIP16:
386  ret = zip_uncompress(src, data_size, uncompressed_size, td);
387  break;
388  case EXR_PXR24:
389  ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td);
390  break;
391  case EXR_RLE:
392  ret = rle_uncompress(src, data_size, uncompressed_size, td);
393  }
394 
395  src = td->uncompressed_data;
396  }
397 
398  channel_buffer[0] = src + xdelta * s->channel_offsets[0];
399  channel_buffer[1] = src + xdelta * s->channel_offsets[1];
400  channel_buffer[2] = src + xdelta * s->channel_offsets[2];
401  if (s->channel_offsets[3] >= 0)
402  channel_buffer[3] = src + xdelta * s->channel_offsets[3];
403 
404  ptr = p->data[0] + line * p->linesize[0];
405  for (i = 0; i < s->scan_lines_per_block && line + i <= s->ymax; i++, ptr += p->linesize[0]) {
406  const uint8_t *r, *g, *b, *a;
407 
408  r = channel_buffer[0];
409  g = channel_buffer[1];
410  b = channel_buffer[2];
411  if (channel_buffer[3])
412  a = channel_buffer[3];
413 
414  ptr_x = (uint16_t *)ptr;
415 
416  // Zero out the start if xmin is not 0
417  memset(ptr_x, 0, bxmin);
418  ptr_x += s->xmin * s->desc->nb_components;
419  if (s->pixel_type == EXR_FLOAT) {
420  // 32-bit
421  for (x = 0; x < xdelta; x++) {
422  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r));
423  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g));
424  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b));
425  if (channel_buffer[3])
426  *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
427  }
428  } else {
429  // 16-bit
430  for (x = 0; x < xdelta; x++) {
431  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r));
432  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g));
433  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b));
434  if (channel_buffer[3])
435  *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
436  }
437  }
438 
439  // Zero out the end if xmax+1 is not w
440  memset(ptr_x, 0, axmax);
441 
442  channel_buffer[0] += s->scan_line_size;
443  channel_buffer[1] += s->scan_line_size;
444  channel_buffer[2] += s->scan_line_size;
445  if (channel_buffer[3])
446  channel_buffer[3] += s->scan_line_size;
447  }
448 
449  return 0;
450 }
451 
452 static int decode_frame(AVCodecContext *avctx,
453  void *data,
454  int *got_frame,
455  AVPacket *avpkt)
456 {
457  const uint8_t *buf = avpkt->data;
458  unsigned int buf_size = avpkt->size;
459  const uint8_t *buf_end = buf + buf_size;
460 
461  EXRContext *const s = avctx->priv_data;
462  ThreadFrame frame = { .f = data };
463  AVFrame *picture = data;
464  uint8_t *ptr;
465 
466  int i, y, magic_number, version, flags, ret;
467  int w = 0;
468  int h = 0;
469 
470  int out_line_size;
471  int scan_line_blocks;
472 
473  unsigned int current_channel_offset = 0;
474 
475  s->xmin = ~0;
476  s->xmax = ~0;
477  s->ymin = ~0;
478  s->ymax = ~0;
479  s->xdelta = ~0;
480  s->ydelta = ~0;
481  s->channel_offsets[0] = -1;
482  s->channel_offsets[1] = -1;
483  s->channel_offsets[2] = -1;
484  s->channel_offsets[3] = -1;
485  s->pixel_type = -1;
486  s->nb_channels = 0;
487  s->compr = -1;
488  s->buf = buf;
489  s->buf_size = buf_size;
490 
491  if (buf_size < 10) {
492  av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
493  return AVERROR_INVALIDDATA;
494  }
495 
496  magic_number = bytestream_get_le32(&buf);
497  if (magic_number != 20000630) { // As per documentation of OpenEXR it's supposed to be int 20000630 little-endian
498  av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number);
499  return AVERROR_INVALIDDATA;
500  }
501 
502  version = bytestream_get_byte(&buf);
503  if (version != 2) {
504  av_log(avctx, AV_LOG_ERROR, "Unsupported version %d\n", version);
505  return AVERROR_PATCHWELCOME;
506  }
507 
508  flags = bytestream_get_le24(&buf);
509  if (flags & 0x2) {
510  av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
511  return AVERROR_PATCHWELCOME;
512  }
513 
514  // Parse the header
515  while (buf < buf_end && buf[0]) {
516  unsigned int variable_buffer_data_size;
517  // Process the channel list
518  if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) {
519  const uint8_t *channel_list_end;
520  if (!variable_buffer_data_size)
521  return AVERROR_INVALIDDATA;
522 
523  channel_list_end = buf + variable_buffer_data_size;
524  while (channel_list_end - buf >= 19) {
525  EXRChannel *channel;
526  int current_pixel_type = -1;
527  int channel_index = -1;
528  int xsub, ysub;
529 
530  if (!strcmp(buf, "R"))
531  channel_index = 0;
532  else if (!strcmp(buf, "G"))
533  channel_index = 1;
534  else if (!strcmp(buf, "B"))
535  channel_index = 2;
536  else if (!strcmp(buf, "A"))
537  channel_index = 3;
538  else
539  av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
540 
541  while (bytestream_get_byte(&buf) && buf < channel_list_end)
542  continue; /* skip */
543 
544  if (channel_list_end - * &buf < 4) {
545  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
546  return AVERROR_INVALIDDATA;
547  }
548 
549  current_pixel_type = bytestream_get_le32(&buf);
550  if (current_pixel_type > 2) {
551  av_log(avctx, AV_LOG_ERROR, "Unknown pixel type\n");
552  return AVERROR_INVALIDDATA;
553  }
554 
555  buf += 4;
556  xsub = bytestream_get_le32(&buf);
557  ysub = bytestream_get_le32(&buf);
558  if (xsub != 1 || ysub != 1) {
559  av_log(avctx, AV_LOG_ERROR, "Unsupported subsampling %dx%d\n", xsub, ysub);
560  return AVERROR_PATCHWELCOME;
561  }
562 
563  if (channel_index >= 0) {
564  if (s->pixel_type != -1 && s->pixel_type != current_pixel_type) {
565  av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n");
566  return AVERROR_INVALIDDATA;
567  }
568  s->pixel_type = current_pixel_type;
569  s->channel_offsets[channel_index] = current_channel_offset;
570  }
571 
572  s->channels = av_realloc_f(s->channels, ++s->nb_channels, sizeof(EXRChannel));
573  if (!s->channels)
574  return AVERROR(ENOMEM);
575  channel = &s->channels[s->nb_channels - 1];
576  channel->pixel_type = current_pixel_type;
577  channel->xsub = xsub;
578  channel->ysub = ysub;
579 
580  current_channel_offset += 1 << current_pixel_type;
581  }
582 
583  /* Check if all channels are set with an offset or if the channels
584  * are causing an overflow */
585 
586  if (FFMIN3(s->channel_offsets[0],
587  s->channel_offsets[1],
588  s->channel_offsets[2]) < 0) {
589  if (s->channel_offsets[0] < 0)
590  av_log(avctx, AV_LOG_ERROR, "Missing red channel\n");
591  if (s->channel_offsets[1] < 0)
592  av_log(avctx, AV_LOG_ERROR, "Missing green channel\n");
593  if (s->channel_offsets[2] < 0)
594  av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n");
595  return AVERROR_INVALIDDATA;
596  }
597 
598  buf = channel_list_end;
599  continue;
600  } else if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
601  if (!variable_buffer_data_size)
602  return AVERROR_INVALIDDATA;
603 
604  s->xmin = AV_RL32(buf);
605  s->ymin = AV_RL32(buf + 4);
606  s->xmax = AV_RL32(buf + 8);
607  s->ymax = AV_RL32(buf + 12);
608  s->xdelta = (s->xmax - s->xmin) + 1;
609  s->ydelta = (s->ymax - s->ymin) + 1;
610 
611  buf += variable_buffer_data_size;
612  continue;
613  } else if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
614  if (!variable_buffer_data_size)
615  return AVERROR_INVALIDDATA;
616 
617  w = AV_RL32(buf + 8) + 1;
618  h = AV_RL32(buf + 12) + 1;
619 
620  buf += variable_buffer_data_size;
621  continue;
622  } else if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
623  if (!variable_buffer_data_size)
624  return AVERROR_INVALIDDATA;
625 
626  av_log(avctx, AV_LOG_DEBUG, "line order : %d\n", *buf);
627  if (*buf > 2) {
628  av_log(avctx, AV_LOG_ERROR, "Unknown line order\n");
629  return AVERROR_INVALIDDATA;
630  }
631 
632  buf += variable_buffer_data_size;
633  continue;
634  } else if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) {
635  if (!variable_buffer_data_size)
636  return AVERROR_INVALIDDATA;
637 
638  avctx->sample_aspect_ratio = av_d2q(av_int2float(AV_RL32(buf)), 255);
639 
640  buf += variable_buffer_data_size;
641  continue;
642  } else if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
643  if (!variable_buffer_data_size)
644  return AVERROR_INVALIDDATA;
645 
646  if (s->compr == -1)
647  s->compr = *buf;
648  else
649  av_log(avctx, AV_LOG_WARNING, "Found more than one compression attribute\n");
650 
651  buf += variable_buffer_data_size;
652  continue;
653  }
654 
655  // Check if there is enough bytes for a header
656  if (buf_end - buf <= 9) {
657  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
658  return AVERROR_INVALIDDATA;
659  }
660 
661  // Process unknown variables
662  for (i = 0; i < 2; i++) {
663  // Skip variable name/type
664  while (++buf < buf_end)
665  if (buf[0] == 0x0)
666  break;
667  }
668  buf++;
669  // Skip variable length
670  if (buf_end - buf >= 5) {
671  variable_buffer_data_size = get_header_variable_length(&buf, buf_end);
672  if (!variable_buffer_data_size) {
673  av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
674  return AVERROR_INVALIDDATA;
675  }
676  buf += variable_buffer_data_size;
677  }
678  }
679 
680  if (s->compr == -1) {
681  av_log(avctx, AV_LOG_ERROR, "Missing compression attribute\n");
682  return AVERROR_INVALIDDATA;
683  }
684 
685  if (buf >= buf_end) {
686  av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n");
687  return AVERROR_INVALIDDATA;
688  }
689  buf++;
690 
691  switch (s->pixel_type) {
692  case EXR_FLOAT:
693  case EXR_HALF:
694  if (s->channel_offsets[3] >= 0)
695  avctx->pix_fmt = AV_PIX_FMT_RGBA64;
696  else
697  avctx->pix_fmt = AV_PIX_FMT_RGB48;
698  break;
699  case EXR_UINT:
700  avpriv_request_sample(avctx, "32-bit unsigned int");
701  return AVERROR_PATCHWELCOME;
702  default:
703  av_log(avctx, AV_LOG_ERROR, "Missing channel list\n");
704  return AVERROR_INVALIDDATA;
705  }
706 
707  switch (s->compr) {
708  case EXR_RAW:
709  case EXR_RLE:
710  case EXR_ZIP1:
711  s->scan_lines_per_block = 1;
712  break;
713  case EXR_PXR24:
714  case EXR_ZIP16:
715  s->scan_lines_per_block = 16;
716  break;
717  default:
718  av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
719  return AVERROR_PATCHWELCOME;
720  }
721 
722  if (av_image_check_size(w, h, 0, avctx))
723  return AVERROR_INVALIDDATA;
724 
725  // Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size
726  if (s->xmin > s->xmax ||
727  s->ymin > s->ymax ||
728  s->xdelta != s->xmax - s->xmin + 1 ||
729  s->xmax >= w || s->ymax >= h) {
730  av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
731  return AVERROR_INVALIDDATA;
732  }
733 
734  if (w != avctx->width || h != avctx->height) {
735  avcodec_set_dimensions(avctx, w, h);
736  }
737 
738  s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
739  out_line_size = avctx->width * 2 * s->desc->nb_components;
740  s->scan_line_size = s->xdelta * current_channel_offset;
741  scan_line_blocks = (s->ydelta + s->scan_lines_per_block - 1) / s->scan_lines_per_block;
742 
743  if (s->compr != EXR_RAW) {
744  size_t thread_data_size, prev_size;
745  EXRThreadData *m;
746 
747  prev_size = s->thread_data_size;
748  if (av_size_mult(avctx->thread_count, sizeof(EXRThreadData), &thread_data_size))
749  return AVERROR(EINVAL);
750 
751  m = av_fast_realloc(s->thread_data, &s->thread_data_size, thread_data_size);
752  if (!m)
753  return AVERROR(ENOMEM);
754  s->thread_data = m;
755  memset(s->thread_data + prev_size, 0, s->thread_data_size - prev_size);
756  }
757 
758  if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
759  return ret;
760 
761  if (buf_end - buf < scan_line_blocks * 8)
762  return AVERROR_INVALIDDATA;
763  s->table = buf;
764  ptr = picture->data[0];
765 
766  // Zero out the start if ymin is not 0
767  for (y = 0; y < s->ymin; y++) {
768  memset(ptr, 0, out_line_size);
769  ptr += picture->linesize[0];
770  }
771 
772  s->picture = picture;
773  avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks);
774 
775  // Zero out the end if ymax+1 is not h
776  for (y = s->ymax + 1; y < avctx->height; y++) {
777  memset(ptr, 0, out_line_size);
778  ptr += picture->linesize[0];
779  }
780 
781  *got_frame = 1;
782 
783  return buf_size;
784 }
785 
787 {
788  EXRContext *s = avctx->priv_data;
789  int i;
790 
791  for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) {
792  EXRThreadData *td = &s->thread_data[i];
794  av_free(td->tmp);
795  }
796 
797  av_freep(&s->thread_data);
798  s->thread_data_size = 0;
799  av_freep(&s->channels);
800 
801  return 0;
802 }
803 
805  .name = "exr",
806  .type = AVMEDIA_TYPE_VIDEO,
807  .id = AV_CODEC_ID_EXR,
808  .priv_data_size = sizeof(EXRContext),
809  .close = decode_end,
810  .decode = decode_frame,
812  .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
813 };
static uint16_t exr_flt2uint(uint32_t v)
Converts from 32-bit float as uint32_t to uint16_t.
Definition: exr.c:104
float v
static unsigned int get_header_variable_length(const uint8_t **buf, const uint8_t *buf_end)
Gets the size of the header variable.
Definition: exr.c:142
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1778
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
Definition: exr.c:48
int thread_data_size
Definition: exr.c:95
misc image utilities
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
Definition: exr.c:43
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
int channel_offsets[4]
Definition: exr.c:76
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:292
int buf_size
Definition: exr.c:89
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
struct EXRThreadData EXRThreadData
uint32_t ymax
Definition: exr.c:80
static int pxr24_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td)
Definition: exr.c:280
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional FF_INPUT_BUFFER_PADDING_SIZE at the end w...
enum ExrPixelType pixel_type
Definition: exr.c:75
int version
Definition: avisynth_c.h:666
static int decode_block(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
Definition: exr.c:335
uint8_t * tmp
Definition: exr.c:68
output residual component w
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
set threshold d
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
#define AV_RL64
const uint8_t * buf
Definition: exr.c:88
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
int compr
Definition: exr.c:74
static int check_header_variable(AVCodecContext *avctx, const uint8_t **buf, const uint8_t *buf_end, const char *value_name, const char *value_type, unsigned int minimum_length, unsigned int *variable_buffer_data_size)
Checks if the variable name corresponds with it&#39;s data type.
Definition: exr.c:165
uint8_t
#define av_cold
Definition: attributes.h:78
struct EXRContext EXRContext
window constants for m
Definition: exr.c:55
#define b
Definition: input.c:42
uint32_t xdelta
Definition: exr.c:81
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: exr.c:59
Definition: exr.c:45
uint8_t * data
#define FFMIN3(a, b, c)
Definition: common.h:59
AVFrame * picture
Definition: exr.c:73
uint32_t ymin
Definition: exr.c:80
uint32_t ydelta
Definition: exr.c:81
uint8_t * uncompressed_data
Definition: exr.c:65
Definition: exr.c:50
frame
Definition: stft.m:14
static void predictor(uint8_t *src, int size)
Definition: exr.c:188
Discrete Time axis x
#define td
Definition: regdef.h:70
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
Multithreading support functions.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
const char * r
Definition: vf_curves.c:94
#define t1
Definition: regdef.h:29
static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
Definition: exr.c:200
Definition: graph2dot.c:48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:267
simple assert() macros that are a bit more flexible than ISO C assert().
enum ExrPixelType pixel_type
Definition: exr.c:61
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int nb_channels
Definition: exr.c:92
const char * name
Name of the codec implementation.
external API header
int size
AVCodec ff_exr_decoder
Definition: exr.c:804
EXRThreadData * thread_data
Definition: exr.c:94
Definition: exr.c:49
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:231
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:57
FFT buffer for g
Definition: stft_peak.m:17
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
Definition: exr.c:47
int xsub
Definition: exr.c:60
#define FFMIN(a, b)
Definition: common.h:58
uint32_t xmin
Definition: exr.c:79
ret
Definition: avfilter.c:821
int width
picture width / height.
const uint8_t * table
Definition: exr.c:88
static int av_size_mult(size_t a, size_t b, size_t *r)
Multiply two size_t values checking for overflow.
Definition: mem.h:204
static uint16_t exr_halflt2uint(uint16_t v)
Converts from 16-bit float as uint16_t to uint16_t.
Definition: exr.c:123
int tmp_size
Definition: exr.c:69
t
Definition: genspecsines3.m:6
int32_t
int ysize
Definition: exr.c:83
#define AV_RL32
Definition: exr.c:56
#define diff(a, as, b, bs)
Definition: vf_phase.c:80
EXRChannel * channels
Definition: exr.c:91
int uncompressed_size
Definition: exr.c:66
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
struct EXRChannel EXRChannel
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
int ysub
Definition: exr.c:60
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
1i.*Xphase exp()
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
ExrCompr
Definition: exr.c:42
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:55
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
static int zip_uncompress(const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td)
Definition: exr.c:220
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
x2
Definition: genspecsines3.m:8
synthesis window for stochastic i
Definition: exr.c:46
ExrPixelType
Definition: exr.c:53
Definition: exr.c:44
uint64_t scan_line_size
Definition: exr.c:85
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread.c:1066
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
static av_cold int decode_end(AVCodecContext *avctx)
Definition: exr.c:786
uint8_t pixel
Definition: tiny_ssim.c:40
static int rle_uncompress(const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td)
Definition: exr.c:235
static int flags
Definition: cpu.c:23
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
int scan_lines_per_block
Definition: exr.c:86
uint32_t xmax
Definition: exr.c:79
#define CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
Definition: exr.c:72
#define CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
static double c[64]
Definition: exr.c:54
function y
Definition: D.m:1
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip please avoid problems through this extra level of scrutiny For cosmetics only commits you should e g by running git config global user name My Name git config global user email my email which is either set in your personal configuration file through git config core editor or set by one of the following environment VISUAL or EDITOR Log messages should be concise but descriptive Explain why you made a what you did will be obvious from the changes themselves most of the time Saying just bug fix or is bad Remember that people of varying skill levels look at and educate themselves while reading through your code Don t include filenames in log Git provides that information Possibly make the commit message have a descriptive first line
Definition: git-howto.txt:153
void INT64 INT64 count
Definition: avisynth_c.h:594
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: exr.c:452
const AVPixFmtDescriptor * desc
Definition: exr.c:77
This structure stores compressed data.
#define t2
Definition: regdef.h:30
#define av_unused
Definition: attributes.h:114