static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,

                             AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    MSS2Context *ctx = avctx->priv_data;

    MSS12Context *c  = &ctx->c;

    AVFrame *frame   = data;

    GetBitContext gb;

    GetByteContext gB;

    ArithCoder acoder;



    int keyframe, has_wmv9, has_mv, is_rle, is_555, ret;



    Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r;

    int used_rects = 0, i, implicit_rect = 0, av_uninit(wmv9_mask);



    if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)

        return ret;



    if (keyframe = get_bits1(&gb))

        skip_bits(&gb, 7);

    has_wmv9 = get_bits1(&gb);

    has_mv   = keyframe ? 0 : get_bits1(&gb);

    is_rle   = get_bits1(&gb);

    is_555   = is_rle && get_bits1(&gb);

    if (c->slice_split > 0)

        ctx->split_position = c->slice_split;

    else if (c->slice_split < 0) {

        if (get_bits1(&gb)) {

            if (get_bits1(&gb)) {

                if (get_bits1(&gb))

                    ctx->split_position = get_bits(&gb, 16);

                else

                    ctx->split_position = get_bits(&gb, 12);

            } else

                ctx->split_position = get_bits(&gb, 8) << 4;

        } else {

            if (keyframe)

                ctx->split_position = avctx->height / 2;

        }

    } else

        ctx->split_position = avctx->height;



    if (c->slice_split && (ctx->split_position < 1 - is_555 ||

                           ctx->split_position > avctx->height - 1))

        return AVERROR_INVALIDDATA;



    align_get_bits(&gb);

    buf      += get_bits_count(&gb) >> 3;

    buf_size -= get_bits_count(&gb) >> 3;



    if (buf_size < 1)

        return AVERROR_INVALIDDATA;



    if (is_555 && (has_wmv9 || has_mv || c->slice_split && ctx->split_position))

        return AVERROR_INVALIDDATA;



    avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;

    if (ctx->last_pic->format != avctx->pix_fmt)

        av_frame_unref(ctx->last_pic);



    if (has_wmv9) {

        bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);

        arith2_init(&acoder, &gB);



        implicit_rect = !arith2_get_bit(&acoder);



        while (arith2_get_bit(&acoder)) {

            if (used_rects == MAX_WMV9_RECTANGLES)

                return AVERROR_INVALIDDATA;

            r = &wmv9rects[used_rects];

            if (!used_rects)

                r->x = arith2_get_number(&acoder, avctx->width);

            else

                r->x = arith2_get_number(&acoder, avctx->width -

                                         wmv9rects[used_rects - 1].x) +

                       wmv9rects[used_rects - 1].x;

            r->y = arith2_get_number(&acoder, avctx->height);

            r->w = arith2_get_number(&acoder, avctx->width  - r->x) + 1;

            r->h = arith2_get_number(&acoder, avctx->height - r->y) + 1;

            used_rects++;

        }



        if (implicit_rect && used_rects) {

            av_log(avctx, AV_LOG_ERROR, "implicit_rect && used_rects > 0\n");

            return AVERROR_INVALIDDATA;

        }



        if (implicit_rect) {

            wmv9rects[0].x = 0;

            wmv9rects[0].y = 0;

            wmv9rects[0].w = avctx->width;

            wmv9rects[0].h = avctx->height;



            used_rects = 1;

        }

        for (i = 0; i < used_rects; i++) {

            if (!implicit_rect && arith2_get_bit(&acoder)) {

                av_log(avctx, AV_LOG_ERROR, "Unexpected grandchildren\n");

                return AVERROR_INVALIDDATA;

            }

            if (!i) {

                wmv9_mask = arith2_get_bit(&acoder) - 1;

                if (!wmv9_mask)

                    wmv9_mask = arith2_get_number(&acoder, 256);

            }

            wmv9rects[i].coded = arith2_get_number(&acoder, 2);

        }



        buf      += arith2_get_consumed_bytes(&acoder);

        buf_size -= arith2_get_consumed_bytes(&acoder);

        if (buf_size < 1)

            return AVERROR_INVALIDDATA;

    }



    c->mvX = c->mvY = 0;

    if (keyframe && !is_555) {

        if ((i = decode_pal_v2(c, buf, buf_size)) < 0)

            return AVERROR_INVALIDDATA;

        buf      += i;

        buf_size -= i;

    } else if (has_mv) {

        buf      += 4;

        buf_size -= 4;

        if (buf_size < 1)

            return AVERROR_INVALIDDATA;

        c->mvX = AV_RB16(buf - 4) - avctx->width;

        c->mvY = AV_RB16(buf - 2) - avctx->height;

    }



    if (c->mvX < 0 || c->mvY < 0) {

        FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic);



        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)

            return ret;



        if (ctx->last_pic->data[0]) {

            av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]);

            c->last_rgb_pic = ctx->last_pic->data[0] +

                              ctx->last_pic->linesize[0] * (avctx->height - 1);

        } else {

            av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n");

            return AVERROR_INVALIDDATA;

        }

    } else {

        if ((ret = ff_reget_buffer(avctx, ctx->last_pic)) < 0)

            return ret;

        if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0)

            return ret;



        c->last_rgb_pic = NULL;

    }

    c->rgb_pic    = frame->data[0] +

                    frame->linesize[0] * (avctx->height - 1);

    c->rgb_stride = -frame->linesize[0];



    frame->key_frame = keyframe;

    frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;



    if (is_555) {

        bytestream2_init(&gB, buf, buf_size);



        if (decode_555(&gB, (uint16_t *)c->rgb_pic, c->rgb_stride >> 1,

                       keyframe, avctx->width, avctx->height))

            return AVERROR_INVALIDDATA;



        buf_size -= bytestream2_tell(&gB);

    } else {

        if (keyframe) {

            c->corrupted = 0;

            ff_mss12_slicecontext_reset(&ctx->sc[0]);

            if (c->slice_split)

                ff_mss12_slicecontext_reset(&ctx->sc[1]);

        }

        if (is_rle) {

            if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)

                return ret;

            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,

                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,

                                 ctx->split_position, 0,

                                 avctx->width, avctx->height))

                return ret;

            align_get_bits(&gb);



            if (c->slice_split)

                if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,

                                     c->rgb_pic, c->rgb_stride, c->pal, keyframe,

                                     ctx->split_position, 1,

                                     avctx->width, avctx->height))

                    return ret;



            align_get_bits(&gb);

            buf      += get_bits_count(&gb) >> 3;

            buf_size -= get_bits_count(&gb) >> 3;

        } else if (!implicit_rect || wmv9_mask != -1) {

            if (c->corrupted)

                return AVERROR_INVALIDDATA;

            bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);

            arith2_init(&acoder, &gB);

            c->keyframe = keyframe;

            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,

                                                    avctx->width,

                                                    ctx->split_position))

                return AVERROR_INVALIDDATA;



            buf      += arith2_get_consumed_bytes(&acoder);

            buf_size -= arith2_get_consumed_bytes(&acoder);

            if (c->slice_split) {

                if (buf_size < 1)

                    return AVERROR_INVALIDDATA;

                bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);

                arith2_init(&acoder, &gB);

                if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,

                                                        ctx->split_position,

                                                        avctx->width,

                                                        avctx->height - ctx->split_position))

                    return AVERROR_INVALIDDATA;



                buf      += arith2_get_consumed_bytes(&acoder);

                buf_size -= arith2_get_consumed_bytes(&acoder);

            }

        } else

            memset(c->pal_pic, 0, c->pal_stride * avctx->height);

    }



    if (has_wmv9) {

        for (i = 0; i < used_rects; i++) {

            int x = wmv9rects[i].x;

            int y = wmv9rects[i].y;

            int w = wmv9rects[i].w;

            int h = wmv9rects[i].h;

            if (wmv9rects[i].coded) {

                int WMV9codedFrameSize;

                if (buf_size < 4 || !(WMV9codedFrameSize = AV_RL24(buf)))

                    return AVERROR_INVALIDDATA;

                if (ret = decode_wmv9(avctx, buf + 3, buf_size - 3,

                                      x, y, w, h, wmv9_mask))

                    return ret;

                buf      += WMV9codedFrameSize + 3;

                buf_size -= WMV9codedFrameSize + 3;

            } else {

                uint8_t *dst = c->rgb_pic + y * c->rgb_stride + x * 3;

                if (wmv9_mask != -1) {

                    ctx->dsp.mss2_gray_fill_masked(dst, c->rgb_stride,

                                                   wmv9_mask,

                                                   c->pal_pic + y * c->pal_stride + x,

                                                   c->pal_stride,

                                                   w, h);

                } else {

                    do {

                        memset(dst, 0x80, w * 3);

                        dst += c->rgb_stride;

                    } while (--h);

                }

            }

        }

    }



    if (buf_size)

        av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");



    if (c->mvX < 0 || c->mvY < 0) {

        av_frame_unref(ctx->last_pic);

        ret = av_frame_ref(ctx->last_pic, frame);

        if (ret < 0)

            return ret;

    }



    *got_frame       = 1;



    return avpkt->size;

}

static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,

                             AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    MSS2Context *ctx = avctx->priv_data;

    MSS12Context *c  = &ctx->c;

    AVFrame *frame   = data;

    GetBitContext gb;

    GetByteContext gB;

    ArithCoder acoder;



    int keyframe, has_wmv9, has_mv, is_rle, is_555, ret;



    Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r;

    int used_rects = 0, i, implicit_rect = 0, av_uninit(wmv9_mask);



    if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)

        return ret;



    if (keyframe = get_bits1(&gb))

        skip_bits(&gb, 7);

    has_wmv9 = get_bits1(&gb);

    has_mv   = keyframe ? 0 : get_bits1(&gb);

    is_rle   = get_bits1(&gb);

    is_555   = is_rle && get_bits1(&gb);

    if (c->slice_split > 0)

        ctx->split_position = c->slice_split;

    else if (c->slice_split < 0) {

        if (get_bits1(&gb)) {

            if (get_bits1(&gb)) {

                if (get_bits1(&gb))

                    ctx->split_position = get_bits(&gb, 16);

                else

                    ctx->split_position = get_bits(&gb, 12);

            } else

                ctx->split_position = get_bits(&gb, 8) << 4;

        } else {

            if (keyframe)

                ctx->split_position = avctx->height / 2;

        }

    } else

        ctx->split_position = avctx->height;



    if (c->slice_split && (ctx->split_position < 1 - is_555 ||

                           ctx->split_position > avctx->height - 1))

        return AVERROR_INVALIDDATA;



    align_get_bits(&gb);

    buf      += get_bits_count(&gb) >> 3;

    buf_size -= get_bits_count(&gb) >> 3;



    if (buf_size < 1)

        return AVERROR_INVALIDDATA;



    if (is_555 && (has_wmv9 || has_mv || c->slice_split && ctx->split_position))

        return AVERROR_INVALIDDATA;



    avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;

    if (ctx->last_pic->format != avctx->pix_fmt)

        av_frame_unref(ctx->last_pic);



    if (has_wmv9) {

        bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);

        arith2_init(&acoder, &gB);



        implicit_rect = !arith2_get_bit(&acoder);



        while (arith2_get_bit(&acoder)) {

            if (used_rects == MAX_WMV9_RECTANGLES)

                return AVERROR_INVALIDDATA;

            r = &wmv9rects[used_rects];

            if (!used_rects)

                r->x = arith2_get_number(&acoder, avctx->width);

            else

                r->x = arith2_get_number(&acoder, avctx->width -

                                         wmv9rects[used_rects - 1].x) +

                       wmv9rects[used_rects - 1].x;

            r->y = arith2_get_number(&acoder, avctx->height);

            r->w = arith2_get_number(&acoder, avctx->width  - r->x) + 1;

            r->h = arith2_get_number(&acoder, avctx->height - r->y) + 1;

            used_rects++;

        }



        if (implicit_rect && used_rects) {

            av_log(avctx, AV_LOG_ERROR, "implicit_rect && used_rects > 0\n");

            return AVERROR_INVALIDDATA;

        }



        if (implicit_rect) {

            wmv9rects[0].x = 0;

            wmv9rects[0].y = 0;

            wmv9rects[0].w = avctx->width;

            wmv9rects[0].h = avctx->height;



            used_rects = 1;

        }

        for (i = 0; i < used_rects; i++) {

            if (!implicit_rect && arith2_get_bit(&acoder)) {

                av_log(avctx, AV_LOG_ERROR, "Unexpected grandchildren\n");

                return AVERROR_INVALIDDATA;

            }

            if (!i) {

                wmv9_mask = arith2_get_bit(&acoder) - 1;

                if (!wmv9_mask)

                    wmv9_mask = arith2_get_number(&acoder, 256);

            }

            wmv9rects[i].coded = arith2_get_number(&acoder, 2);

        }



        buf      += arith2_get_consumed_bytes(&acoder);

        buf_size -= arith2_get_consumed_bytes(&acoder);

        if (buf_size < 1)

            return AVERROR_INVALIDDATA;

    }



    c->mvX = c->mvY = 0;

    if (keyframe && !is_555) {

        if ((i = decode_pal_v2(c, buf, buf_size)) < 0)

            return AVERROR_INVALIDDATA;

        buf      += i;

        buf_size -= i;

    } else if (has_mv) {

        buf      += 4;

        buf_size -= 4;

        if (buf_size < 1)

            return AVERROR_INVALIDDATA;

        c->mvX = AV_RB16(buf - 4) - avctx->width;

        c->mvY = AV_RB16(buf - 2) - avctx->height;

    }



    if (c->mvX < 0 || c->mvY < 0) {

        FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic);



        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)

            return ret;



        if (ctx->last_pic->data[0]) {

            av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]);

            c->last_rgb_pic = ctx->last_pic->data[0] +

                              ctx->last_pic->linesize[0] * (avctx->height - 1);

        } else {

            av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n");

            return AVERROR_INVALIDDATA;

        }

    } else {

        if ((ret = ff_reget_buffer(avctx, ctx->last_pic)) < 0)

            return ret;

        if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0)

            return ret;



        c->last_rgb_pic = NULL;

    }

    c->rgb_pic    = frame->data[0] +

                    frame->linesize[0] * (avctx->height - 1);

    c->rgb_stride = -frame->linesize[0];



    frame->key_frame = keyframe;

    frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;



    if (is_555) {

        bytestream2_init(&gB, buf, buf_size);



        if (decode_555(&gB, (uint16_t *)c->rgb_pic, c->rgb_stride >> 1,

                       keyframe, avctx->width, avctx->height))

            return AVERROR_INVALIDDATA;



        buf_size -= bytestream2_tell(&gB);

    } else {

        if (keyframe) {

            c->corrupted = 0;

            ff_mss12_slicecontext_reset(&ctx->sc[0]);

            if (c->slice_split)

                ff_mss12_slicecontext_reset(&ctx->sc[1]);

        }

        if (is_rle) {

            if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)

                return ret;

            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,

                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,

                                 ctx->split_position, 0,

                                 avctx->width, avctx->height))

                return ret;

            align_get_bits(&gb);



            if (c->slice_split)

                if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,

                                     c->rgb_pic, c->rgb_stride, c->pal, keyframe,

                                     ctx->split_position, 1,

                                     avctx->width, avctx->height))

                    return ret;



            align_get_bits(&gb);

            buf      += get_bits_count(&gb) >> 3;

            buf_size -= get_bits_count(&gb) >> 3;

        } else if (!implicit_rect || wmv9_mask != -1) {

            if (c->corrupted)

                return AVERROR_INVALIDDATA;

            bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);

            arith2_init(&acoder, &gB);

            c->keyframe = keyframe;

            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,

                                                    avctx->width,

                                                    ctx->split_position))

                return AVERROR_INVALIDDATA;



            buf      += arith2_get_consumed_bytes(&acoder);

            buf_size -= arith2_get_consumed_bytes(&acoder);

            if (c->slice_split) {

                if (buf_size < 1)

                    return AVERROR_INVALIDDATA;

                bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);

                arith2_init(&acoder, &gB);

                if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,

                                                        ctx->split_position,

                                                        avctx->width,

                                                        avctx->height - ctx->split_position))

                    return AVERROR_INVALIDDATA;



                buf      += arith2_get_consumed_bytes(&acoder);

                buf_size -= arith2_get_consumed_bytes(&acoder);

            }

        } else

            memset(c->pal_pic, 0, c->pal_stride * avctx->height);

    }



    if (has_wmv9) {

        for (i = 0; i < used_rects; i++) {

            int x = wmv9rects[i].x;

            int y = wmv9rects[i].y;

            int w = wmv9rects[i].w;

            int h = wmv9rects[i].h;

            if (wmv9rects[i].coded) {

                int WMV9codedFrameSize;

                if (buf_size < 4 || !(WMV9codedFrameSize = AV_RL24(buf)))

                    return AVERROR_INVALIDDATA;

                if (ret = decode_wmv9(avctx, buf + 3, buf_size - 3,

                                      x, y, w, h, wmv9_mask))

                    return ret;

                buf      += WMV9codedFrameSize + 3;

                buf_size -= WMV9codedFrameSize + 3;

            } else {

                uint8_t *dst = c->rgb_pic + y * c->rgb_stride + x * 3;

                if (wmv9_mask != -1) {

                    ctx->dsp.mss2_gray_fill_masked(dst, c->rgb_stride,

                                                   wmv9_mask,

                                                   c->pal_pic + y * c->pal_stride + x,

                                                   c->pal_stride,

                                                   w, h);

                } else {

                    do {

                        memset(dst, 0x80, w * 3);

                        dst += c->rgb_stride;

                    } while (--h);

                }

            }

        }

    }



    if (buf_size)

        av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");



    if (c->mvX < 0 || c->mvY < 0) {

        av_frame_unref(ctx->last_pic);

        ret = av_frame_ref(ctx->last_pic, frame);

        if (ret < 0)

            return ret;

    }



    *got_frame       = 1;



    return avpkt->size;

}

