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

Reply via email to