static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)

{

    SCPRContext *s = avctx->priv_data;

    GetByteContext *gb = &s->gb;

    int cx = 0, cx1 = 0, k = 0, clr = 0;

    int run, r, g, b, off, y = 0, x = 0, ret;

    const int cxshift = s->cxshift;

    unsigned lx, ly, ptype;



    reinit_tables(s);

    bytestream2_skip(gb, 2);

    init_rangecoder(&s->rc, gb);



    while (k < avctx->width + 1) {

        ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r);

        if (ret < 0)

            return ret;



        cx1 = (cx << 6) & 0xFC0;

        cx = r >> cxshift;

        ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g);

        if (ret < 0)

            return ret;



        cx1 = (cx << 6) & 0xFC0;

        cx = g >> cxshift;

        ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b);

        if (ret < 0)

            return ret;



        cx1 = (cx << 6) & 0xFC0;

        cx = b >> cxshift;



        ret = decode_value(s, s->run_model[0], 256, 400, &run);

        if (ret < 0)

            return ret;



        clr = (b << 16) + (g << 8) + r;

        k += run;

        while (run-- > 0) {

            dst[y * linesize + x] = clr;

            lx = x;

            ly = y;

            x++;

            if (x >= avctx->width) {

                x = 0;

                y++;

            }

        }

    }

    off = -linesize - 1;

    ptype = 0;



    while (x < avctx->width && y < avctx->height) {

        ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype);

        if (ret < 0)

            return ret;

        if (ptype == 0) {

            ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r);

            if (ret < 0)

                return ret;



            cx1 = (cx << 6) & 0xFC0;

            cx = r >> cxshift;

            ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g);

            if (ret < 0)

                return ret;



            cx1 = (cx << 6) & 0xFC0;

            cx = g >> cxshift;

            ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b);

            if (ret < 0)

                return ret;



            cx1 = (cx << 6) & 0xFC0;

            cx = b >> cxshift;

            clr = (b << 16) + (g << 8) + r;

        }

        if (ptype > 5)

            return AVERROR_INVALIDDATA;

        ret = decode_value(s, s->run_model[ptype], 256, 400, &run);

        if (ret < 0)

            return ret;



        switch (ptype) {

        case 0:

            while (run-- > 0) {

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        case 1:

            while (run-- > 0) {

                dst[y * linesize + x] = dst[ly * linesize + lx];

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            clr = dst[ly * linesize + lx];

            break;

        case 2:

            while (run-- > 0) {

                clr = dst[y * linesize + x + off + 1];

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        case 4:

            while (run-- > 0) {

                uint8_t *odst = (uint8_t *)dst;

                r = odst[(ly * linesize + lx) * 4] +

                    odst[((y * linesize + x) + off) * 4 + 4] -

                    odst[((y * linesize + x) + off) * 4];

                g = odst[(ly * linesize + lx) * 4 + 1] +

                    odst[((y * linesize + x) + off) * 4 + 5] -

                    odst[((y * linesize + x) + off) * 4 + 1];

                b = odst[(ly * linesize + lx) * 4 + 2] +

                    odst[((y * linesize + x) + off) * 4 + 6] -

                    odst[((y * linesize + x) + off) * 4 + 2];

                clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        case 5:

            while (run-- > 0) {

                clr = dst[y * linesize + x + off];

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        }



        if (avctx->bits_per_coded_sample == 16) {

            cx1 = (clr & 0xFF00) >> 2;

            cx = (clr & 0xFFFFFF) >> 16;

        } else {

            cx1 = (clr & 0xFC00) >> 4;

            cx = (clr & 0xFFFFFF) >> 18;

        }

    }



    return 0;

}