static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1, int *VAR_2,

                             AVPacket *VAR_3)

{

    const uint8_t *VAR_4 = VAR_3->VAR_1;

    int VAR_5       = VAR_3->size;

    MSS2Context *ctx = VAR_0->priv_data;

    MSS12Context *c  = &ctx->c;

    AVFrame *frame   = VAR_1;

    GetBitContext gb;

    GetByteContext gB;

    ArithCoder acoder;



    int VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11;



    Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r;

    int VAR_12 = 0, VAR_13, VAR_14 = 0, FUNC_1(wmv9_mask);



    if ((VAR_11 = init_get_bits8(&gb, VAR_4, VAR_5)) < 0)

        return VAR_11;



    if (VAR_6 = get_bits1(&gb))

        skip_bits(&gb, 7);

    VAR_7 = get_bits1(&gb);

    VAR_8   = VAR_6 ? 0 : get_bits1(&gb);

    VAR_9   = get_bits1(&gb);

    VAR_10   = VAR_9 && get_bits1(&gb);

    if (c->slice_split > 0)

        ctx->split_position = c->slice_split;

    else if (c->slice_split < 0) {

        if (get_bits1(&gb)) {

            if (get_bits1(&gb)) {

                if (get_bits1(&gb))

                    ctx->split_position = get_bits(&gb, 16);

                else

                    ctx->split_position = get_bits(&gb, 12);

            } else

                ctx->split_position = get_bits(&gb, 8) << 4;

        } else {

            if (VAR_6)

                ctx->split_position = VAR_0->height / 2;

        }

    } else

        ctx->split_position = VAR_0->height;



    if (c->slice_split && (ctx->split_position < 1 - VAR_10 ||

                           ctx->split_position > VAR_0->height - 1))

        return AVERROR_INVALIDDATA;



    align_get_bits(&gb);

    VAR_4      += get_bits_count(&gb) >> 3;

    VAR_5 -= get_bits_count(&gb) >> 3;



    if (VAR_5 < 1)

        return AVERROR_INVALIDDATA;



    if (VAR_10 && (VAR_7 || VAR_8 || c->slice_split && ctx->split_position))

        return AVERROR_INVALIDDATA;



    VAR_0->pix_fmt = VAR_10 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;

    if (ctx->last_pic->format != VAR_0->pix_fmt)

        av_frame_unref(ctx->last_pic);



    if (VAR_7) {

        bytestream2_init(&gB, VAR_4, VAR_5 + ARITH2_PADDING);

        arith2_init(&acoder, &gB);



        VAR_14 = !arith2_get_bit(&acoder);



        while (arith2_get_bit(&acoder)) {

            if (VAR_12 == MAX_WMV9_RECTANGLES)

                return AVERROR_INVALIDDATA;

            r = &wmv9rects[VAR_12];

            if (!VAR_12)

                r->VAR_15 = arith2_get_number(&acoder, VAR_0->width);

            else

                r->VAR_15 = arith2_get_number(&acoder, VAR_0->width -

                                         wmv9rects[VAR_12 - 1].VAR_15) +

                       wmv9rects[VAR_12 - 1].VAR_15;

            r->VAR_16 = arith2_get_number(&acoder, VAR_0->height);

            r->VAR_17 = arith2_get_number(&acoder, VAR_0->width  - r->VAR_15) + 1;

            r->VAR_18 = arith2_get_number(&acoder, VAR_0->height - r->VAR_16) + 1;

            VAR_12++;

        }



        if (VAR_14 && VAR_12) {

            av_log(VAR_0, AV_LOG_ERROR, "VAR_14 && VAR_12 > 0\n");

            return AVERROR_INVALIDDATA;

        }



        if (VAR_14) {

            wmv9rects[0].VAR_15 = 0;

            wmv9rects[0].VAR_16 = 0;

            wmv9rects[0].VAR_17 = VAR_0->width;

            wmv9rects[0].VAR_18 = VAR_0->height;



            VAR_12 = 1;

        }

        for (VAR_13 = 0; VAR_13 < VAR_12; VAR_13++) {

            if (!VAR_14 && arith2_get_bit(&acoder)) {

                av_log(VAR_0, AV_LOG_ERROR, "Unexpected grandchildren\n");

                return AVERROR_INVALIDDATA;

            }

            if (!VAR_13) {

                wmv9_mask = arith2_get_bit(&acoder) - 1;

                if (!wmv9_mask)

                    wmv9_mask = arith2_get_number(&acoder, 256);

            }

            wmv9rects[VAR_13].coded = arith2_get_number(&acoder, 2);

        }



        VAR_4      += arith2_get_consumed_bytes(&acoder);

        VAR_5 -= arith2_get_consumed_bytes(&acoder);

        if (VAR_5 < 1)

            return AVERROR_INVALIDDATA;

    }



    c->mvX = c->mvY = 0;

    if (VAR_6 && !VAR_10) {

        if ((VAR_13 = decode_pal_v2(c, VAR_4, VAR_5)) < 0)

            return AVERROR_INVALIDDATA;

        VAR_4      += VAR_13;

        VAR_5 -= VAR_13;

    } else if (VAR_8) {

        VAR_4      += 4;

        VAR_5 -= 4;

        if (VAR_5 < 1)

            return AVERROR_INVALIDDATA;

        c->mvX = AV_RB16(VAR_4 - 4) - VAR_0->width;

        c->mvY = AV_RB16(VAR_4 - 2) - VAR_0->height;

    }



    if (c->mvX < 0 || c->mvY < 0) {

        FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic);



        if ((VAR_11 = ff_get_buffer(VAR_0, frame, AV_GET_BUFFER_FLAG_REF)) < 0)

            return VAR_11;



        if (ctx->last_pic->VAR_1[0]) {

            av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]);

            c->last_rgb_pic = ctx->last_pic->VAR_1[0] +

                              ctx->last_pic->linesize[0] * (VAR_0->height - 1);

        } else {

            av_log(VAR_0, AV_LOG_ERROR, "Missing VAR_6\n");

            return AVERROR_INVALIDDATA;

        }

    } else {

        if ((VAR_11 = ff_reget_buffer(VAR_0, ctx->last_pic)) < 0)

            return VAR_11;

        if ((VAR_11 = av_frame_ref(frame, ctx->last_pic)) < 0)

            return VAR_11;



        c->last_rgb_pic = NULL;

    }

    c->rgb_pic    = frame->VAR_1[0] +

                    frame->linesize[0] * (VAR_0->height - 1);

    c->rgb_stride = -frame->linesize[0];



    frame->key_frame = VAR_6;

    frame->pict_type = VAR_6 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;



    if (VAR_10) {

        bytestream2_init(&gB, VAR_4, VAR_5);



        if (decode_555(&gB, (uint16_t *)c->rgb_pic, c->rgb_stride >> 1,

                       VAR_6, VAR_0->width, VAR_0->height))

            return AVERROR_INVALIDDATA;



        VAR_5 -= bytestream2_tell(&gB);

    } else {

        if (VAR_6) {

            c->corrupted = 0;

            ff_mss12_slicecontext_reset(&ctx->sc[0]);

            if (c->slice_split)

                ff_mss12_slicecontext_reset(&ctx->sc[1]);

        }

        if (VAR_9) {

            if ((VAR_11 = init_get_bits8(&gb, VAR_4, VAR_5)) < 0)

                return VAR_11;

            if (VAR_11 = decode_rle(&gb, c->pal_pic, c->pal_stride,

                                 c->rgb_pic, c->rgb_stride, c->pal, VAR_6,

                                 ctx->split_position, 0,

                                 VAR_0->width, VAR_0->height))

                return VAR_11;

            align_get_bits(&gb);



            if (c->slice_split)

                if (VAR_11 = decode_rle(&gb, c->pal_pic, c->pal_stride,

                                     c->rgb_pic, c->rgb_stride, c->pal, VAR_6,

                                     ctx->split_position, 1,

                                     VAR_0->width, VAR_0->height))

                    return VAR_11;



            align_get_bits(&gb);

            VAR_4      += get_bits_count(&gb) >> 3;

            VAR_5 -= get_bits_count(&gb) >> 3;

        } else if (!VAR_14 || wmv9_mask != -1) {

            if (c->corrupted)

                return AVERROR_INVALIDDATA;

            bytestream2_init(&gB, VAR_4, VAR_5 + ARITH2_PADDING);

            arith2_init(&acoder, &gB);

            c->VAR_6 = VAR_6;

            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,

                                                    VAR_0->width,

                                                    ctx->split_position))

                return AVERROR_INVALIDDATA;



            VAR_4      += arith2_get_consumed_bytes(&acoder);

            VAR_5 -= arith2_get_consumed_bytes(&acoder);

            if (c->slice_split) {

                if (VAR_5 < 1)

                    return AVERROR_INVALIDDATA;

                bytestream2_init(&gB, VAR_4, VAR_5 + ARITH2_PADDING);

                arith2_init(&acoder, &gB);

                if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,

                                                        ctx->split_position,

                                                        VAR_0->width,

                                                        VAR_0->height - ctx->split_position))

                    return AVERROR_INVALIDDATA;



                VAR_4      += arith2_get_consumed_bytes(&acoder);

                VAR_5 -= arith2_get_consumed_bytes(&acoder);

            }

        } else

            memset(c->pal_pic, 0, c->pal_stride * VAR_0->height);

    }



    if (VAR_7) {

        for (VAR_13 = 0; VAR_13 < VAR_12; VAR_13++) {

            int VAR_15 = wmv9rects[VAR_13].VAR_15;

            int VAR_16 = wmv9rects[VAR_13].VAR_16;

            int VAR_17 = wmv9rects[VAR_13].VAR_17;

            int VAR_18 = wmv9rects[VAR_13].VAR_18;

            if (wmv9rects[VAR_13].coded) {

                int VAR_19;

                if (VAR_5 < 4 || !(VAR_19 = AV_RL24(VAR_4)))

                    return AVERROR_INVALIDDATA;

                if (VAR_11 = decode_wmv9(VAR_0, VAR_4 + 3, VAR_5 - 3,

                                      VAR_15, VAR_16, VAR_17, VAR_18, wmv9_mask))

                    return VAR_11;

                VAR_4      += VAR_19 + 3;

                VAR_5 -= VAR_19 + 3;

            } else {

                uint8_t *dst = c->rgb_pic + VAR_16 * c->rgb_stride + VAR_15 * 3;

                if (wmv9_mask != -1) {

                    ctx->dsp.mss2_gray_fill_masked(dst, c->rgb_stride,

                                                   wmv9_mask,

                                                   c->pal_pic + VAR_16 * c->pal_stride + VAR_15,

                                                   c->pal_stride,

                                                   VAR_17, VAR_18);

                } else {

                    do {

                        memset(dst, 0x80, VAR_17 * 3);

                        dst += c->rgb_stride;

                    } while (--VAR_18);

                }

            }

        }

    }



    if (VAR_5)

        av_log(VAR_0, AV_LOG_WARNING, "buffer not fully consumed\n");



    if (c->mvX < 0 || c->mvY < 0) {

        av_frame_unref(ctx->last_pic);

        VAR_11 = av_frame_ref(ctx->last_pic, frame);

        if (VAR_11 < 0)

            return VAR_11;

    }



    *VAR_2       = 1;



    return VAR_3->size;

}

