annotate ffmpeg/libavcodec/exr.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * OpenEXR (.exr) image decoder
yading@10 3 * Copyright (c) 2009 Jimmy Christensen
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * OpenEXR decoder
yading@10 25 * @author Jimmy Christensen
yading@10 26 *
yading@10 27 * For more information on the OpenEXR format, visit:
yading@10 28 * http://openexr.com/
yading@10 29 *
yading@10 30 * exr_flt2uint() and exr_halflt2uint() is credited to Reimar Döffinger
yading@10 31 */
yading@10 32
yading@10 33 #include <zlib.h>
yading@10 34
yading@10 35 #include "avcodec.h"
yading@10 36 #include "bytestream.h"
yading@10 37 #include "mathops.h"
yading@10 38 #include "thread.h"
yading@10 39 #include "libavutil/imgutils.h"
yading@10 40 #include "libavutil/avassert.h"
yading@10 41
yading@10 42 enum ExrCompr {
yading@10 43 EXR_RAW = 0,
yading@10 44 EXR_RLE = 1,
yading@10 45 EXR_ZIP1 = 2,
yading@10 46 EXR_ZIP16 = 3,
yading@10 47 EXR_PIZ = 4,
yading@10 48 EXR_PXR24 = 5,
yading@10 49 EXR_B44 = 6,
yading@10 50 EXR_B44A = 7,
yading@10 51 };
yading@10 52
yading@10 53 enum ExrPixelType {
yading@10 54 EXR_UINT,
yading@10 55 EXR_HALF,
yading@10 56 EXR_FLOAT
yading@10 57 };
yading@10 58
yading@10 59 typedef struct EXRChannel {
yading@10 60 int xsub, ysub;
yading@10 61 enum ExrPixelType pixel_type;
yading@10 62 } EXRChannel;
yading@10 63
yading@10 64 typedef struct EXRThreadData {
yading@10 65 uint8_t *uncompressed_data;
yading@10 66 int uncompressed_size;
yading@10 67
yading@10 68 uint8_t *tmp;
yading@10 69 int tmp_size;
yading@10 70 } EXRThreadData;
yading@10 71
yading@10 72 typedef struct EXRContext {
yading@10 73 AVFrame *picture;
yading@10 74 int compr;
yading@10 75 enum ExrPixelType pixel_type;
yading@10 76 int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
yading@10 77 const AVPixFmtDescriptor *desc;
yading@10 78
yading@10 79 uint32_t xmax, xmin;
yading@10 80 uint32_t ymax, ymin;
yading@10 81 uint32_t xdelta, ydelta;
yading@10 82
yading@10 83 int ysize;
yading@10 84
yading@10 85 uint64_t scan_line_size;
yading@10 86 int scan_lines_per_block;
yading@10 87
yading@10 88 const uint8_t *buf, *table;
yading@10 89 int buf_size;
yading@10 90
yading@10 91 EXRChannel *channels;
yading@10 92 int nb_channels;
yading@10 93
yading@10 94 EXRThreadData *thread_data;
yading@10 95 int thread_data_size;
yading@10 96 } EXRContext;
yading@10 97
yading@10 98 /**
yading@10 99 * Converts from 32-bit float as uint32_t to uint16_t
yading@10 100 *
yading@10 101 * @param v 32-bit float
yading@10 102 * @return normalized 16-bit unsigned int
yading@10 103 */
yading@10 104 static inline uint16_t exr_flt2uint(uint32_t v)
yading@10 105 {
yading@10 106 unsigned int exp = v >> 23;
yading@10 107 // "HACK": negative values result in exp< 0, so clipping them to 0
yading@10 108 // is also handled by this condition, avoids explicit check for sign bit.
yading@10 109 if (exp<= 127 + 7 - 24) // we would shift out all bits anyway
yading@10 110 return 0;
yading@10 111 if (exp >= 127)
yading@10 112 return 0xffff;
yading@10 113 v &= 0x007fffff;
yading@10 114 return (v + (1 << 23)) >> (127 + 7 - exp);
yading@10 115 }
yading@10 116
yading@10 117 /**
yading@10 118 * Converts from 16-bit float as uint16_t to uint16_t
yading@10 119 *
yading@10 120 * @param v 16-bit float
yading@10 121 * @return normalized 16-bit unsigned int
yading@10 122 */
yading@10 123 static inline uint16_t exr_halflt2uint(uint16_t v)
yading@10 124 {
yading@10 125 unsigned exp = 14 - (v >> 10);
yading@10 126 if (exp >= 14) {
yading@10 127 if (exp == 14) return (v >> 9) & 1;
yading@10 128 else return (v & 0x8000) ? 0 : 0xffff;
yading@10 129 }
yading@10 130 v <<= 6;
yading@10 131 return (v + (1 << 16)) >> (exp + 1);
yading@10 132 }
yading@10 133
yading@10 134 /**
yading@10 135 * Gets the size of the header variable
yading@10 136 *
yading@10 137 * @param **buf the current pointer location in the header where
yading@10 138 * the variable data starts
yading@10 139 * @param *buf_end pointer location of the end of the buffer
yading@10 140 * @return size of variable data
yading@10 141 */
yading@10 142 static unsigned int get_header_variable_length(const uint8_t **buf,
yading@10 143 const uint8_t *buf_end)
yading@10 144 {
yading@10 145 unsigned int variable_buffer_data_size = bytestream_get_le32(buf);
yading@10 146 if (variable_buffer_data_size >= buf_end - *buf)
yading@10 147 return 0;
yading@10 148 return variable_buffer_data_size;
yading@10 149 }
yading@10 150
yading@10 151 /**
yading@10 152 * Checks if the variable name corresponds with it's data type
yading@10 153 *
yading@10 154 * @param *avctx the AVCodecContext
yading@10 155 * @param **buf the current pointer location in the header where
yading@10 156 * the variable name starts
yading@10 157 * @param *buf_end pointer location of the end of the buffer
yading@10 158 * @param *value_name name of the varible to check
yading@10 159 * @param *value_type type of the varible to check
yading@10 160 * @param minimum_length minimum length of the variable data
yading@10 161 * @param variable_buffer_data_size variable length read from the header
yading@10 162 * after it's checked
yading@10 163 * @return negative if variable is invalid
yading@10 164 */
yading@10 165 static int check_header_variable(AVCodecContext *avctx,
yading@10 166 const uint8_t **buf,
yading@10 167 const uint8_t *buf_end,
yading@10 168 const char *value_name,
yading@10 169 const char *value_type,
yading@10 170 unsigned int minimum_length,
yading@10 171 unsigned int *variable_buffer_data_size)
yading@10 172 {
yading@10 173 if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) {
yading@10 174 *buf += strlen(value_name)+1;
yading@10 175 if (!strcmp(*buf, value_type)) {
yading@10 176 *buf += strlen(value_type)+1;
yading@10 177 *variable_buffer_data_size = get_header_variable_length(buf, buf_end);
yading@10 178 if (!*variable_buffer_data_size)
yading@10 179 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
yading@10 180 return 1;
yading@10 181 }
yading@10 182 *buf -= strlen(value_name)+1;
yading@10 183 av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name);
yading@10 184 }
yading@10 185 return -1;
yading@10 186 }
yading@10 187
yading@10 188 static void predictor(uint8_t *src, int size)
yading@10 189 {
yading@10 190 uint8_t *t = src + 1;
yading@10 191 uint8_t *stop = src + size;
yading@10 192
yading@10 193 while (t < stop) {
yading@10 194 int d = (int)t[-1] + (int)t[0] - 128;
yading@10 195 t[0] = d;
yading@10 196 ++t;
yading@10 197 }
yading@10 198 }
yading@10 199
yading@10 200 static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
yading@10 201 {
yading@10 202 const int8_t *t1 = src;
yading@10 203 const int8_t *t2 = src + (size + 1) / 2;
yading@10 204 int8_t *s = dst;
yading@10 205 int8_t *stop = s + size;
yading@10 206
yading@10 207 while (1) {
yading@10 208 if (s < stop)
yading@10 209 *(s++) = *(t1++);
yading@10 210 else
yading@10 211 break;
yading@10 212
yading@10 213 if (s < stop)
yading@10 214 *(s++) = *(t2++);
yading@10 215 else
yading@10 216 break;
yading@10 217 }
yading@10 218 }
yading@10 219
yading@10 220 static int zip_uncompress(const uint8_t *src, int compressed_size,
yading@10 221 int uncompressed_size, EXRThreadData *td)
yading@10 222 {
yading@10 223 unsigned long dest_len = uncompressed_size;
yading@10 224
yading@10 225 if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
yading@10 226 dest_len != uncompressed_size)
yading@10 227 return AVERROR(EINVAL);
yading@10 228
yading@10 229 predictor(td->tmp, uncompressed_size);
yading@10 230 reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
yading@10 231
yading@10 232 return 0;
yading@10 233 }
yading@10 234
yading@10 235 static int rle_uncompress(const uint8_t *src, int compressed_size,
yading@10 236 int uncompressed_size, EXRThreadData *td)
yading@10 237 {
yading@10 238 int8_t *d = (int8_t *)td->tmp;
yading@10 239 const int8_t *s = (const int8_t *)src;
yading@10 240 int ssize = compressed_size;
yading@10 241 int dsize = uncompressed_size;
yading@10 242 int8_t *dend = d + dsize;
yading@10 243 int count;
yading@10 244
yading@10 245 while (ssize > 0) {
yading@10 246 count = *s++;
yading@10 247
yading@10 248 if (count < 0) {
yading@10 249 count = -count;
yading@10 250
yading@10 251 if ((dsize -= count ) < 0 ||
yading@10 252 (ssize -= count + 1) < 0)
yading@10 253 return -1;
yading@10 254
yading@10 255 while (count--)
yading@10 256 *d++ = *s++;
yading@10 257 } else {
yading@10 258 count++;
yading@10 259
yading@10 260 if ((dsize -= count) < 0 ||
yading@10 261 (ssize -= 2 ) < 0)
yading@10 262 return -1;
yading@10 263
yading@10 264 while (count--)
yading@10 265 *d++ = *s;
yading@10 266
yading@10 267 s++;
yading@10 268 }
yading@10 269 }
yading@10 270
yading@10 271 if (dend != d)
yading@10 272 return AVERROR_INVALIDDATA;
yading@10 273
yading@10 274 predictor(td->tmp, uncompressed_size);
yading@10 275 reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
yading@10 276
yading@10 277 return 0;
yading@10 278 }
yading@10 279
yading@10 280 static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
yading@10 281 int compressed_size, int uncompressed_size,
yading@10 282 EXRThreadData *td)
yading@10 283 {
yading@10 284 unsigned long dest_len = uncompressed_size;
yading@10 285 const uint8_t *in = td->tmp;
yading@10 286 uint8_t *out;
yading@10 287 int c, i, j;
yading@10 288
yading@10 289 if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
yading@10 290 dest_len != uncompressed_size)
yading@10 291 return AVERROR(EINVAL);
yading@10 292
yading@10 293 out = td->uncompressed_data;
yading@10 294 for (i = 0; i < s->ysize; i++) {
yading@10 295 for (c = 0; c < s->nb_channels; c++) {
yading@10 296 EXRChannel *channel = &s->channels[c];
yading@10 297 const uint8_t *ptr[4];
yading@10 298 uint32_t pixel = 0;
yading@10 299
yading@10 300 switch (channel->pixel_type) {
yading@10 301 case EXR_FLOAT:
yading@10 302 ptr[0] = in;
yading@10 303 ptr[1] = ptr[0] + s->xdelta;
yading@10 304 ptr[2] = ptr[1] + s->xdelta;
yading@10 305 in = ptr[2] + s->xdelta;
yading@10 306
yading@10 307 for (j = 0; j < s->xdelta; ++j) {
yading@10 308 uint32_t diff = (*(ptr[0]++) << 24) |
yading@10 309 (*(ptr[1]++) << 16) |
yading@10 310 (*(ptr[2]++) << 8);
yading@10 311 pixel += diff;
yading@10 312 bytestream_put_le32(&out, pixel);
yading@10 313 }
yading@10 314 break;
yading@10 315 case EXR_HALF:
yading@10 316 ptr[0] = in;
yading@10 317 ptr[1] = ptr[0] + s->xdelta;
yading@10 318 in = ptr[1] + s->xdelta;
yading@10 319 for (j = 0; j < s->xdelta; j++) {
yading@10 320 uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++);
yading@10 321
yading@10 322 pixel += diff;
yading@10 323 bytestream_put_le16(&out, pixel);
yading@10 324 }
yading@10 325 break;
yading@10 326 default:
yading@10 327 av_assert1(0);
yading@10 328 }
yading@10 329 }
yading@10 330 }
yading@10 331
yading@10 332 return 0;
yading@10 333 }
yading@10 334
yading@10 335 static int decode_block(AVCodecContext *avctx, void *tdata,
yading@10 336 int jobnr, int threadnr)
yading@10 337 {
yading@10 338 EXRContext *s = avctx->priv_data;
yading@10 339 AVFrame *const p = s->picture;
yading@10 340 EXRThreadData *td = &s->thread_data[threadnr];
yading@10 341 const uint8_t *channel_buffer[4] = { 0 };
yading@10 342 const uint8_t *buf = s->buf;
yading@10 343 uint64_t line_offset, uncompressed_size;
yading@10 344 uint32_t xdelta = s->xdelta;
yading@10 345 uint16_t *ptr_x;
yading@10 346 uint8_t *ptr;
yading@10 347 int32_t data_size, line;
yading@10 348 const uint8_t *src;
yading@10 349 int axmax = (avctx->width - (s->xmax + 1)) * 2 * s->desc->nb_components;
yading@10 350 int bxmin = s->xmin * 2 * s->desc->nb_components;
yading@10 351 int i, x, buf_size = s->buf_size;
yading@10 352 int av_unused ret;
yading@10 353
yading@10 354 line_offset = AV_RL64(s->table + jobnr * 8);
yading@10 355 // Check if the buffer has the required bytes needed from the offset
yading@10 356 if (line_offset > buf_size - 8)
yading@10 357 return AVERROR_INVALIDDATA;
yading@10 358
yading@10 359 src = buf + line_offset + 8;
yading@10 360 line = AV_RL32(src - 8);
yading@10 361 if (line < s->ymin || line > s->ymax)
yading@10 362 return AVERROR_INVALIDDATA;
yading@10 363
yading@10 364 data_size = AV_RL32(src - 4);
yading@10 365 if (data_size <= 0 || data_size > buf_size)
yading@10 366 return AVERROR_INVALIDDATA;
yading@10 367
yading@10 368 s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1);
yading@10 369 uncompressed_size = s->scan_line_size * s->ysize;
yading@10 370 if ((s->compr == EXR_RAW && (data_size != uncompressed_size ||
yading@10 371 line_offset > buf_size - uncompressed_size)) ||
yading@10 372 (s->compr != EXR_RAW && (data_size > uncompressed_size ||
yading@10 373 line_offset > buf_size - data_size))) {
yading@10 374 return AVERROR_INVALIDDATA;
yading@10 375 }
yading@10 376
yading@10 377 if (data_size < uncompressed_size) {
yading@10 378 av_fast_padded_malloc(&td->uncompressed_data, &td->uncompressed_size, uncompressed_size);
yading@10 379 av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size);
yading@10 380 if (!td->uncompressed_data || !td->tmp)
yading@10 381 return AVERROR(ENOMEM);
yading@10 382
yading@10 383 switch (s->compr) {
yading@10 384 case EXR_ZIP1:
yading@10 385 case EXR_ZIP16:
yading@10 386 ret = zip_uncompress(src, data_size, uncompressed_size, td);
yading@10 387 break;
yading@10 388 case EXR_PXR24:
yading@10 389 ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td);
yading@10 390 break;
yading@10 391 case EXR_RLE:
yading@10 392 ret = rle_uncompress(src, data_size, uncompressed_size, td);
yading@10 393 }
yading@10 394
yading@10 395 src = td->uncompressed_data;
yading@10 396 }
yading@10 397
yading@10 398 channel_buffer[0] = src + xdelta * s->channel_offsets[0];
yading@10 399 channel_buffer[1] = src + xdelta * s->channel_offsets[1];
yading@10 400 channel_buffer[2] = src + xdelta * s->channel_offsets[2];
yading@10 401 if (s->channel_offsets[3] >= 0)
yading@10 402 channel_buffer[3] = src + xdelta * s->channel_offsets[3];
yading@10 403
yading@10 404 ptr = p->data[0] + line * p->linesize[0];
yading@10 405 for (i = 0; i < s->scan_lines_per_block && line + i <= s->ymax; i++, ptr += p->linesize[0]) {
yading@10 406 const uint8_t *r, *g, *b, *a;
yading@10 407
yading@10 408 r = channel_buffer[0];
yading@10 409 g = channel_buffer[1];
yading@10 410 b = channel_buffer[2];
yading@10 411 if (channel_buffer[3])
yading@10 412 a = channel_buffer[3];
yading@10 413
yading@10 414 ptr_x = (uint16_t *)ptr;
yading@10 415
yading@10 416 // Zero out the start if xmin is not 0
yading@10 417 memset(ptr_x, 0, bxmin);
yading@10 418 ptr_x += s->xmin * s->desc->nb_components;
yading@10 419 if (s->pixel_type == EXR_FLOAT) {
yading@10 420 // 32-bit
yading@10 421 for (x = 0; x < xdelta; x++) {
yading@10 422 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r));
yading@10 423 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g));
yading@10 424 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b));
yading@10 425 if (channel_buffer[3])
yading@10 426 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
yading@10 427 }
yading@10 428 } else {
yading@10 429 // 16-bit
yading@10 430 for (x = 0; x < xdelta; x++) {
yading@10 431 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r));
yading@10 432 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g));
yading@10 433 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b));
yading@10 434 if (channel_buffer[3])
yading@10 435 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
yading@10 436 }
yading@10 437 }
yading@10 438
yading@10 439 // Zero out the end if xmax+1 is not w
yading@10 440 memset(ptr_x, 0, axmax);
yading@10 441
yading@10 442 channel_buffer[0] += s->scan_line_size;
yading@10 443 channel_buffer[1] += s->scan_line_size;
yading@10 444 channel_buffer[2] += s->scan_line_size;
yading@10 445 if (channel_buffer[3])
yading@10 446 channel_buffer[3] += s->scan_line_size;
yading@10 447 }
yading@10 448
yading@10 449 return 0;
yading@10 450 }
yading@10 451
yading@10 452 static int decode_frame(AVCodecContext *avctx,
yading@10 453 void *data,
yading@10 454 int *got_frame,
yading@10 455 AVPacket *avpkt)
yading@10 456 {
yading@10 457 const uint8_t *buf = avpkt->data;
yading@10 458 unsigned int buf_size = avpkt->size;
yading@10 459 const uint8_t *buf_end = buf + buf_size;
yading@10 460
yading@10 461 EXRContext *const s = avctx->priv_data;
yading@10 462 ThreadFrame frame = { .f = data };
yading@10 463 AVFrame *picture = data;
yading@10 464 uint8_t *ptr;
yading@10 465
yading@10 466 int i, y, magic_number, version, flags, ret;
yading@10 467 int w = 0;
yading@10 468 int h = 0;
yading@10 469
yading@10 470 int out_line_size;
yading@10 471 int scan_line_blocks;
yading@10 472
yading@10 473 unsigned int current_channel_offset = 0;
yading@10 474
yading@10 475 s->xmin = ~0;
yading@10 476 s->xmax = ~0;
yading@10 477 s->ymin = ~0;
yading@10 478 s->ymax = ~0;
yading@10 479 s->xdelta = ~0;
yading@10 480 s->ydelta = ~0;
yading@10 481 s->channel_offsets[0] = -1;
yading@10 482 s->channel_offsets[1] = -1;
yading@10 483 s->channel_offsets[2] = -1;
yading@10 484 s->channel_offsets[3] = -1;
yading@10 485 s->pixel_type = -1;
yading@10 486 s->nb_channels = 0;
yading@10 487 s->compr = -1;
yading@10 488 s->buf = buf;
yading@10 489 s->buf_size = buf_size;
yading@10 490
yading@10 491 if (buf_size < 10) {
yading@10 492 av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
yading@10 493 return AVERROR_INVALIDDATA;
yading@10 494 }
yading@10 495
yading@10 496 magic_number = bytestream_get_le32(&buf);
yading@10 497 if (magic_number != 20000630) { // As per documentation of OpenEXR it's supposed to be int 20000630 little-endian
yading@10 498 av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number);
yading@10 499 return AVERROR_INVALIDDATA;
yading@10 500 }
yading@10 501
yading@10 502 version = bytestream_get_byte(&buf);
yading@10 503 if (version != 2) {
yading@10 504 av_log(avctx, AV_LOG_ERROR, "Unsupported version %d\n", version);
yading@10 505 return AVERROR_PATCHWELCOME;
yading@10 506 }
yading@10 507
yading@10 508 flags = bytestream_get_le24(&buf);
yading@10 509 if (flags & 0x2) {
yading@10 510 av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
yading@10 511 return AVERROR_PATCHWELCOME;
yading@10 512 }
yading@10 513
yading@10 514 // Parse the header
yading@10 515 while (buf < buf_end && buf[0]) {
yading@10 516 unsigned int variable_buffer_data_size;
yading@10 517 // Process the channel list
yading@10 518 if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) {
yading@10 519 const uint8_t *channel_list_end;
yading@10 520 if (!variable_buffer_data_size)
yading@10 521 return AVERROR_INVALIDDATA;
yading@10 522
yading@10 523 channel_list_end = buf + variable_buffer_data_size;
yading@10 524 while (channel_list_end - buf >= 19) {
yading@10 525 EXRChannel *channel;
yading@10 526 int current_pixel_type = -1;
yading@10 527 int channel_index = -1;
yading@10 528 int xsub, ysub;
yading@10 529
yading@10 530 if (!strcmp(buf, "R"))
yading@10 531 channel_index = 0;
yading@10 532 else if (!strcmp(buf, "G"))
yading@10 533 channel_index = 1;
yading@10 534 else if (!strcmp(buf, "B"))
yading@10 535 channel_index = 2;
yading@10 536 else if (!strcmp(buf, "A"))
yading@10 537 channel_index = 3;
yading@10 538 else
yading@10 539 av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
yading@10 540
yading@10 541 while (bytestream_get_byte(&buf) && buf < channel_list_end)
yading@10 542 continue; /* skip */
yading@10 543
yading@10 544 if (channel_list_end - * &buf < 4) {
yading@10 545 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
yading@10 546 return AVERROR_INVALIDDATA;
yading@10 547 }
yading@10 548
yading@10 549 current_pixel_type = bytestream_get_le32(&buf);
yading@10 550 if (current_pixel_type > 2) {
yading@10 551 av_log(avctx, AV_LOG_ERROR, "Unknown pixel type\n");
yading@10 552 return AVERROR_INVALIDDATA;
yading@10 553 }
yading@10 554
yading@10 555 buf += 4;
yading@10 556 xsub = bytestream_get_le32(&buf);
yading@10 557 ysub = bytestream_get_le32(&buf);
yading@10 558 if (xsub != 1 || ysub != 1) {
yading@10 559 av_log(avctx, AV_LOG_ERROR, "Unsupported subsampling %dx%d\n", xsub, ysub);
yading@10 560 return AVERROR_PATCHWELCOME;
yading@10 561 }
yading@10 562
yading@10 563 if (channel_index >= 0) {
yading@10 564 if (s->pixel_type != -1 && s->pixel_type != current_pixel_type) {
yading@10 565 av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n");
yading@10 566 return AVERROR_INVALIDDATA;
yading@10 567 }
yading@10 568 s->pixel_type = current_pixel_type;
yading@10 569 s->channel_offsets[channel_index] = current_channel_offset;
yading@10 570 }
yading@10 571
yading@10 572 s->channels = av_realloc_f(s->channels, ++s->nb_channels, sizeof(EXRChannel));
yading@10 573 if (!s->channels)
yading@10 574 return AVERROR(ENOMEM);
yading@10 575 channel = &s->channels[s->nb_channels - 1];
yading@10 576 channel->pixel_type = current_pixel_type;
yading@10 577 channel->xsub = xsub;
yading@10 578 channel->ysub = ysub;
yading@10 579
yading@10 580 current_channel_offset += 1 << current_pixel_type;
yading@10 581 }
yading@10 582
yading@10 583 /* Check if all channels are set with an offset or if the channels
yading@10 584 * are causing an overflow */
yading@10 585
yading@10 586 if (FFMIN3(s->channel_offsets[0],
yading@10 587 s->channel_offsets[1],
yading@10 588 s->channel_offsets[2]) < 0) {
yading@10 589 if (s->channel_offsets[0] < 0)
yading@10 590 av_log(avctx, AV_LOG_ERROR, "Missing red channel\n");
yading@10 591 if (s->channel_offsets[1] < 0)
yading@10 592 av_log(avctx, AV_LOG_ERROR, "Missing green channel\n");
yading@10 593 if (s->channel_offsets[2] < 0)
yading@10 594 av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n");
yading@10 595 return AVERROR_INVALIDDATA;
yading@10 596 }
yading@10 597
yading@10 598 buf = channel_list_end;
yading@10 599 continue;
yading@10 600 } else if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
yading@10 601 if (!variable_buffer_data_size)
yading@10 602 return AVERROR_INVALIDDATA;
yading@10 603
yading@10 604 s->xmin = AV_RL32(buf);
yading@10 605 s->ymin = AV_RL32(buf + 4);
yading@10 606 s->xmax = AV_RL32(buf + 8);
yading@10 607 s->ymax = AV_RL32(buf + 12);
yading@10 608 s->xdelta = (s->xmax - s->xmin) + 1;
yading@10 609 s->ydelta = (s->ymax - s->ymin) + 1;
yading@10 610
yading@10 611 buf += variable_buffer_data_size;
yading@10 612 continue;
yading@10 613 } else if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
yading@10 614 if (!variable_buffer_data_size)
yading@10 615 return AVERROR_INVALIDDATA;
yading@10 616
yading@10 617 w = AV_RL32(buf + 8) + 1;
yading@10 618 h = AV_RL32(buf + 12) + 1;
yading@10 619
yading@10 620 buf += variable_buffer_data_size;
yading@10 621 continue;
yading@10 622 } else if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
yading@10 623 if (!variable_buffer_data_size)
yading@10 624 return AVERROR_INVALIDDATA;
yading@10 625
yading@10 626 av_log(avctx, AV_LOG_DEBUG, "line order : %d\n", *buf);
yading@10 627 if (*buf > 2) {
yading@10 628 av_log(avctx, AV_LOG_ERROR, "Unknown line order\n");
yading@10 629 return AVERROR_INVALIDDATA;
yading@10 630 }
yading@10 631
yading@10 632 buf += variable_buffer_data_size;
yading@10 633 continue;
yading@10 634 } else if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) {
yading@10 635 if (!variable_buffer_data_size)
yading@10 636 return AVERROR_INVALIDDATA;
yading@10 637
yading@10 638 avctx->sample_aspect_ratio = av_d2q(av_int2float(AV_RL32(buf)), 255);
yading@10 639
yading@10 640 buf += variable_buffer_data_size;
yading@10 641 continue;
yading@10 642 } else if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
yading@10 643 if (!variable_buffer_data_size)
yading@10 644 return AVERROR_INVALIDDATA;
yading@10 645
yading@10 646 if (s->compr == -1)
yading@10 647 s->compr = *buf;
yading@10 648 else
yading@10 649 av_log(avctx, AV_LOG_WARNING, "Found more than one compression attribute\n");
yading@10 650
yading@10 651 buf += variable_buffer_data_size;
yading@10 652 continue;
yading@10 653 }
yading@10 654
yading@10 655 // Check if there is enough bytes for a header
yading@10 656 if (buf_end - buf <= 9) {
yading@10 657 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
yading@10 658 return AVERROR_INVALIDDATA;
yading@10 659 }
yading@10 660
yading@10 661 // Process unknown variables
yading@10 662 for (i = 0; i < 2; i++) {
yading@10 663 // Skip variable name/type
yading@10 664 while (++buf < buf_end)
yading@10 665 if (buf[0] == 0x0)
yading@10 666 break;
yading@10 667 }
yading@10 668 buf++;
yading@10 669 // Skip variable length
yading@10 670 if (buf_end - buf >= 5) {
yading@10 671 variable_buffer_data_size = get_header_variable_length(&buf, buf_end);
yading@10 672 if (!variable_buffer_data_size) {
yading@10 673 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
yading@10 674 return AVERROR_INVALIDDATA;
yading@10 675 }
yading@10 676 buf += variable_buffer_data_size;
yading@10 677 }
yading@10 678 }
yading@10 679
yading@10 680 if (s->compr == -1) {
yading@10 681 av_log(avctx, AV_LOG_ERROR, "Missing compression attribute\n");
yading@10 682 return AVERROR_INVALIDDATA;
yading@10 683 }
yading@10 684
yading@10 685 if (buf >= buf_end) {
yading@10 686 av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n");
yading@10 687 return AVERROR_INVALIDDATA;
yading@10 688 }
yading@10 689 buf++;
yading@10 690
yading@10 691 switch (s->pixel_type) {
yading@10 692 case EXR_FLOAT:
yading@10 693 case EXR_HALF:
yading@10 694 if (s->channel_offsets[3] >= 0)
yading@10 695 avctx->pix_fmt = AV_PIX_FMT_RGBA64;
yading@10 696 else
yading@10 697 avctx->pix_fmt = AV_PIX_FMT_RGB48;
yading@10 698 break;
yading@10 699 case EXR_UINT:
yading@10 700 avpriv_request_sample(avctx, "32-bit unsigned int");
yading@10 701 return AVERROR_PATCHWELCOME;
yading@10 702 default:
yading@10 703 av_log(avctx, AV_LOG_ERROR, "Missing channel list\n");
yading@10 704 return AVERROR_INVALIDDATA;
yading@10 705 }
yading@10 706
yading@10 707 switch (s->compr) {
yading@10 708 case EXR_RAW:
yading@10 709 case EXR_RLE:
yading@10 710 case EXR_ZIP1:
yading@10 711 s->scan_lines_per_block = 1;
yading@10 712 break;
yading@10 713 case EXR_PXR24:
yading@10 714 case EXR_ZIP16:
yading@10 715 s->scan_lines_per_block = 16;
yading@10 716 break;
yading@10 717 default:
yading@10 718 av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
yading@10 719 return AVERROR_PATCHWELCOME;
yading@10 720 }
yading@10 721
yading@10 722 if (av_image_check_size(w, h, 0, avctx))
yading@10 723 return AVERROR_INVALIDDATA;
yading@10 724
yading@10 725 // Verify the xmin, xmax, ymin, ymax and xdelta before setting the actual image size
yading@10 726 if (s->xmin > s->xmax ||
yading@10 727 s->ymin > s->ymax ||
yading@10 728 s->xdelta != s->xmax - s->xmin + 1 ||
yading@10 729 s->xmax >= w || s->ymax >= h) {
yading@10 730 av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
yading@10 731 return AVERROR_INVALIDDATA;
yading@10 732 }
yading@10 733
yading@10 734 if (w != avctx->width || h != avctx->height) {
yading@10 735 avcodec_set_dimensions(avctx, w, h);
yading@10 736 }
yading@10 737
yading@10 738 s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
yading@10 739 out_line_size = avctx->width * 2 * s->desc->nb_components;
yading@10 740 s->scan_line_size = s->xdelta * current_channel_offset;
yading@10 741 scan_line_blocks = (s->ydelta + s->scan_lines_per_block - 1) / s->scan_lines_per_block;
yading@10 742
yading@10 743 if (s->compr != EXR_RAW) {
yading@10 744 size_t thread_data_size, prev_size;
yading@10 745 EXRThreadData *m;
yading@10 746
yading@10 747 prev_size = s->thread_data_size;
yading@10 748 if (av_size_mult(avctx->thread_count, sizeof(EXRThreadData), &thread_data_size))
yading@10 749 return AVERROR(EINVAL);
yading@10 750
yading@10 751 m = av_fast_realloc(s->thread_data, &s->thread_data_size, thread_data_size);
yading@10 752 if (!m)
yading@10 753 return AVERROR(ENOMEM);
yading@10 754 s->thread_data = m;
yading@10 755 memset(s->thread_data + prev_size, 0, s->thread_data_size - prev_size);
yading@10 756 }
yading@10 757
yading@10 758 if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
yading@10 759 return ret;
yading@10 760
yading@10 761 if (buf_end - buf < scan_line_blocks * 8)
yading@10 762 return AVERROR_INVALIDDATA;
yading@10 763 s->table = buf;
yading@10 764 ptr = picture->data[0];
yading@10 765
yading@10 766 // Zero out the start if ymin is not 0
yading@10 767 for (y = 0; y < s->ymin; y++) {
yading@10 768 memset(ptr, 0, out_line_size);
yading@10 769 ptr += picture->linesize[0];
yading@10 770 }
yading@10 771
yading@10 772 s->picture = picture;
yading@10 773 avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks);
yading@10 774
yading@10 775 // Zero out the end if ymax+1 is not h
yading@10 776 for (y = s->ymax + 1; y < avctx->height; y++) {
yading@10 777 memset(ptr, 0, out_line_size);
yading@10 778 ptr += picture->linesize[0];
yading@10 779 }
yading@10 780
yading@10 781 *got_frame = 1;
yading@10 782
yading@10 783 return buf_size;
yading@10 784 }
yading@10 785
yading@10 786 static av_cold int decode_end(AVCodecContext *avctx)
yading@10 787 {
yading@10 788 EXRContext *s = avctx->priv_data;
yading@10 789 int i;
yading@10 790
yading@10 791 for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) {
yading@10 792 EXRThreadData *td = &s->thread_data[i];
yading@10 793 av_free(td->uncompressed_data);
yading@10 794 av_free(td->tmp);
yading@10 795 }
yading@10 796
yading@10 797 av_freep(&s->thread_data);
yading@10 798 s->thread_data_size = 0;
yading@10 799 av_freep(&s->channels);
yading@10 800
yading@10 801 return 0;
yading@10 802 }
yading@10 803
yading@10 804 AVCodec ff_exr_decoder = {
yading@10 805 .name = "exr",
yading@10 806 .type = AVMEDIA_TYPE_VIDEO,
yading@10 807 .id = AV_CODEC_ID_EXR,
yading@10 808 .priv_data_size = sizeof(EXRContext),
yading@10 809 .close = decode_end,
yading@10 810 .decode = decode_frame,
yading@10 811 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
yading@10 812 .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
yading@10 813 };