00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00033 #include <zlib.h>
00034
00035 #include "avcodec.h"
00036 #include "bytestream.h"
00037 #include "mathops.h"
00038 #include "thread.h"
00039 #include "libavutil/imgutils.h"
00040
00041 enum ExrCompr {
00042 EXR_RAW = 0,
00043 EXR_RLE = 1,
00044 EXR_ZIP1 = 2,
00045 EXR_ZIP16 = 3,
00046 EXR_PIZ = 4,
00047 EXR_B44 = 6,
00048 EXR_B44A = 7,
00049 };
00050
00051 typedef struct EXRContext {
00052 AVFrame picture;
00053 int compr;
00054 int bits_per_color_id;
00055 int channel_offsets[4];
00056
00057 uint8_t *uncompressed_data;
00058 int uncompressed_size;
00059
00060 uint8_t *tmp;
00061 int tmp_size;
00062 } EXRContext;
00063
00070 static inline uint16_t exr_flt2uint(uint32_t v)
00071 {
00072 unsigned int exp = v >> 23;
00073
00074
00075 if (exp<= 127 + 7 - 24)
00076 return 0;
00077 if (exp >= 127)
00078 return 0xffff;
00079 v &= 0x007fffff;
00080 return (v + (1 << 23)) >> (127 + 7 - exp);
00081 }
00082
00089 static inline uint16_t exr_halflt2uint(uint16_t v)
00090 {
00091 unsigned exp = 14 - (v >> 10);
00092 if (exp >= 14) {
00093 if (exp == 14) return (v >> 9) & 1;
00094 else return (v & 0x8000) ? 0 : 0xffff;
00095 }
00096 v <<= 6;
00097 return (v + (1 << 16)) >> (exp + 1);
00098 }
00099
00108 static unsigned int get_header_variable_length(const uint8_t **buf,
00109 const uint8_t *buf_end)
00110 {
00111 unsigned int variable_buffer_data_size = bytestream_get_le32(buf);
00112 if (variable_buffer_data_size >= buf_end - *buf)
00113 return 0;
00114 return variable_buffer_data_size;
00115 }
00116
00131 static int check_header_variable(AVCodecContext *avctx,
00132 const uint8_t **buf,
00133 const uint8_t *buf_end,
00134 const char *value_name,
00135 const char *value_type,
00136 unsigned int minimum_length,
00137 unsigned int *variable_buffer_data_size)
00138 {
00139 if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) {
00140 *buf += strlen(value_name)+1;
00141 if (!strcmp(*buf, value_type)) {
00142 *buf += strlen(value_type)+1;
00143 *variable_buffer_data_size = get_header_variable_length(buf, buf_end);
00144 if (!*variable_buffer_data_size)
00145 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00146 if (*variable_buffer_data_size > buf_end - *buf)
00147 return -1;
00148 return 1;
00149 }
00150 *buf -= strlen(value_name)+1;
00151 av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name);
00152 }
00153 return -1;
00154 }
00155
00156 static void predictor(uint8_t *src, int size)
00157 {
00158 uint8_t *t = src + 1;
00159 uint8_t *stop = src + size;
00160
00161 while (t < stop) {
00162 int d = (int)t[-1] + (int)t[0] - 128;
00163 t[0] = d;
00164 ++t;
00165 }
00166 }
00167
00168 static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
00169 {
00170 const int8_t *t1 = src;
00171 const int8_t *t2 = src + (size + 1) / 2;
00172 int8_t *s = dst;
00173 int8_t *stop = s + size;
00174
00175 while (1) {
00176 if (s < stop)
00177 *(s++) = *(t1++);
00178 else
00179 break;
00180
00181 if (s < stop)
00182 *(s++) = *(t2++);
00183 else
00184 break;
00185 }
00186 }
00187
00188 static int rle_uncompress(const uint8_t *src, int ssize, uint8_t *dst, int dsize)
00189 {
00190 int8_t *d = (int8_t *)dst;
00191 int8_t *s = (int8_t *)src;
00192 int8_t *dend = d + dsize;
00193 int count;
00194
00195 while (ssize > 0) {
00196 count = *s++;
00197
00198 if (count < 0) {
00199 count = -count;
00200
00201 if ((dsize -= count ) < 0 ||
00202 (ssize -= count + 1) < 0)
00203 return -1;
00204
00205 while (count--)
00206 *d++ = *s++;
00207 } else {
00208 count++;
00209
00210 if ((dsize -= count) < 0 ||
00211 (ssize -= 2 ) < 0)
00212 return -1;
00213
00214 while (count--)
00215 *d++ = *s;
00216
00217 s++;
00218 }
00219 }
00220
00221 return dend != d;
00222 }
00223
00224 static int decode_frame(AVCodecContext *avctx,
00225 void *data,
00226 int *data_size,
00227 AVPacket *avpkt)
00228 {
00229 const uint8_t *buf = avpkt->data;
00230 unsigned int buf_size = avpkt->size;
00231 const uint8_t *buf_end = buf + buf_size;
00232
00233 EXRContext *const s = avctx->priv_data;
00234 AVFrame *picture = data;
00235 AVFrame *const p = &s->picture;
00236 uint8_t *ptr;
00237
00238 int i, x, y, stride, magic_number, version_flag, ret;
00239 int w = 0;
00240 int h = 0;
00241 unsigned int xmin = ~0;
00242 unsigned int xmax = ~0;
00243 unsigned int ymin = ~0;
00244 unsigned int ymax = ~0;
00245 unsigned int xdelta = ~0;
00246
00247 int out_line_size;
00248 int bxmin, axmax;
00249 int scan_lines_per_block;
00250 unsigned long scan_line_size;
00251 unsigned long uncompressed_size;
00252
00253 unsigned int current_channel_offset = 0;
00254
00255 s->channel_offsets[0] = -1;
00256 s->channel_offsets[1] = -1;
00257 s->channel_offsets[2] = -1;
00258 s->channel_offsets[3] = -1;
00259 s->bits_per_color_id = -1;
00260
00261 if (buf_size < 10) {
00262 av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
00263 return AVERROR_INVALIDDATA;
00264 }
00265
00266 magic_number = bytestream_get_le32(&buf);
00267 if (magic_number != 20000630) {
00268 av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number);
00269 return AVERROR_INVALIDDATA;
00270 }
00271
00272 version_flag = bytestream_get_le32(&buf);
00273 if ((version_flag & 0x200) == 0x200) {
00274 av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
00275 return AVERROR_PATCHWELCOME;
00276 }
00277
00278
00279 while (buf < buf_end && buf[0]) {
00280 unsigned int variable_buffer_data_size;
00281
00282 if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) {
00283 const uint8_t *channel_list_end;
00284 if (!variable_buffer_data_size)
00285 return AVERROR_INVALIDDATA;
00286
00287 channel_list_end = buf + variable_buffer_data_size;
00288 while (channel_list_end - buf >= 19) {
00289 int current_bits_per_color_id = -1;
00290 int channel_index = -1;
00291
00292 if (!strcmp(buf, "R"))
00293 channel_index = 0;
00294 else if (!strcmp(buf, "G"))
00295 channel_index = 1;
00296 else if (!strcmp(buf, "B"))
00297 channel_index = 2;
00298 else if (!strcmp(buf, "A"))
00299 channel_index = 3;
00300 else
00301 av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
00302
00303 while (bytestream_get_byte(&buf) && buf < channel_list_end)
00304 continue;
00305
00306 if (channel_list_end - * &buf < 4) {
00307 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00308 return AVERROR_INVALIDDATA;
00309 }
00310
00311 current_bits_per_color_id = bytestream_get_le32(&buf);
00312 if (current_bits_per_color_id > 2) {
00313 av_log(avctx, AV_LOG_ERROR, "Unknown color format\n");
00314 return AVERROR_INVALIDDATA;
00315 }
00316
00317 if (channel_index >= 0) {
00318 if (s->bits_per_color_id != -1 && s->bits_per_color_id != current_bits_per_color_id) {
00319 av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n");
00320 return AVERROR_INVALIDDATA;
00321 }
00322 s->bits_per_color_id = current_bits_per_color_id;
00323 s->channel_offsets[channel_index] = current_channel_offset;
00324 }
00325
00326 current_channel_offset += 1 << current_bits_per_color_id;
00327 buf += 12;
00328 }
00329
00330
00331
00332
00333 if (FFMIN3(s->channel_offsets[0],
00334 s->channel_offsets[1],
00335 s->channel_offsets[2]) < 0) {
00336 if (s->channel_offsets[0] < 0)
00337 av_log(avctx, AV_LOG_ERROR, "Missing red channel\n");
00338 if (s->channel_offsets[1] < 0)
00339 av_log(avctx, AV_LOG_ERROR, "Missing green channel\n");
00340 if (s->channel_offsets[2] < 0)
00341 av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n");
00342 return AVERROR_INVALIDDATA;
00343 }
00344
00345 buf = channel_list_end;
00346 continue;
00347 }
00348
00349
00350 if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
00351 if (!variable_buffer_data_size)
00352 return AVERROR_INVALIDDATA;
00353
00354 xmin = AV_RL32(buf);
00355 ymin = AV_RL32(buf + 4);
00356 xmax = AV_RL32(buf + 8);
00357 ymax = AV_RL32(buf + 12);
00358 xdelta = (xmax-xmin) + 1;
00359
00360 buf += variable_buffer_data_size;
00361 continue;
00362 }
00363
00364
00365 if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
00366 if (!variable_buffer_data_size)
00367 return AVERROR_INVALIDDATA;
00368
00369 w = AV_RL32(buf + 8) + 1;
00370 h = AV_RL32(buf + 12) + 1;
00371
00372 buf += variable_buffer_data_size;
00373 continue;
00374 }
00375
00376
00377 if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
00378 if (!variable_buffer_data_size)
00379 return AVERROR_INVALIDDATA;
00380
00381 if (*buf) {
00382 av_log(avctx, AV_LOG_ERROR, "Doesn't support this line order : %d\n", *buf);
00383 return AVERROR_PATCHWELCOME;
00384 }
00385
00386 buf += variable_buffer_data_size;
00387 continue;
00388 }
00389
00390
00391 if (check_header_variable(avctx, &buf, buf_end, "pixelAspectRatio", "float", 31, &variable_buffer_data_size) >= 0) {
00392 if (!variable_buffer_data_size)
00393 return AVERROR_INVALIDDATA;
00394
00395 avctx->sample_aspect_ratio = av_d2q(av_int2float(AV_RL32(buf)), 255);
00396
00397 buf += variable_buffer_data_size;
00398 continue;
00399 }
00400
00401
00402 if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
00403 if (!variable_buffer_data_size)
00404 return AVERROR_INVALIDDATA;
00405
00406 if (s->compr == -1)
00407 s->compr = *buf;
00408 else
00409 av_log(avctx, AV_LOG_WARNING, "Found more than one compression attribute\n");
00410
00411 buf += variable_buffer_data_size;
00412 continue;
00413 }
00414
00415
00416 if (buf_end - buf <= 9) {
00417 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00418 return AVERROR_INVALIDDATA;
00419 }
00420
00421
00422 for (i = 0; i < 2; i++) {
00423
00424 while (++buf < buf_end)
00425 if (buf[0] == 0x0)
00426 break;
00427 }
00428 buf++;
00429
00430 if (buf_end - buf >= 5) {
00431 variable_buffer_data_size = get_header_variable_length(&buf, buf_end);
00432 if (!variable_buffer_data_size) {
00433 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00434 return AVERROR_INVALIDDATA;
00435 }
00436 buf += variable_buffer_data_size;
00437 }
00438 }
00439
00440 if (s->compr == -1) {
00441 av_log(avctx, AV_LOG_ERROR, "Missing compression attribute\n");
00442 return AVERROR_INVALIDDATA;
00443 }
00444
00445 if (buf >= buf_end) {
00446 av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n");
00447 return AVERROR_INVALIDDATA;
00448 }
00449 buf++;
00450
00451 switch (s->bits_per_color_id) {
00452 case 2:
00453 case 1:
00454 if (s->channel_offsets[3] >= 0)
00455 avctx->pix_fmt = PIX_FMT_RGBA64;
00456 else
00457 avctx->pix_fmt = PIX_FMT_RGB48;
00458 break;
00459
00460 case 0:
00461 av_log_missing_feature(avctx, "8-bit OpenEXR", 1);
00462 return AVERROR_PATCHWELCOME;
00463 default:
00464 av_log(avctx, AV_LOG_ERROR, "Unknown color format : %d\n", s->bits_per_color_id);
00465 return AVERROR_INVALIDDATA;
00466 }
00467
00468 switch (s->compr) {
00469 case EXR_RAW:
00470 case EXR_RLE:
00471 case EXR_ZIP1:
00472 scan_lines_per_block = 1;
00473 break;
00474 case EXR_ZIP16:
00475 scan_lines_per_block = 16;
00476 break;
00477 default:
00478 av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
00479 return AVERROR_PATCHWELCOME;
00480 }
00481
00482 if (s->picture.data[0])
00483 ff_thread_release_buffer(avctx, &s->picture);
00484 if (av_image_check_size(w, h, 0, avctx))
00485 return AVERROR_INVALIDDATA;
00486
00487
00488 if (xmin > xmax || ymin > ymax || xdelta != xmax - xmin + 1 || xmax >= w || ymax >= h) {
00489 av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
00490 return AVERROR_INVALIDDATA;
00491 }
00492
00493 if (w != avctx->width || h != avctx->height) {
00494 avcodec_set_dimensions(avctx, w, h);
00495 }
00496
00497 bxmin = xmin * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00498 axmax = (avctx->width - (xmax + 1)) * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00499 out_line_size = avctx->width * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00500 scan_line_size = xdelta * current_channel_offset;
00501 uncompressed_size = scan_line_size * scan_lines_per_block;
00502
00503 if (s->compr != EXR_RAW) {
00504 av_fast_padded_malloc(&s->uncompressed_data, &s->uncompressed_size, uncompressed_size);
00505 av_fast_padded_malloc(&s->tmp, &s->tmp_size, uncompressed_size);
00506 if (!s->uncompressed_data || !s->tmp)
00507 return AVERROR(ENOMEM);
00508 }
00509
00510 if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
00511 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00512 return ret;
00513 }
00514
00515 ptr = p->data[0];
00516 stride = p->linesize[0];
00517
00518
00519 for (y = 0; y < ymin; y++) {
00520 memset(ptr, 0, out_line_size);
00521 ptr += stride;
00522 }
00523
00524
00525 for (y = ymin; y <= ymax; y += scan_lines_per_block) {
00526 uint16_t *ptr_x = (uint16_t *)ptr;
00527 if (buf_end - buf > 8) {
00528
00529
00530 const uint64_t line_offset = bytestream_get_le64(&buf) + 8;
00531 int32_t data_size;
00532
00533
00534 if ((line_offset > buf_size) ||
00535 (s->compr == EXR_RAW && line_offset > avpkt->size - xdelta * current_channel_offset) ||
00536 (s->compr != EXR_RAW && line_offset > buf_size - (data_size = AV_RL32(avpkt->data + line_offset - 4)))) {
00537
00538 av_log(avctx, AV_LOG_WARNING, "Line offset for line %d is out of reach setting it to black\n", y);
00539 for (i = 0; i < scan_lines_per_block && y + i <= ymax; i++, ptr += stride) {
00540 ptr_x = (uint16_t *)ptr;
00541 memset(ptr_x, 0, out_line_size);
00542 }
00543 } else {
00544 const uint8_t *red_channel_buffer, *green_channel_buffer, *blue_channel_buffer, *alpha_channel_buffer = 0;
00545
00546 if (scan_lines_per_block > 1)
00547 uncompressed_size = scan_line_size * FFMIN(scan_lines_per_block, ymax - y + 1);
00548 if ((s->compr == EXR_ZIP1 || s->compr == EXR_ZIP16) && data_size < uncompressed_size) {
00549 unsigned long dest_len = uncompressed_size;
00550
00551 if (uncompress(s->tmp, &dest_len, avpkt->data + line_offset, data_size) != Z_OK ||
00552 dest_len != uncompressed_size) {
00553 av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n");
00554 return AVERROR(EINVAL);
00555 }
00556 } else if (s->compr == EXR_RLE && data_size < uncompressed_size) {
00557 if (rle_uncompress(avpkt->data + line_offset, data_size, s->tmp, uncompressed_size)) {
00558 av_log(avctx, AV_LOG_ERROR, "error during rle decompression\n");
00559 return AVERROR(EINVAL);
00560 }
00561 }
00562
00563 if (s->compr != EXR_RAW && data_size < uncompressed_size) {
00564 predictor(s->tmp, uncompressed_size);
00565 reorder_pixels(s->tmp, s->uncompressed_data, uncompressed_size);
00566
00567 red_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[0];
00568 green_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[1];
00569 blue_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[2];
00570 if (s->channel_offsets[3] >= 0)
00571 alpha_channel_buffer = s->uncompressed_data + xdelta * s->channel_offsets[3];
00572 } else {
00573 red_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[0];
00574 green_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[1];
00575 blue_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[2];
00576 if (s->channel_offsets[3] >= 0)
00577 alpha_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[3];
00578 }
00579
00580 for (i = 0; i < scan_lines_per_block && y + i <= ymax; i++, ptr += stride) {
00581 const uint8_t *r, *g, *b, *a;
00582
00583 r = red_channel_buffer;
00584 g = green_channel_buffer;
00585 b = blue_channel_buffer;
00586 if (alpha_channel_buffer)
00587 a = alpha_channel_buffer;
00588
00589 ptr_x = (uint16_t *)ptr;
00590
00591
00592 memset(ptr_x, 0, bxmin);
00593 ptr_x += xmin * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00594 if (s->bits_per_color_id == 2) {
00595
00596 for (x = 0; x < xdelta; x++) {
00597 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&r));
00598 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&g));
00599 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&b));
00600 if (alpha_channel_buffer)
00601 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
00602 }
00603 } else {
00604
00605 for (x = 0; x < xdelta; x++) {
00606 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&r));
00607 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&g));
00608 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&b));
00609 if (alpha_channel_buffer)
00610 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
00611 }
00612 }
00613
00614
00615 memset(ptr_x, 0, axmax);
00616
00617 red_channel_buffer += scan_line_size;
00618 green_channel_buffer += scan_line_size;
00619 blue_channel_buffer += scan_line_size;
00620 if (alpha_channel_buffer)
00621 alpha_channel_buffer += scan_line_size;
00622 }
00623 }
00624 }
00625 }
00626
00627
00628 for (y = ymax + 1; y < avctx->height; y++) {
00629 memset(ptr, 0, out_line_size);
00630 ptr += stride;
00631 }
00632
00633 *picture = s->picture;
00634 *data_size = sizeof(AVPicture);
00635
00636 return buf_size;
00637 }
00638
00639 static av_cold int decode_init(AVCodecContext *avctx)
00640 {
00641 EXRContext *s = avctx->priv_data;
00642
00643 avcodec_get_frame_defaults(&s->picture);
00644 avctx->coded_frame = &s->picture;
00645
00646 s->compr = -1;
00647
00648 return 0;
00649 }
00650
00651 static av_cold int decode_end(AVCodecContext *avctx)
00652 {
00653 EXRContext *s = avctx->priv_data;
00654
00655 if (s->picture.data[0])
00656 avctx->release_buffer(avctx, &s->picture);
00657
00658 av_freep(&s->uncompressed_data);
00659 av_freep(&s->tmp);
00660
00661 return 0;
00662 }
00663
00664 AVCodec ff_exr_decoder = {
00665 .name = "exr",
00666 .type = AVMEDIA_TYPE_VIDEO,
00667 .id = AV_CODEC_ID_EXR,
00668 .priv_data_size = sizeof(EXRContext),
00669 .init = decode_init,
00670 .close = decode_end,
00671 .decode = decode_frame,
00672 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
00673 .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
00674 };