[FFmpeg-devel] [PATCH] libavcodec/exr.c : exr lossy compression B44 added

Michael Niedermayer michaelni at gmx.at
Thu Apr 23 21:07:43 CEST 2015


On Thu, Apr 23, 2015 at 09:29:31PM +0530, greeshma wrote:
> for patch PFA
> 
> Greeshma

>  exr.c |  114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 114 insertions(+)
> 57f8f5e474a82ddfce30f7356cb83fed4186d137  0001-exr-lossy-compression-B44-added.patch
> From c10e182e56310cfc5ebd6c6f8801128668042a2a Mon Sep 17 00:00:00 2001
> From: greeshmab <greeshmabalabadra at gmail.com>
> Date: Mon, 20 Apr 2015 23:33:55 +0530
> Subject: [PATCH] exr lossy compression B44 added

FFmpeg_Logo_B44_HalfRGBA.exr does not decode correctly


> 
> ---
>  libavcodec/exr.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 114 insertions(+)
> 
> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
> index f9525ec..92ecc9b 100644
> --- a/libavcodec/exr.c
> +++ b/libavcodec/exr.c
> @@ -770,6 +770,115 @@ static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize,
>      return 0;
>  }
>  
> +static void B44_unpack14 ( GetByteContext *gb, uint16_t out[16]){
> +    uint16_t shift;
> +    const uint8_t *r = gb->buffer;

theers no need to pass a GetByteContext if only a uint8_t * is used


> +    av_assert0(r[2] != 0xfc);


> +    out[0] = (r[0] << 8) | r[1];
> +    shift = (r[2] >> 2);
> +    out[ 1] = out[ 0] + ((r[ 5] >> 2) << shift);
> +    out[ 2] = out[ 1] + ((r[ 8] >> 2) << shift);
> +    out[ 3] = out[ 2] + ((r[11] >> 2) << shift);
> +    out[ 4] = out[ 0] + (((r[ 2] << 4) | (r[ 3] >> 4)) << shift);
> +    out[ 5] = out[ 4] + (((r[ 5] << 4) | (r[ 6] >> 4)) << shift);
> +    out[ 6] = out[ 5] + (((r[ 8] << 4) | (r[ 9] >> 4)) << shift);
> +    out[ 7] = out[ 6] + (((r[11] << 4) | (r[12] >> 4)) << shift);
> +    out[ 8] = out[ 4] + (((r[ 3] << 2) | (r[ 4] >> 6)) << shift);
> +    out[ 9] = out[ 8] + (((r[ 6] << 2) | (r[ 7] >> 6)) << shift);
> +    out[10] = out[ 9] + (((r[ 9] << 2) | (r[10] >> 6)) << shift);
> +    out[11] = out[10] + (((r[12] << 2) | (r[13] >> 6)) << shift);
> +    out[12] = out[ 8] + (r[ 4]  << shift);
> +    out[13] = out[12] + (r[ 7]  << shift);
> +    out[14] = out[13] + (r[10]  << shift);
> +    out[15] = out[14] + (r[13]  << shift);
> +    for (int i = 0; i < 16; ++i) {              //if any out value exceeds 16bits 
> +        if (out[i] & 0x8000)
> +            out[i] &= 0x7fff;
> +        else
> +            out[i] = ~out[i];
> +    }
> +}
> +
> +static void B44_unpack3 ( GetByteContext *gb, uint16_t out[16]){
> +    const uint8_t *r = gb->buffer;                                       //pixels have the same value
> +    av_assert0(r[2] == 0xfc);
> +    out[0] = (r[0] << 8) | r[1];
> +    if (out[0] & 0x8000)
> +        out[0] &= 0x7fff;
> +    else
> +        out[0] = ~out[0];
> +    for (int i = 1; i < 16; ++i)
> +        out[i] = out[0];
> +}
> +
> +static int b44_uncompress(EXRContext *s, const uint8_t *src,int ssize, int dsize, EXRThreadData *td){
> +    GetByteContext gb;
> +    unsigned long  dest_len = dsize;
> +    uint8_t *out;
> +    int i, j;
> +    uint16_t *tmp = (uint16_t *)td->tmp;

> +    out = td->uncompressed_data;

> +    bytestream2_init(&gb, src, ssize);
> +    if (uncompress(td->tmp, &dest_len, src, ssize) != Z_OK || dest_len != dsize)
> +        return AVERROR_INVALIDDATA;

this initialized both a bytereader as well as decomressing from
the same source
later the output from uncompress is overwritten without being used


> +    for (i = 0; i < s->nb_channels; i++) {
> +        EXRChannel *channel = &s->channels[i];
> +        int size = channel->pixel_type;
> +        int inSize = ssize;
> +        if (channel->pixel_type != EXR_HALF) {              // UINT or FLOAT channel.
> +            int n = s->xdelta * s->ydelta * size * sizeof (*tmp);
> +            memcpy (tmp, gb.buffer, n);
> +            gb.buffer += n;
> +            inSize -= n;
> +            continue;
> +        } else {                                            //EXR_HALF Channel
> +            for (int y=0; y < s->ydelta; y +=4 ) {
> +                uint16_t *row0 = tmp + y * s->xdelta;
> +                uint16_t *row1 = row0 + s->xdelta;
> +                uint16_t *row2 = row1 + s->xdelta;
> +                uint16_t *row3 = row2 + s->xdelta;
> +                for (int x = 0; x < s->xdelta; x += 4) {
> +                    uint16_t out[16];
> +                    int num = (x + 3 < s->xdelta)? 4 * sizeof (*out) : (s->xdelta - x) * sizeof (*out); 
> +                    if (gb.buffer[2] == 0xfc) {
> +                        B44_unpack3 (&gb, out);
> +                        gb.buffer += 3;
> +                        inSize -= 3;
> +                    } else {
> +                        B44_unpack14 (&gb, out);
> +                        gb.buffer += 14;
> +                        inSize -= 14;
> +                    }
> +                    if (y + 3 < s->ydelta) {
> +                        memcpy (row0, &out[ 0], num);
> +                        memcpy (row1, &out[ 4], num);
> +                        memcpy (row2, &out[ 8], num);
> +                        memcpy (row3, &out[12], num);
> +                    } else {
> +                        memcpy (row0, &out[ 0], num);
> +                        if (y + 1 < s->ydelta)
> +                            memcpy (row1, &out[ 4], num);
> +                        if (y + 2 < s->ydelta)
> +                            memcpy (row2, &out[ 8], num);
> +                    }
> +                    row0 += 4;
> +                    row1 += 4;
> +                    row2 += 4;
> +                    row3 += 4;
> +                }
> +            }

missing checks on the input buffer size

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

When the tyrant has disposed of foreign enemies by conquest or treaty, and
there is nothing more to fear from them, then he is always stirring up
some war or other, in order that the people may require a leader. -- Plato
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150423/90f19807/attachment.asc>


More information about the ffmpeg-devel mailing list