Hello, In attach a patch to add support for UINT32 pixel type.
Sample of UINT 32 file (scanline only in that case) can be found here : https://we.tl/sFB0NYlQVW For colorprocessing, UINT32, are converted to float, and follow a similar way for color process than float. I not enable in this patch PXR24 in UINT32, who need modification inside pxr24_uncompress. Comments welcome Martin Jokyo Images
From eb04d989eb53f81c225fb7ea6debf04a33fbb9c6 Mon Sep 17 00:00:00 2001 From: Martin Vignali <martin.vign...@gmail.com> Date: Sun, 3 Apr 2016 18:55:36 +0200 Subject: [PATCH] libavcodec/exr : add support for uint32. --- libavcodec/exr.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index b0573d5..45eb24a 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -154,6 +154,10 @@ typedef struct EXRContext { #define HALF_FLOAT_MAX_BIASED_EXP (0x1F << 10) +#ifndef UINT32_MAX + #define UINT32_MAX (0xffffffff) +#endif + /** * Convert a half float as a uint16_t into a full float. * @@ -1052,13 +1056,13 @@ static int decode_block(AVCodecContext *avctx, void *tdata, return AVERROR_INVALIDDATA; } } - + if (data_size < uncompressed_size || s->is_tile) { /* td->tmp is use for tile reorganization */ av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size); if (!td->tmp) return AVERROR(ENOMEM); } - + if (data_size < uncompressed_size) { av_fast_padded_malloc(&td->uncompressed_data, &td->uncompressed_size, uncompressed_size); @@ -1092,11 +1096,11 @@ static int decode_block(AVCodecContext *avctx, void *tdata, } src = td->uncompressed_data; } - + if (s->is_tile) { indexSrc = 0; channelLineSize = s->xsize * 2; - if (s->pixel_type == EXR_FLOAT) + if ((s->pixel_type == EXR_FLOAT)||(s->pixel_type == EXR_UINT)) channelLineSize *= 2; /* reorganise tile data to have each channel one after the other instead of line by line */ @@ -1126,7 +1130,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, for (i = 0; i < s->ysize; i++, ptr += p->linesize[0]) { - + const uint8_t *r, *g, *b, *a; r = channel_buffer[0]; @@ -1181,7 +1185,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata, *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a)); } } - } else { + } else if (s->pixel_type == EXR_HALF) { // 16-bit for (x = 0; x < s->xsize; x++) { *ptr_x++ = s->gamma_table[bytestream_get_le16(&r)]; @@ -1190,6 +1194,44 @@ static int decode_block(AVCodecContext *avctx, void *tdata, if (channel_buffer[3]) *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a)); } + } else { + //UINT 32 + if (trc_func) { + for (x = 0; x < s->xsize; x++) { + union av_intfloat32 t; + t.f = trc_func((float)bytestream_get_le32(&r) / (float)UINT32_MAX); + *ptr_x++ = exr_flt2uint(t.i); + + t.f = trc_func((float)bytestream_get_le32(&g) / (float)UINT32_MAX); + *ptr_x++ = exr_flt2uint(t.i); + + t.f = trc_func((float)bytestream_get_le32(&b) / (float)UINT32_MAX); + *ptr_x++ = exr_flt2uint(t.i); + if (channel_buffer[3]){ + t.f = trc_func((float)bytestream_get_le32(&a) / (float)UINT32_MAX); + *ptr_x++ = exr_flt2uint(t.i); + } + } + } else { + for (x = 0; x < s->xsize; x++) { + union av_intfloat32 t; + t.f = (float)bytestream_get_le32(&r) / (float)UINT32_MAX; + t.f = powf(t.f, one_gamma); + *ptr_x++ = exr_flt2uint(t.i); + + t.f = (float)bytestream_get_le32(&g) / (float)UINT32_MAX; + t.f = powf(t.f, one_gamma); + *ptr_x++ = exr_flt2uint(t.i); + + t.f = (float)bytestream_get_le32(&b) / (float)UINT32_MAX; + t.f = powf(t.f, one_gamma); + *ptr_x++ = exr_flt2uint(t.i); + if (channel_buffer[3]){ + t.f = (float)bytestream_get_le32(&a) / (float)UINT32_MAX; + *ptr_x++ = exr_flt2uint(t.i); + } + } + } } // Zero out the end if xmax+1 is not w @@ -1210,7 +1252,6 @@ static int decode_block(AVCodecContext *avctx, void *tdata, channel_buffer[3] += s->scan_line_size; } } - return 0; } @@ -1400,8 +1441,13 @@ static int decode_header(EXRContext *s) channel->pixel_type = current_pixel_type; channel->xsub = xsub; channel->ysub = ysub; - - s->current_channel_offset += 1 << current_pixel_type; + + if (current_pixel_type == EXR_HALF){ + s->current_channel_offset += 2; + } + else{/* Float or UINT32 */ + s->current_channel_offset += 4; + } } /* Check if all channels are set with an offset or if the channels @@ -1526,6 +1572,11 @@ static int decode_header(EXRContext *s) av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n"); return AVERROR_INVALIDDATA; } + + if ((s->pixel_type == EXR_UINT)&&(s->compression == EXR_PXR24)) { + avpriv_report_missing_feature(s->avctx, "Pxr24 in UINT32"); + return AVERROR_INVALIDDATA; + } if (s->is_tile) { if (s->tile_attr.xSize < 1 || s->tile_attr.ySize < 1) { @@ -1571,14 +1622,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, switch (s->pixel_type) { case EXR_FLOAT: case EXR_HALF: + case EXR_UINT: if (s->channel_offsets[3] >= 0) avctx->pix_fmt = AV_PIX_FMT_RGBA64; else avctx->pix_fmt = AV_PIX_FMT_RGB48; break; - case EXR_UINT: - avpriv_request_sample(avctx, "32-bit unsigned int"); - return AVERROR_PATCHWELCOME; default: av_log(avctx, AV_LOG_ERROR, "Missing channel list.\n"); return AVERROR_INVALIDDATA; -- 1.9.3 (Apple Git-50)
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel