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

greeshma greeshmabalabadra at gmail.com
Sun Apr 26 07:41:58 CEST 2015


Updated Patch

Greeshma


On Fri, Apr 24, 2015 at 12:37 AM, Michael Niedermayer <michaelni at gmx.at>
wrote:

> 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
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-B44-compression-techinique-added.patch
Type: text/x-patch
Size: 6714 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150426/d0b6f88d/attachment.bin>


More information about the ffmpeg-devel mailing list