[FFmpeg-devel] [PATCH] Add a gamma flag to exr loader to avoid banding

Gonzalo Garramuno ggarra13 at gmail.com
Sun Apr 27 18:28:15 CEST 2014


On 27/04/14 13:12, Michael Niedermayer wrote:
> On Sun, Apr 27, 2014 at 06:04:33PM +0200, Michael Niedermayer wrote:
>> On Sun, Apr 27, 2014 at 10:43:09AM -0300, Gonzalo Garramuno wrote:
>>> Attached is a patch to add a gamma flag to the exr loader.  This is
>>> needed to avoid banding artifacts when gammaing the picture.
>>> Currently, if done with a video filter, the process is done on uints
>>> instead of full float.
>>>   Changelog        |    1
>>>   libavcodec/exr.c |  138 ++++++++++++++++++++++++++++++++++++++++++++++---------
>>>   2 files changed, 117 insertions(+), 22 deletions(-)
>>> 828c54dedd21b004de00e049b4fa4b2f72ae78b1  exr_gamma.patch
>>> diff --git a/Changelog b/Changelog
>>> index daaa1ea..a726823 100644
>>> --- a/Changelog
>>> +++ b/Changelog
>>> @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest within each release,
>>>   releases are sorted from youngest to oldest.
>>>   
>>>   version <next>:
>>> +- EXR loader supports a gamma flag
>>>   - AC3 fixed-point decoding
>>>   - shuffleplanes filter
>>>   - subfile protocol
>>> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
>>> index 084025a..8c2425c 100644
>>> --- a/libavcodec/exr.c
>>> +++ b/libavcodec/exr.c
>>> @@ -31,6 +31,7 @@
>>>    */
>>>   
>>>   #include <zlib.h>
>>> +#include <float.h>
>>>   
>>>   #include "libavutil/imgutils.h"
>>>   #include "libavutil/opt.h"
>>> @@ -106,8 +107,30 @@ typedef struct EXRContext {
>>>       EXRThreadData *thread_data;
>>>   
>>>       const char *layer;
>>> +
>>> +    float gamma;
>>> +
>>>   } EXRContext;
>>>   
>>> +union FP32 {
>>> +    uint32_t u;
>>> +    float f;
>>> +    struct {
>>> +        unsigned int Mantissa : 23;
>>> +        unsigned int Exponent : 8;
>>> +        unsigned int Sign : 1;
>>> +    };
>>> +} FP32;
>>> +
>>> +union FP16 {
>>> +    uint16_t u;
>>> +    struct {
>>> +        unsigned int Mantissa : 10;
>>> +        unsigned int Exponent : 5;
>>> +        unsigned int Sign : 1;
>>> +     };
>>> +} FP16;
>> that way to access parts of a float is not portable
>>
>> see libavutil/intfloat.h

In what way is not portable?  The bits in the struct?

> or for 16bit floats you could simply use a LUT
>
>
> [...]
>
>

I am following the blog at:

http://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/

In there, there are several ways to convert a half to a float.  The 
smallest one is the following (and does not rely on bits):

staticFP32half_to_float_fast5(FP16h)
{
staticconstFP32magic={(254-15)<<23};
staticconstFP32was_infnan={(127+16)<<23};
FP32o;
o.u=(h.u&0x7fff)<<13;// exponent/mantissa bits
o.f*=magic.f;// exponent adjust
if(o.f>=was_infnan.f)// make sure Inf/NaN survive
o.u|=255<<23;
o.u|=(h.u&0x8000)<<16;// sign bit
returno;
}

Would that be acceptable?



More information about the ffmpeg-devel mailing list