static int cdg_decode_frame(AVCodecContext *avctx,

                            void *data, int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    int ret;

    uint8_t command, inst;

    uint8_t cdg_data[CDG_DATA_SIZE];

    AVFrame *frame = data;

    CDGraphicsContext *cc = avctx->priv_data;



    if (buf_size < CDG_MINIMUM_PKT_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n");

        return AVERROR(EINVAL);

    }

    if (buf_size > CDG_HEADER_SIZE + CDG_DATA_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "buffer too big for decoder\n");

        return AVERROR(EINVAL);

    }



    if ((ret = ff_reget_buffer(avctx, cc->frame)) < 0)

        return ret;

    if (!avctx->frame_number) {

        memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);

        memset(cc->frame->data[1], 0, AVPALETTE_SIZE);

    }



    command = bytestream_get_byte(&buf);

    inst    = bytestream_get_byte(&buf);

    inst    &= CDG_MASK;

    buf += 2;  /// skipping 2 unneeded bytes



    if (buf_size > CDG_HEADER_SIZE)

        bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE);



    if ((command & CDG_MASK) == CDG_COMMAND) {

        switch (inst) {

        case CDG_INST_MEMORY_PRESET:

            if (!(cdg_data[1] & 0x0F))

                memset(cc->frame->data[0], cdg_data[0] & 0x0F,

                       cc->frame->linesize[0] * CDG_FULL_HEIGHT);

            break;

        case CDG_INST_LOAD_PAL_LO:

        case CDG_INST_LOAD_PAL_HIGH:

            if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) {

                av_log(avctx, AV_LOG_ERROR, "buffer too small for loading palette\n");

                return AVERROR(EINVAL);

            }



            cdg_load_palette(cc, cdg_data, inst == CDG_INST_LOAD_PAL_LO);

            break;

        case CDG_INST_BORDER_PRESET:

            cdg_border_preset(cc, cdg_data);

            break;

        case CDG_INST_TILE_BLOCK_XOR:

        case CDG_INST_TILE_BLOCK:

            if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) {

                av_log(avctx, AV_LOG_ERROR, "buffer too small for drawing tile\n");

                return AVERROR(EINVAL);

            }



            ret = cdg_tile_block(cc, cdg_data, inst == CDG_INST_TILE_BLOCK_XOR);

            if (ret) {

                av_log(avctx, AV_LOG_ERROR, "tile is out of range\n");

                return ret;

            }

            break;

        case CDG_INST_SCROLL_PRESET:

        case CDG_INST_SCROLL_COPY:

            if (buf_size - CDG_HEADER_SIZE < CDG_MINIMUM_SCROLL_SIZE) {

                av_log(avctx, AV_LOG_ERROR, "buffer too small for scrolling\n");

                return AVERROR(EINVAL);

            }



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

                return ret;



            cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY);

            av_frame_unref(cc->frame);

            ret = av_frame_ref(cc->frame, frame);

            if (ret < 0)

                return ret;

            break;

        default:

            break;

        }



        if (!frame->data[0]) {

            ret = av_frame_ref(frame, cc->frame);

            if (ret < 0)

                return ret;

        }

        *got_frame = 1;

    } else {

        *got_frame = 0;

        buf_size   = 0;

    }



    return buf_size;

}

