static int decode_555(GetByteContext *gB, uint16_t *dst, int stride,

                      int keyframe, int w, int h)

{

    int last_symbol = 0, repeat = 0, prev_avail = 0;



    if (!keyframe) {

        int x, y, endx, endy, t;



#define READ_PAIR(a, b)                 \

    a  = bytestream2_get_byte(gB) << 4; \

    t  = bytestream2_get_byte(gB);      \

    a |= t >> 4;                        \

    b  = (t & 0xF) << 8;                \

    b |= bytestream2_get_byte(gB);      \



        READ_PAIR(x, endx)

        READ_PAIR(y, endy)



        if (endx >= w || endy >= h || x > endx || y > endy)

            return AVERROR_INVALIDDATA;

        dst += x + stride * y;

        w    = endx - x + 1;

        h    = endy - y + 1;

        if (y)

            prev_avail = 1;

    }



    do {

        uint16_t *p = dst;

        do {

            if (repeat-- < 1) {

                int b = bytestream2_get_byte(gB);

                if (b < 128)

                    last_symbol = b << 8 | bytestream2_get_byte(gB);

                else if (b > 129) {

                    repeat = 0;

                    while (b-- > 130)

                        repeat = (repeat << 8) + bytestream2_get_byte(gB) + 1;

                    if (last_symbol == -2) {

                        int skip = FFMIN((unsigned)repeat, dst + w - p);

                        repeat -= skip;

                        p      += skip;

                    }

                } else

                    last_symbol = 127 - b;

            }

            if (last_symbol >= 0)

                *p = last_symbol;

            else if (last_symbol == -1 && prev_avail)

                *p = *(p - stride);

        } while (++p < dst + w);

        dst       += stride;

        prev_avail = 1;

    } while (--h);



    return 0;

}
