[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