static int cdg_decode_frame(AVCodecContext *avctx,

                            void *data, int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    int ret;

    uint8_t command, inst;

    uint8_t cdg_data[CDG_DATA_SIZE];

    AVFrame *frame = data;

    CDGraphicsContext *cc = avctx->priv_data;



    if (buf_size < CDG_MINIMUM_PKT_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n");

        return AVERROR(EINVAL);

    }

    if (buf_size > CDG_HEADER_SIZE + CDG_DATA_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "buffer too big for decoder\n");

        return AVERROR(EINVAL);

    }



    if ((ret = ff_reget_buffer(avctx, cc->frame)) < 0)

        return ret;

    if (!avctx->frame_number) {

        memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);

        memset(cc->frame->data[1], 0, AVPALETTE_SIZE);

    }



    command = bytestream_get_byte(&buf);

    inst    = bytestream_get_byte(&buf);

    inst    &= CDG_MASK;

    buf += 2;  



    if (buf_size > CDG_HEADER_SIZE)

        bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE);



    if ((command & CDG_MASK) == CDG_COMMAND) {

        switch (inst) {

        case CDG_INST_MEMORY_PRESET:

            if (!(cdg_data[1] & 0x0F))

                memset(cc->frame->data[0], cdg_data[0] & 0x0F,

                       cc->frame->linesize[0] * CDG_FULL_HEIGHT);

            break;

        case CDG_INST_LOAD_PAL_LO:

        case CDG_INST_LOAD_PAL_HIGH:

            if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) {

                av_log(avctx, AV_LOG_ERROR, "buffer too small for loading palette\n");

                return AVERROR(EINVAL);

            }



            cdg_load_palette(cc, cdg_data, inst == CDG_INST_LOAD_PAL_LO);

            break;

        case CDG_INST_BORDER_PRESET:

            cdg_border_preset(cc, cdg_data);

            break;

        case CDG_INST_TILE_BLOCK_XOR:

        case CDG_INST_TILE_BLOCK:

            if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) {

                av_log(avctx, AV_LOG_ERROR, "buffer too small for drawing tile\n");

                return AVERROR(EINVAL);

            }



            ret = cdg_tile_block(cc, cdg_data, inst == CDG_INST_TILE_BLOCK_XOR);

            if (ret) {

                av_log(avctx, AV_LOG_ERROR, "tile is out of range\n");

                return ret;

            }

            break;

        case CDG_INST_SCROLL_PRESET:

        case CDG_INST_SCROLL_COPY:

            if (buf_size - CDG_HEADER_SIZE < CDG_MINIMUM_SCROLL_SIZE) {

                av_log(avctx, AV_LOG_ERROR, "buffer too small for scrolling\n");

                return AVERROR(EINVAL);

            }



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

                return ret;



            cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY);

            av_frame_unref(cc->frame);

            ret = av_frame_ref(cc->frame, frame);

            if (ret < 0)

                return ret;

            break;

        default:

            break;

        }



        if (!frame->data[0]) {

            ret = av_frame_ref(frame, cc->frame);

            if (ret < 0)

                return ret;

        }

        *got_frame = 1;

    } else {

        *got_frame = 0;

        buf_size   = 0;

    }



    return buf_size;

}

    uint8_t cdg_data[CDG_DATA_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;

    int VAR_6;

    uint8_t command, inst;

    uint8_t cdg_data[CDG_DATA_SIZE];

    AVFrame *frame = VAR_1;

    CDGraphicsContext *cc = VAR_0->priv_data;



    if (VAR_5 < CDG_MINIMUM_PKT_SIZE) {

        av_log(VAR_0, AV_LOG_ERROR, "buffer too small for decoder\n");

        return AVERROR(EINVAL);

    }

    if (VAR_5 > CDG_HEADER_SIZE + CDG_DATA_SIZE) {

        av_log(VAR_0, AV_LOG_ERROR, "buffer too big for decoder\n");

        return AVERROR(EINVAL);

    }



    if ((VAR_6 = ff_reget_buffer(VAR_0, cc->frame)) < 0)

        return VAR_6;

    if (!VAR_0->frame_number) {

        memset(cc->frame->VAR_1[0], 0, cc->frame->linesize[0] * VAR_0->height);

        memset(cc->frame->VAR_1[1], 0, AVPALETTE_SIZE);

    }



    command = bytestream_get_byte(&VAR_4);

    inst    = bytestream_get_byte(&VAR_4);

    inst    &= CDG_MASK;

    VAR_4 += 2;  



    if (VAR_5 > CDG_HEADER_SIZE)

        bytestream_get_buffer(&VAR_4, cdg_data, VAR_5 - CDG_HEADER_SIZE);



    if ((command & CDG_MASK) == CDG_COMMAND) {

        switch (inst) {

        case CDG_INST_MEMORY_PRESET:

            if (!(cdg_data[1] & 0x0F))

                memset(cc->frame->VAR_1[0], cdg_data[0] & 0x0F,

                       cc->frame->linesize[0] * CDG_FULL_HEIGHT);

            break;

        case CDG_INST_LOAD_PAL_LO:

        case CDG_INST_LOAD_PAL_HIGH:

            if (VAR_5 - CDG_HEADER_SIZE < CDG_DATA_SIZE) {

                av_log(VAR_0, AV_LOG_ERROR, "buffer too small for loading palette\n");

                return AVERROR(EINVAL);

            }



            cdg_load_palette(cc, cdg_data, inst == CDG_INST_LOAD_PAL_LO);

            break;

        case CDG_INST_BORDER_PRESET:

            cdg_border_preset(cc, cdg_data);

            break;

        case CDG_INST_TILE_BLOCK_XOR:

        case CDG_INST_TILE_BLOCK:

            if (VAR_5 - CDG_HEADER_SIZE < CDG_DATA_SIZE) {

                av_log(VAR_0, AV_LOG_ERROR, "buffer too small for drawing tile\n");

                return AVERROR(EINVAL);

            }



            VAR_6 = cdg_tile_block(cc, cdg_data, inst == CDG_INST_TILE_BLOCK_XOR);

            if (VAR_6) {

                av_log(VAR_0, AV_LOG_ERROR, "tile is out of range\n");

                return VAR_6;

            }

            break;

        case CDG_INST_SCROLL_PRESET:

        case CDG_INST_SCROLL_COPY:

            if (VAR_5 - CDG_HEADER_SIZE < CDG_MINIMUM_SCROLL_SIZE) {

                av_log(VAR_0, AV_LOG_ERROR, "buffer too small for scrolling\n");

                return AVERROR(EINVAL);

            }



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

                return VAR_6;



            cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY);

            av_frame_unref(cc->frame);

            VAR_6 = av_frame_ref(cc->frame, frame);

            if (VAR_6 < 0)

                return VAR_6;

            break;

        default:

            break;

        }



        if (!frame->VAR_1[0]) {

            VAR_6 = av_frame_ref(frame, cc->frame);

            if (VAR_6 < 0)

                return VAR_6;

        }

        *VAR_2 = 1;

    } else {

        *VAR_2 = 0;

        VAR_5   = 0;

    }



    return VAR_5;

}

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; int VAR_6; uint8_t command, inst; uint8_t cdg_data[CDG_DATA_SIZE]; AVFrame *frame = VAR_1; CDGraphicsContext *cc = VAR_0->priv_data; if (VAR_5 < CDG_MINIMUM_PKT_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "buffer too small for decoder\n"); return AVERROR(EINVAL); } if (VAR_5 > CDG_HEADER_SIZE + CDG_DATA_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "buffer too big for decoder\n"); return AVERROR(EINVAL); } if ((VAR_6 = ff_reget_buffer(VAR_0, cc->frame)) < 0)
return VAR_6; if (!VAR_0->frame_number) { memset(cc->frame->VAR_1[0], 0, cc->frame->linesize[0] * VAR_0->height); memset(cc->frame->VAR_1[1], 0, AVPALETTE_SIZE); } command = bytestream_get_byte(&VAR_4); inst    = bytestream_get_byte(&VAR_4); inst    &= CDG_MASK; VAR_4 += 2; if (VAR_5 > CDG_HEADER_SIZE)
bytestream_get_buffer(&VAR_4, cdg_data, VAR_5 - CDG_HEADER_SIZE); if ((command & CDG_MASK) == CDG_COMMAND) { switch (inst) { case CDG_INST_MEMORY_PRESET:
if (!(cdg_data[1] & 0x0F))
memset(cc->frame->VAR_1[0], cdg_data[0] & 0x0F,
cc->frame->linesize[0] * CDG_FULL_HEIGHT); break; case CDG_INST_LOAD_PAL_LO:
case CDG_INST_LOAD_PAL_HIGH:
if (VAR_5 - CDG_HEADER_SIZE < CDG_DATA_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "buffer too small for loading palette\n"); return AVERROR(EINVAL); } cdg_load_palette(cc, cdg_data, inst == CDG_INST_LOAD_PAL_LO); break; case CDG_INST_BORDER_PRESET:
cdg_border_preset(cc, cdg_data); break; case CDG_INST_TILE_BLOCK_XOR:
case CDG_INST_TILE_BLOCK:
if (VAR_5 - CDG_HEADER_SIZE < CDG_DATA_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "buffer too small for drawing tile\n"); return AVERROR(EINVAL); } VAR_6 = cdg_tile_block(cc, cdg_data, inst == CDG_INST_TILE_BLOCK_XOR); if (VAR_6) { av_log(VAR_0, AV_LOG_ERROR, "tile is out of range\n"); return VAR_6; } break; case CDG_INST_SCROLL_PRESET:
case CDG_INST_SCROLL_COPY:
if (VAR_5 - CDG_HEADER_SIZE < CDG_MINIMUM_SCROLL_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "buffer too small for scrolling\n"); return AVERROR(EINVAL); } if ((VAR_6 = ff_get_buffer(VAR_0, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
return VAR_6; cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY); av_frame_unref(cc->frame); VAR_6 = av_frame_ref(cc->frame, frame); if (VAR_6 < 0)
return VAR_6; break; default:
break; } if (!frame->VAR_1[0]) { VAR_6 = av_frame_ref(frame, cc->frame); if (VAR_6 < 0)
return VAR_6; } *VAR_2 = 1; } else { *VAR_2 = 0; VAR_5   = 0; } return VAR_5; }