static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1, int *VAR_2,
AVPacket *VAR_3)
{ const uint8_t *VAR_4 = VAR_3->VAR_1; int VAR_5       = VAR_3->size; MSS2Context *ctx = VAR_0->priv_data; MSS12Context *c  = &ctx->c; AVFrame *frame   = VAR_1; GetBitContext gb; GetByteContext gB; ArithCoder acoder; int VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11; Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r; int VAR_12 = 0, VAR_13, VAR_14 = 0, FUNC_1(wmv9_mask); if ((VAR_11 = init_get_bits8(&gb, VAR_4, VAR_5)) < 0)
return VAR_11; if (VAR_6 = get_bits1(&gb))
skip_bits(&gb, 7); VAR_7 = get_bits1(&gb); VAR_8   = VAR_6 ? 0 : get_bits1(&gb); VAR_9   = get_bits1(&gb); VAR_10   = VAR_9 && get_bits1(&gb); if (c->slice_split > 0)
ctx->split_position = c->slice_split; else if (c->slice_split < 0) { if (get_bits1(&gb)) { if (get_bits1(&gb)) { if (get_bits1(&gb))
ctx->split_position = get_bits(&gb, 16); else
ctx->split_position = get_bits(&gb, 12); } else ctx->split_position = get_bits(&gb, 8) << 4; } else { if (VAR_6)
ctx->split_position = VAR_0->height / 2; } } else ctx->split_position = VAR_0->height; if (c->slice_split && (ctx->split_position < 1 - VAR_10 ||
ctx->split_position > VAR_0->height - 1))
return AVERROR_INVALIDDATA; align_get_bits(&gb); VAR_4      += get_bits_count(&gb) >> 3; VAR_5 -= get_bits_count(&gb) >> 3; if (VAR_5 < 1)
return AVERROR_INVALIDDATA; if (VAR_10 && (VAR_7 || VAR_8 || c->slice_split && ctx->split_position))
return AVERROR_INVALIDDATA; VAR_0->pix_fmt = VAR_10 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24; if (ctx->last_pic->format != VAR_0->pix_fmt)
av_frame_unref(ctx->last_pic); if (VAR_7) { bytestream2_init(&gB, VAR_4, VAR_5 + ARITH2_PADDING); arith2_init(&acoder, &gB); VAR_14 = !arith2_get_bit(&acoder); while (arith2_get_bit(&acoder)) { if (VAR_12 == MAX_WMV9_RECTANGLES)
return AVERROR_INVALIDDATA; r = &wmv9rects[VAR_12]; if (!VAR_12)
r->VAR_15 = arith2_get_number(&acoder, VAR_0->width); else
r->VAR_15 = arith2_get_number(&acoder, VAR_0->width -
wmv9rects[VAR_12 - 1].VAR_15) +
wmv9rects[VAR_12 - 1].VAR_15; r->VAR_16 = arith2_get_number(&acoder, VAR_0->height); r->VAR_17 = arith2_get_number(&acoder, VAR_0->width  - r->VAR_15) + 1; r->VAR_18 = arith2_get_number(&acoder, VAR_0->height - r->VAR_16) + 1; VAR_12++; } if (VAR_14 && VAR_12) { av_log(VAR_0, AV_LOG_ERROR, "VAR_14 && VAR_12 > 0\n"); return AVERROR_INVALIDDATA; } if (VAR_14) { wmv9rects[0].VAR_15 = 0; wmv9rects[0].VAR_16 = 0; wmv9rects[0].VAR_17 = VAR_0->width; wmv9rects[0].VAR_18 = VAR_0->height; VAR_12 = 1; } for (VAR_13 = 0; VAR_13 < VAR_12; VAR_13++) { if (!VAR_14 && arith2_get_bit(&acoder)) { av_log(VAR_0, AV_LOG_ERROR, "Unexpected grandchildren\n"); return AVERROR_INVALIDDATA; } if (!VAR_13) { wmv9_mask = arith2_get_bit(&acoder) - 1; if (!wmv9_mask)
wmv9_mask = arith2_get_number(&acoder, 256); } wmv9rects[VAR_13].coded = arith2_get_number(&acoder, 2); } VAR_4      += arith2_get_consumed_bytes(&acoder); VAR_5 -= arith2_get_consumed_bytes(&acoder); if (VAR_5 < 1)
return AVERROR_INVALIDDATA; } c->mvX = c->mvY = 0; if (VAR_6 && !VAR_10) { if ((VAR_13 = decode_pal_v2(c, VAR_4, VAR_5)) < 0)
return AVERROR_INVALIDDATA; VAR_4      += VAR_13; VAR_5 -= VAR_13; } else if (VAR_8) { VAR_4      += 4; VAR_5 -= 4; if (VAR_5 < 1)
return AVERROR_INVALIDDATA; c->mvX = AV_RB16(VAR_4 - 4) - VAR_0->width; c->mvY = AV_RB16(VAR_4 - 2) - VAR_0->height; } if (c->mvX < 0 || c->mvY < 0) { FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic); if ((VAR_11 = ff_get_buffer(VAR_0, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
return VAR_11; if (ctx->last_pic->VAR_1[0]) { av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]); c->last_rgb_pic = ctx->last_pic->VAR_1[0] +
ctx->last_pic->linesize[0] * (VAR_0->height - 1); } else { av_log(VAR_0, AV_LOG_ERROR, "Missing VAR_6\n"); return AVERROR_INVALIDDATA; } } else { if ((VAR_11 = ff_reget_buffer(VAR_0, ctx->last_pic)) < 0)
return VAR_11; if ((VAR_11 = av_frame_ref(frame, ctx->last_pic)) < 0)
return VAR_11; c->last_rgb_pic = NULL; } c->rgb_pic    = frame->VAR_1[0] +
frame->linesize[0] * (VAR_0->height - 1); c->rgb_stride = -frame->linesize[0]; frame->key_frame = VAR_6; frame->pict_type = VAR_6 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; if (VAR_10) { bytestream2_init(&gB, VAR_4, VAR_5); if (decode_555(&gB, (uint16_t *)c->rgb_pic, c->rgb_stride >> 1,
VAR_6, VAR_0->width, VAR_0->height))
return AVERROR_INVALIDDATA; VAR_5 -= bytestream2_tell(&gB); } else { if (VAR_6) { c->corrupted = 0; ff_mss12_slicecontext_reset(&ctx->sc[0]); if (c->slice_split)
ff_mss12_slicecontext_reset(&ctx->sc[1]); } if (VAR_9) { if ((VAR_11 = init_get_bits8(&gb, VAR_4, VAR_5)) < 0)
return VAR_11; if (VAR_11 = decode_rle(&gb, c->pal_pic, c->pal_stride,
c->rgb_pic, c->rgb_stride, c->pal, VAR_6,
ctx->split_position, 0,
VAR_0->width, VAR_0->height))
return VAR_11; align_get_bits(&gb); if (c->slice_split)
if (VAR_11 = decode_rle(&gb, c->pal_pic, c->pal_stride,
c->rgb_pic, c->rgb_stride, c->pal, VAR_6,
ctx->split_position, 1,
VAR_0->width, VAR_0->height))
return VAR_11; align_get_bits(&gb); VAR_4      += get_bits_count(&gb) >> 3; VAR_5 -= get_bits_count(&gb) >> 3; } else if (!VAR_14 || wmv9_mask != -1) { if (c->corrupted)
return AVERROR_INVALIDDATA; bytestream2_init(&gB, VAR_4, VAR_5 + ARITH2_PADDING); arith2_init(&acoder, &gB); c->VAR_6 = VAR_6; if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,
VAR_0->width,
ctx->split_position))
return AVERROR_INVALIDDATA; VAR_4      += arith2_get_consumed_bytes(&acoder); VAR_5 -= arith2_get_consumed_bytes(&acoder); if (c->slice_split) { if (VAR_5 < 1)
return AVERROR_INVALIDDATA; bytestream2_init(&gB, VAR_4, VAR_5 + ARITH2_PADDING); arith2_init(&acoder, &gB); if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,
ctx->split_position,
VAR_0->width,
VAR_0->height - ctx->split_position))
return AVERROR_INVALIDDATA; VAR_4      += arith2_get_consumed_bytes(&acoder); VAR_5 -= arith2_get_consumed_bytes(&acoder); } } else memset(c->pal_pic, 0, c->pal_stride * VAR_0->height); } if (VAR_7) { for (VAR_13 = 0; VAR_13 < VAR_12; VAR_13++) { int VAR_15 = wmv9rects[VAR_13].VAR_15; int VAR_16 = wmv9rects[VAR_13].VAR_16; int VAR_17 = wmv9rects[VAR_13].VAR_17; int VAR_18 = wmv9rects[VAR_13].VAR_18; if (wmv9rects[VAR_13].coded) { int VAR_19; if (VAR_5 < 4 || !(VAR_19 = AV_RL24(VAR_4)))
return AVERROR_INVALIDDATA; if (VAR_11 = decode_wmv9(VAR_0, VAR_4 + 3, VAR_5 - 3,
VAR_15, VAR_16, VAR_17, VAR_18, wmv9_mask))
return VAR_11; VAR_4      += VAR_19 + 3; VAR_5 -= VAR_19 + 3; } else { uint8_t *dst = c->rgb_pic + VAR_16 * c->rgb_stride + VAR_15 * 3; if (wmv9_mask != -1) { ctx->dsp.mss2_gray_fill_masked(dst, c->rgb_stride,
wmv9_mask,
c->pal_pic + VAR_16 * c->pal_stride + VAR_15,
c->pal_stride,
VAR_17, VAR_18); } else { do { memset(dst, 0x80, VAR_17 * 3); dst += c->rgb_stride; } while (--VAR_18); } } } } if (VAR_5)
av_log(VAR_0, AV_LOG_WARNING, "buffer not fully consumed\n"); if (c->mvX < 0 || c->mvY < 0) { av_frame_unref(ctx->last_pic); VAR_11 = av_frame_ref(ctx->last_pic, frame); if (VAR_11 < 0)
return VAR_11; } *VAR_2       = 1; return VAR_3->size; }