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);
    av_assert0(FF_INPUT_BUFFER_PADDING_SIZE >=
               ARITH2_PADDING + (MIN_CACHE_BITS + 7) / 8);
    init_get_bits(&gb, buf, buf_size * 8);
    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) {
            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
            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) {
            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
            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) {
            init_get_bits(&gb, buf, buf_size * 8);
            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,\n                             AVPacket *avpkt)\n{\n    const uint8_t *buf = avpkt->data;\n    int buf_size       = avpkt->size;\n    MSS2Context *ctx = avctx->priv_data;\n    MSS12Context *c  = &ctx->c;\n    AVFrame *frame   = data;\n    GetBitContext gb;\n    GetByteContext gB;\n    ArithCoder acoder;\n    int keyframe, has_wmv9, has_mv, is_rle, is_555, ret;\n    Rectangle wmv9rects[MAX_WMV9_RECTANGLES], *r;\n    int used_rects = 0, i, implicit_rect = 0, av_uninit(wmv9_mask);\n    av_assert0(FF_INPUT_BUFFER_PADDING_SIZE >=\n               ARITH2_PADDING + (MIN_CACHE_BITS + 7) / 8);\n    init_get_bits(&gb, buf, buf_size * 8);\n    if (keyframe = get_bits1(&gb))\n        skip_bits(&gb, 7);\n    has_wmv9 = get_bits1(&gb);\n    has_mv   = keyframe ? 0 : get_bits1(&gb);\n    is_rle   = get_bits1(&gb);\n    is_555   = is_rle && get_bits1(&gb);\n    if (c->slice_split > 0)\n        ctx->split_position = c->slice_split;\n    else if (c->slice_split < 0) {\n        if (get_bits1(&gb)) {\n            if (get_bits1(&gb)) {\n                if (get_bits1(&gb))\n                    ctx->split_position = get_bits(&gb, 16);\n                else\n                    ctx->split_position = get_bits(&gb, 12);\n            } else\n                ctx->split_position = get_bits(&gb, 8) << 4;\n        } else {\n            if (keyframe)\n                ctx->split_position = avctx->height / 2;\n        }\n    } else\n        ctx->split_position = avctx->height;\n    if (c->slice_split && (ctx->split_position < 1 - is_555 ||\n                           ctx->split_position > avctx->height - 1))\n        return AVERROR_INVALIDDATA;\n    align_get_bits(&gb);\n    buf      += get_bits_count(&gb) >> 3;\n    buf_size -= get_bits_count(&gb) >> 3;\n    if (buf_size < 1)\n        return AVERROR_INVALIDDATA;\n    if (is_555 && (has_wmv9 || has_mv || c->slice_split && ctx->split_position))\n        return AVERROR_INVALIDDATA;\n    avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;\n    if (ctx->last_pic->format != avctx->pix_fmt)\n        av_frame_unref(ctx->last_pic);\n    if (has_wmv9) {\n        bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);\n        arith2_init(&acoder, &gB);\n        implicit_rect = !arith2_get_bit(&acoder);\n        while (arith2_get_bit(&acoder)) {\n            if (used_rects == MAX_WMV9_RECTANGLES)\n                return AVERROR_INVALIDDATA;\n            r = &wmv9rects[used_rects];\n            if (!used_rects)\n                r->x = arith2_get_number(&acoder, avctx->width);\n            else\n                r->x = arith2_get_number(&acoder, avctx->width -\n                                         wmv9rects[used_rects - 1].x) +\n                       wmv9rects[used_rects - 1].x;\n            r->y = arith2_get_number(&acoder, avctx->height);\n            r->w = arith2_get_number(&acoder, avctx->width  - r->x) + 1;\n            r->h = arith2_get_number(&acoder, avctx->height - r->y) + 1;\n            used_rects++;\n        }\n        if (implicit_rect && used_rects) {\n            av_log(avctx, AV_LOG_ERROR, "implicit_rect && used_rects > 0\\n");\n            return AVERROR_INVALIDDATA;\n        }\n        if (implicit_rect) {\n            wmv9rects[0].x = 0;\n            wmv9rects[0].y = 0;\n            wmv9rects[0].w = avctx->width;\n            wmv9rects[0].h = avctx->height;\n            used_rects = 1;\n        }\n        for (i = 0; i < used_rects; i++) {\n            if (!implicit_rect && arith2_get_bit(&acoder)) {\n                av_log(avctx, AV_LOG_ERROR, "Unexpected grandchildren\\n");\n                return AVERROR_INVALIDDATA;\n            }\n            if (!i) {\n                wmv9_mask = arith2_get_bit(&acoder) - 1;\n                if (!wmv9_mask)\n                    wmv9_mask = arith2_get_number(&acoder, 256);\n            }\n            wmv9rects[i].coded = arith2_get_number(&acoder, 2);\n        }\n        buf      += arith2_get_consumed_bytes(&acoder);\n        buf_size -= arith2_get_consumed_bytes(&acoder);\n        if (buf_size < 1)\n            return AVERROR_INVALIDDATA;\n    }\n    c->mvX = c->mvY = 0;\n    if (keyframe && !is_555) {\n        if ((i = decode_pal_v2(c, buf, buf_size)) < 0)\n            return AVERROR_INVALIDDATA;\n        buf      += i;\n        buf_size -= i;\n    } else if (has_mv) {\n        buf      += 4;\n        buf_size -= 4;\n        if (buf_size < 1)\n            return AVERROR_INVALIDDATA;\n        c->mvX = AV_RB16(buf - 4) - avctx->width;\n        c->mvY = AV_RB16(buf - 2) - avctx->height;\n    }\n    if (c->mvX < 0 || c->mvY < 0) {\n        FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic);\n        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {\n            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\\n");\n            return ret;\n        }\n        if (ctx->last_pic->data[0]) {\n            av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]);\n            c->last_rgb_pic = ctx->last_pic->data[0] +\n                              ctx->last_pic->linesize[0] * (avctx->height - 1);\n        } else {\n            av_log(avctx, AV_LOG_ERROR, "Missing keyframe\\n");\n            return AVERROR_INVALIDDATA;\n        }\n    } else {\n        if ((ret = ff_reget_buffer(avctx, ctx->last_pic)) < 0) {\n            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\\n");\n            return ret;\n        }\n        if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0)\n            return ret;\n        c->last_rgb_pic = NULL;\n    }\n    c->rgb_pic    = frame->data[0] +\n                    frame->linesize[0] * (avctx->height - 1);\n    c->rgb_stride = -frame->linesize[0];\n    frame->key_frame = keyframe;\n    frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;\n    if (is_555) {\n        bytestream2_init(&gB, buf, buf_size);\n        if (decode_555(&gB, (uint16_t *)c->rgb_pic, c->rgb_stride >> 1,\n                       keyframe, avctx->width, avctx->height))\n            return AVERROR_INVALIDDATA;\n        buf_size -= bytestream2_tell(&gB);\n    } else {\n        if (keyframe) {\n            c->corrupted = 0;\n            ff_mss12_slicecontext_reset(&ctx->sc[0]);\n            if (c->slice_split)\n                ff_mss12_slicecontext_reset(&ctx->sc[1]);\n        }\n        if (is_rle) {\n            init_get_bits(&gb, buf, buf_size * 8);\n            if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,\n                                 c->rgb_pic, c->rgb_stride, c->pal, keyframe,\n                                 ctx->split_position, 0,\n                                 avctx->width, avctx->height))\n                return ret;\n            align_get_bits(&gb);\n            if (c->slice_split)\n                if (ret = decode_rle(&gb, c->pal_pic, c->pal_stride,\n                                     c->rgb_pic, c->rgb_stride, c->pal, keyframe,\n                                     ctx->split_position, 1,\n                                     avctx->width, avctx->height))\n                    return ret;\n            align_get_bits(&gb);\n            buf      += get_bits_count(&gb) >> 3;\n            buf_size -= get_bits_count(&gb) >> 3;\n        } else if (!implicit_rect || wmv9_mask != -1) {\n            if (c->corrupted)\n                return AVERROR_INVALIDDATA;\n            bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);\n            arith2_init(&acoder, &gB);\n            c->keyframe = keyframe;\n            if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[0], &acoder, 0, 0,\n                                                    avctx->width,\n                                                    ctx->split_position))\n                return AVERROR_INVALIDDATA;\n            buf      += arith2_get_consumed_bytes(&acoder);\n            buf_size -= arith2_get_consumed_bytes(&acoder);\n            if (c->slice_split) {\n                if (buf_size < 1)\n                    return AVERROR_INVALIDDATA;\n                bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);\n                arith2_init(&acoder, &gB);\n                if (c->corrupted = ff_mss12_decode_rect(&ctx->sc[1], &acoder, 0,\n                                                        ctx->split_position,\n                                                        avctx->width,\n                                                        avctx->height - ctx->split_position))\n                    return AVERROR_INVALIDDATA;\n                buf      += arith2_get_consumed_bytes(&acoder);\n                buf_size -= arith2_get_consumed_bytes(&acoder);\n            }\n        } else\n            memset(c->pal_pic, 0, c->pal_stride * avctx->height);\n    }\n    if (has_wmv9) {\n        for (i = 0; i < used_rects; i++) {\n            int x = wmv9rects[i].x;\n            int y = wmv9rects[i].y;\n            int w = wmv9rects[i].w;\n            int h = wmv9rects[i].h;\n            if (wmv9rects[i].coded) {\n                int WMV9codedFrameSize;\n                if (buf_size < 4 || !(WMV9codedFrameSize = AV_RL24(buf)))\n                    return AVERROR_INVALIDDATA;\n                if (ret = decode_wmv9(avctx, buf + 3, buf_size - 3,\n                                      x, y, w, h, wmv9_mask))\n                    return ret;\n                buf      += WMV9codedFrameSize + 3;\n                buf_size -= WMV9codedFrameSize + 3;\n            } else {\n                uint8_t *dst = c->rgb_pic + y * c->rgb_stride + x * 3;\n                if (wmv9_mask != -1) {\n                    ctx->dsp.mss2_gray_fill_masked(dst, c->rgb_stride,\n                                                   wmv9_mask,\n                                                   c->pal_pic + y * c->pal_stride + x,\n                                                   c->pal_stride,\n                                                   w, h);\n                } else {\n                    do {\n                        memset(dst, 0x80, w * 3);\n                        dst += c->rgb_stride;\n                    } while (--h);\n                }\n            }\n        }\n    }\n    if (buf_size)\n        av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\\n");\n    if (c->mvX < 0 || c->mvY < 0) {\n        av_frame_unref(ctx->last_pic);\n        ret = av_frame_ref(ctx->last_pic, frame);\n        if (ret < 0)\n            return ret;\n    }\n    *got_frame       = 1;\n    return avpkt->size;\n}', 'static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,\n                                int bit_size)\n{\n    int buffer_size;\n    int ret = 0;\n    if (bit_size > INT_MAX - 7 || bit_size < 0 || !buffer) {\n        buffer_size = bit_size = 0;\n        buffer      = NULL;\n        ret         = AVERROR_INVALIDDATA;\n    }\n    buffer_size = (bit_size + 7) >> 3;\n    s->buffer             = buffer;\n    s->size_in_bits       = bit_size;\n#if !UNCHECKED_BITSTREAM_READER\n    s->size_in_bits_plus8 = bit_size + 8;\n#endif\n    s->buffer_end         = buffer + buffer_size;\n    s->index              = 0;\n    return ret;\n}', 'static inline unsigned int get_bits1(GetBitContext *s)\n{\n    unsigned int index = s->index;\n    uint8_t result     = s->buffer[index >> 3];\n#ifdef BITSTREAM_READER_LE\n    result >>= index & 7;\n    result  &= 1;\n#else\n    result <<= index & 7;\n    result >>= 8 - 1;\n#endif\n#if !UNCHECKED_BITSTREAM_READER\n    if (s->index < s->size_in_bits_plus8)\n#endif\n        index++;\n    s->index = index;\n    return result;\n}']