00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00033 #include "avcodec.h"
00034 #include "bytestream.h"
00035 #include "libavutil/imgutils.h"
00036
00037 enum ExrCompr {
00038 EXR_RAW = 0,
00039 EXR_RLE = 1,
00040 EXR_ZIP1 = 2,
00041 EXR_ZIP16 = 3,
00042 EXR_PIZ = 4,
00043 EXR_B44 = 6
00044 };
00045
00046 typedef struct EXRContext {
00047 AVFrame picture;
00048 int compr;
00049 int bits_per_color_id;
00050 int8_t channel_offsets[4];
00051 } EXRContext;
00052
00059 static inline uint16_t exr_flt2uint(uint32_t v)
00060 {
00061 unsigned int exp = v >> 23;
00062
00063
00064 if (exp<= 127 + 7 - 24)
00065 return 0;
00066 if (exp >= 127)
00067 return 0xffff;
00068 v &= 0x007fffff;
00069 return (v + (1 << 23)) >> (127 + 7 - exp);
00070 }
00071
00078 static inline uint16_t exr_halflt2uint(uint16_t v)
00079 {
00080 unsigned exp = 14 - (v >> 10);
00081 if (exp >= 14) {
00082 if (exp == 14) return (v >> 9) & 1;
00083 else return (v & 0x8000) ? 0 : 0xffff;
00084 }
00085 v <<= 6;
00086 return (v + (1 << 16)) >> (exp + 1);
00087 }
00088
00097 static unsigned int get_header_variable_length(const uint8_t **buf,
00098 const uint8_t *buf_end)
00099 {
00100 unsigned int variable_buffer_data_size = bytestream_get_le32(buf);
00101 if (variable_buffer_data_size >= buf_end - *buf)
00102 return 0;
00103 return variable_buffer_data_size;
00104 }
00105
00120 static int check_header_variable(AVCodecContext *avctx,
00121 const uint8_t **buf,
00122 const uint8_t *buf_end,
00123 const char *value_name,
00124 const char *value_type,
00125 unsigned int minimum_length,
00126 unsigned int *variable_buffer_data_size)
00127 {
00128 if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) {
00129 *buf += strlen(value_name)+1;
00130 if (!strcmp(*buf, value_type)) {
00131 *buf += strlen(value_type)+1;
00132 *variable_buffer_data_size = get_header_variable_length(buf, buf_end);
00133 if (!*variable_buffer_data_size)
00134 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00135 if (*variable_buffer_data_size > buf_end - *buf)
00136 return -1;
00137 return 1;
00138 }
00139 *buf -= strlen(value_name)+1;
00140 av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name);
00141 }
00142 return -1;
00143 }
00144
00145 static int decode_frame(AVCodecContext *avctx,
00146 void *data,
00147 int *data_size,
00148 AVPacket *avpkt)
00149 {
00150 const uint8_t *buf = avpkt->data;
00151 unsigned int buf_size = avpkt->size;
00152 const uint8_t *buf_end = buf + buf_size;
00153
00154 EXRContext *const s = avctx->priv_data;
00155 AVFrame *picture = data;
00156 AVFrame *const p = &s->picture;
00157 uint8_t *ptr;
00158
00159 int i, x, y, stride, magic_number, version_flag;
00160 int w = 0;
00161 int h = 0;
00162 unsigned int xmin = ~0;
00163 unsigned int xmax = ~0;
00164 unsigned int ymin = ~0;
00165 unsigned int ymax = ~0;
00166 unsigned int xdelta = ~0;
00167
00168 unsigned int current_channel_offset = 0;
00169
00170 s->channel_offsets[0] = -1;
00171 s->channel_offsets[1] = -1;
00172 s->channel_offsets[2] = -1;
00173 s->channel_offsets[3] = -1;
00174 s->bits_per_color_id = -1;
00175
00176 if (buf_end - buf < 10) {
00177 av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
00178 return -1;
00179 }
00180
00181 magic_number = bytestream_get_le32(&buf);
00182 if (magic_number != 20000630) {
00183 av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number);
00184 return -1;
00185 }
00186
00187 version_flag = bytestream_get_le32(&buf);
00188 if ((version_flag & 0x200) == 0x200) {
00189 av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
00190 return -1;
00191 }
00192
00193
00194 while (buf < buf_end && buf[0]) {
00195 unsigned int variable_buffer_data_size;
00196
00197 if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) {
00198 const uint8_t *channel_list_end;
00199 if (!variable_buffer_data_size)
00200 return -1;
00201
00202 channel_list_end = buf + variable_buffer_data_size;
00203 while (channel_list_end - buf >= 19) {
00204 int current_bits_per_color_id = -1;
00205 int channel_index = -1;
00206
00207 if (!strcmp(buf, "R"))
00208 channel_index = 0;
00209 if (!strcmp(buf, "G"))
00210 channel_index = 1;
00211 if (!strcmp(buf, "B"))
00212 channel_index = 2;
00213 if (!strcmp(buf, "A"))
00214 channel_index = 3;
00215
00216 while (bytestream_get_byte(&buf) && buf < channel_list_end)
00217 continue;
00218
00219 if (channel_list_end - * &buf < 4) {
00220 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00221 return -1;
00222 }
00223
00224 current_bits_per_color_id = bytestream_get_le32(&buf);
00225 if (current_bits_per_color_id > 2) {
00226 av_log(avctx, AV_LOG_ERROR, "Unknown color format\n");
00227 return -1;
00228 }
00229
00230 if (channel_index >= 0) {
00231 if (s->bits_per_color_id != -1 && s->bits_per_color_id != current_bits_per_color_id) {
00232 av_log(avctx, AV_LOG_ERROR, "RGB channels not of the same depth\n");
00233 return -1;
00234 }
00235 s->bits_per_color_id = current_bits_per_color_id;
00236 s->channel_offsets[channel_index] = current_channel_offset;
00237 }
00238
00239 current_channel_offset += 1 << current_bits_per_color_id;
00240 buf += 12;
00241 }
00242
00243
00244
00245
00246 if (FFMIN3(s->channel_offsets[0],
00247 s->channel_offsets[1],
00248 s->channel_offsets[2]) < 0) {
00249 if (s->channel_offsets[0] < 0)
00250 av_log(avctx, AV_LOG_ERROR, "Missing red channel\n");
00251 if (s->channel_offsets[1] < 0)
00252 av_log(avctx, AV_LOG_ERROR, "Missing green channel\n");
00253 if (s->channel_offsets[2] < 0)
00254 av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n");
00255 return -1;
00256 }
00257
00258 buf = channel_list_end;
00259 continue;
00260 }
00261
00262
00263 if (check_header_variable(avctx, &buf, buf_end, "dataWindow", "box2i", 31, &variable_buffer_data_size) >= 0) {
00264 if (!variable_buffer_data_size)
00265 return -1;
00266
00267 xmin = AV_RL32(buf);
00268 ymin = AV_RL32(buf + 4);
00269 xmax = AV_RL32(buf + 8);
00270 ymax = AV_RL32(buf + 12);
00271 xdelta = (xmax-xmin) + 1;
00272
00273 buf += variable_buffer_data_size;
00274 continue;
00275 }
00276
00277
00278 if (check_header_variable(avctx, &buf, buf_end, "displayWindow", "box2i", 34, &variable_buffer_data_size) >= 0) {
00279 if (!variable_buffer_data_size)
00280 return -1;
00281
00282 w = AV_RL32(buf + 8) + 1;
00283 h = AV_RL32(buf + 12) + 1;
00284
00285 buf += variable_buffer_data_size;
00286 continue;
00287 }
00288
00289
00290 if (check_header_variable(avctx, &buf, buf_end, "lineOrder", "lineOrder", 25, &variable_buffer_data_size) >= 0) {
00291 if (!variable_buffer_data_size)
00292 return -1;
00293
00294 if (*buf) {
00295 av_log(avctx, AV_LOG_ERROR, "Doesn't support this line order : %d\n", *buf);
00296 return -1;
00297 }
00298
00299 buf += variable_buffer_data_size;
00300 continue;
00301 }
00302
00303
00304 if (check_header_variable(avctx, &buf, buf_end, "compression", "compression", 29, &variable_buffer_data_size) >= 0) {
00305 if (!variable_buffer_data_size)
00306 return -1;
00307
00308 s->compr = *buf;
00309 switch (s->compr) {
00310 case EXR_RAW:
00311 break;
00312 case EXR_RLE:
00313 case EXR_ZIP1:
00314 case EXR_ZIP16:
00315 case EXR_PIZ:
00316 case EXR_B44:
00317 default:
00318 av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
00319 return -1;
00320 }
00321
00322 buf += variable_buffer_data_size;
00323 continue;
00324 }
00325
00326
00327 if (buf_end - buf <= 9) {
00328 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00329 return -1;
00330 }
00331
00332
00333 for (i = 0; i < 2; i++) {
00334
00335 while (++buf < buf_end)
00336 if (buf[0] == 0x0)
00337 break;
00338 }
00339 buf++;
00340
00341 if (buf_end - buf >= 5) {
00342 variable_buffer_data_size = get_header_variable_length(&buf, buf_end);
00343 if (!variable_buffer_data_size) {
00344 av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
00345 return -1;
00346 }
00347 buf += variable_buffer_data_size;
00348 }
00349 }
00350
00351 if (buf >= buf_end) {
00352 av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n");
00353 return -1;
00354 }
00355 buf++;
00356
00357 switch (s->bits_per_color_id) {
00358 case 2:
00359 case 1:
00360 if (s->channel_offsets[3] >= 0)
00361 avctx->pix_fmt = PIX_FMT_RGBA64;
00362 else
00363 avctx->pix_fmt = PIX_FMT_RGB48;
00364 break;
00365
00366 case 0:
00367 av_log_missing_feature(avctx, "8-bit OpenEXR", 1);
00368 return -1;
00369 default:
00370 av_log(avctx, AV_LOG_ERROR, "Unknown color format : %d\n", s->bits_per_color_id);
00371 return -1;
00372 }
00373
00374 if (s->picture.data[0])
00375 avctx->release_buffer(avctx, &s->picture);
00376 if (av_image_check_size(w, h, 0, avctx))
00377 return -1;
00378
00379
00380 if (xmin > xmax || ymin > ymax || xdelta != xmax - xmin + 1 || xmax >= w || ymax >= h) {
00381 av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
00382 return -1;
00383 }
00384
00385 if (w != avctx->width || h != avctx->height) {
00386 avcodec_set_dimensions(avctx, w, h);
00387 }
00388
00389 if (avctx->get_buffer(avctx, p) < 0) {
00390 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00391 return -1;
00392 }
00393
00394 ptr = p->data[0];
00395 stride = p->linesize[0];
00396
00397
00398 for (y = 0; y < ymin; y++) {
00399 memset(ptr, 0, avctx->width * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components);
00400 ptr += stride;
00401 }
00402
00403
00404 for (y = ymin; y <= ymax; y++) {
00405 uint16_t *ptr_x = (uint16_t *)ptr;
00406 if (buf_end - buf > 8) {
00407
00408
00409 const uint64_t line_offset = bytestream_get_le64(&buf) + 8;
00410
00411 if (line_offset > avpkt->size - xdelta * current_channel_offset) {
00412
00413 av_log(avctx, AV_LOG_WARNING, "Line offset for line %d is out of reach setting it to black\n", y);
00414 memset(ptr_x, 0, avctx->width * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components);
00415 } else {
00416 const uint8_t *red_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[0];
00417 const uint8_t *green_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[1];
00418 const uint8_t *blue_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[2];
00419 const uint8_t *alpha_channel_buffer = 0;
00420
00421 if (s->channel_offsets[3] >= 0)
00422 alpha_channel_buffer = avpkt->data + line_offset + xdelta * s->channel_offsets[3];
00423
00424
00425 memset(ptr_x, 0, xmin * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components);
00426 ptr_x += xmin * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00427 if (s->bits_per_color_id == 2) {
00428
00429 for (x = 0; x < xdelta; x++) {
00430 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&red_channel_buffer));
00431 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&green_channel_buffer));
00432 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&blue_channel_buffer));
00433 if (alpha_channel_buffer)
00434 *ptr_x++ = exr_flt2uint(bytestream_get_le32(&alpha_channel_buffer));
00435 }
00436 } else {
00437
00438 for (x = 0; x < xdelta; x++) {
00439 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&red_channel_buffer));
00440 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&green_channel_buffer));
00441 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&blue_channel_buffer));
00442 if (alpha_channel_buffer)
00443 *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&alpha_channel_buffer));
00444 }
00445 }
00446
00447
00448 memset(ptr_x, 0, (avctx->width - (xmax + 1)) * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components);
00449 ptr_x += (avctx->width - (xmax + 1)) * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components;
00450
00451 }
00452
00453 ptr += stride;
00454 }
00455 }
00456
00457
00458 for (y = ymax + 1; y < avctx->height; y++) {
00459 memset(ptr, 0, avctx->width * 2 * av_pix_fmt_descriptors[avctx->pix_fmt].nb_components);
00460 ptr += stride;
00461 }
00462
00463 *picture = s->picture;
00464 *data_size = sizeof(AVPicture);
00465
00466 return buf_size;
00467 }
00468
00469 static av_cold int decode_init(AVCodecContext *avctx)
00470 {
00471 EXRContext *s = avctx->priv_data;
00472 avcodec_get_frame_defaults(&s->picture);
00473 avctx->coded_frame = &s->picture;
00474 return 0;
00475 }
00476
00477 static av_cold int decode_end(AVCodecContext *avctx)
00478 {
00479 EXRContext *s = avctx->priv_data;
00480 if (s->picture.data[0])
00481 avctx->release_buffer(avctx, &s->picture);
00482
00483 return 0;
00484 }
00485
00486 AVCodec ff_exr_decoder = {
00487 .name = "exr",
00488 .type = AVMEDIA_TYPE_VIDEO,
00489 .id = CODEC_ID_EXR,
00490 .priv_data_size = sizeof(EXRContext),
00491 .init = decode_init,
00492 .close = decode_end,
00493 .decode = decode_frame,
00494 .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
00495 };