2016-04-03 19:31 GMT+02:00 wm4 <nfx...@googlemail.com>:

> On Sun, 3 Apr 2016 19:19:25 +0200
> Paul B Mahol <one...@gmail.com> wrote:
>
> > On 4/3/16, Martin Vignali <martin.vign...@gmail.com> wrote:
> > > 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
> >
> > So UINT_32 is processed as it was FLOAT, that is strange.
>
> And then the float data is converted back to integer for output? That's
> very funny.
>
>
New patch attach, without the UINT32_MAX define and clean empty line

For color processing :
The actual exr decoder of ffmpeg, make color conversion inside the decoding
process in float (trc_func, seems to expect to have a float, and one_gamma
is also a float)
After the color conversion, data are converted to uint16.

uint32 is convert to float (but map in the range 0., 1.0). Some software
decode UINT32 Exr as float without conversion (so the picture is most of
the time white and more). But i doesn't think this way is very convenient
(specially if the rest of the process is not in float)

Seems you're both not agree. What solution you recommend ?

Martin
Jokyo Images
From 62a3500ff874db4c7da69ec235dfe9901cd49c3c Mon Sep 17 00:00:00 2001
From: Martin Vignali <martin.vign...@gmail.com>
Date: Sun, 3 Apr 2016 20:32:54 +0200
Subject: [PATCH] libavcodec/exr : add support for uint32

---
 libavcodec/exr.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 6 deletions(-)

diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index b0573d5..3e65a91 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1096,7 +1096,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
     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 */
@@ -1181,7 +1181,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 +1190,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
@@ -1401,7 +1439,12 @@ static int decode_header(EXRContext *s)
                 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 +1569,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 +1619,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