static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,

                                const uint8_t *buf, int buf_size)

{

    GetByteContext gb;

    const uint8_t   *bs_hdr;

    uint32_t        frame_num, word2, check_sum, data_size;

    uint32_t        y_offset, u_offset, v_offset, starts[3], ends[3];

    uint16_t        height, width;

    int             i, j;



    bytestream2_init(&gb, buf, buf_size);



    /* parse and check the OS header */

    frame_num = bytestream2_get_le32(&gb);

    word2     = bytestream2_get_le32(&gb);

    check_sum = bytestream2_get_le32(&gb);

    data_size = bytestream2_get_le32(&gb);



    if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {

        av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");

        return AVERROR_INVALIDDATA;

    }



    /* parse the bitstream header */

    bs_hdr = gb.buffer;



    if (bytestream2_get_le16(&gb) != 32) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");

        return AVERROR_INVALIDDATA;

    }



    ctx->frame_num   =  frame_num;

    ctx->frame_flags =  bytestream2_get_le16(&gb);

    ctx->data_size   = (bytestream2_get_le32(&gb) + 7) >> 3;

    ctx->cb_offset   =  bytestream2_get_byte(&gb);



    if (ctx->data_size == 16)

        return 4;

    if (ctx->data_size > buf_size)

        ctx->data_size = buf_size;



    bytestream2_skip(&gb, 3); // skip reserved byte and checksum



    /* check frame dimensions */

    height = bytestream2_get_le16(&gb);

    width  = bytestream2_get_le16(&gb);

    if (av_image_check_size(width, height, 0, avctx))

        return AVERROR_INVALIDDATA;



    if (width != ctx->width || height != ctx->height) {

        int res;



        av_dlog(avctx, "Frame dimensions changed!\n");



        if (width  < 16 || width  > 640 ||

            height < 16 || height > 480 ||

            width  &  3 || height &   3) {

            av_log(avctx, AV_LOG_ERROR,

                   "Invalid picture dimensions: %d x %d!\n", width, height);

            return AVERROR_INVALIDDATA;

        }



        ctx->width  = width;

        ctx->height = height;



        free_frame_buffers(ctx);

        if ((res = allocate_frame_buffers(ctx, avctx)) < 0)

             return res;

        avcodec_set_dimensions(avctx, width, height);

    }



    y_offset = bytestream2_get_le32(&gb);

    v_offset = bytestream2_get_le32(&gb);

    u_offset = bytestream2_get_le32(&gb);

    bytestream2_skip(&gb, 4);



    /* unfortunately there is no common order of planes in the buffer */

    /* so we use that sorting algo for determining planes data sizes  */

    starts[0] = y_offset;

    starts[1] = v_offset;

    starts[2] = u_offset;



    for (j = 0; j < 3; j++) {

        ends[j] = ctx->data_size;

        for (i = 2; i >= 0; i--)

            if (starts[i] < ends[j] && starts[i] > starts[j])

                ends[j] = starts[i];

    }



    ctx->y_data_size = ends[0] - starts[0];

    ctx->v_data_size = ends[1] - starts[1];

    ctx->u_data_size = ends[2] - starts[2];

    if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||

        FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 ||

        FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {

        av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");

        return AVERROR_INVALIDDATA;

    }



    ctx->y_data_ptr = bs_hdr + y_offset;

    ctx->v_data_ptr = bs_hdr + v_offset;

    ctx->u_data_ptr = bs_hdr + u_offset;

    ctx->alt_quant  = gb.buffer;



    if (ctx->data_size == 16) {

        av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");

        return 16;

    }



    if (ctx->frame_flags & BS_8BIT_PEL) {

        avpriv_request_sample(avctx, "8-bit pixel format");

        return AVERROR_PATCHWELCOME;

    }



    if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {

        avpriv_request_sample(avctx, "Halfpel motion vectors");

        return AVERROR_PATCHWELCOME;

    }



    return 0;

}

static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,

                                const uint8_t *buf, int buf_size)

{

    GetByteContext gb;

    const uint8_t   *bs_hdr;

    uint32_t        frame_num, word2, check_sum, data_size;

    uint32_t        y_offset, u_offset, v_offset, starts[3], ends[3];

    uint16_t        height, width;

    int             i, j;



    bytestream2_init(&gb, buf, buf_size);



    

    frame_num = bytestream2_get_le32(&gb);

    word2     = bytestream2_get_le32(&gb);

    check_sum = bytestream2_get_le32(&gb);

    data_size = bytestream2_get_le32(&gb);



    if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {

        av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");

        return AVERROR_INVALIDDATA;

    }



    

    bs_hdr = gb.buffer;



    if (bytestream2_get_le16(&gb) != 32) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");

        return AVERROR_INVALIDDATA;

    }



    ctx->frame_num   =  frame_num;

    ctx->frame_flags =  bytestream2_get_le16(&gb);

    ctx->data_size   = (bytestream2_get_le32(&gb) + 7) >> 3;

    ctx->cb_offset   =  bytestream2_get_byte(&gb);



    if (ctx->data_size == 16)

        return 4;

    if (ctx->data_size > buf_size)

        ctx->data_size = buf_size;



    bytestream2_skip(&gb, 3); 



    

    height = bytestream2_get_le16(&gb);

    width  = bytestream2_get_le16(&gb);

    if (av_image_check_size(width, height, 0, avctx))

        return AVERROR_INVALIDDATA;



    if (width != ctx->width || height != ctx->height) {

        int res;



        av_dlog(avctx, "Frame dimensions changed!\n");



        if (width  < 16 || width  > 640 ||

            height < 16 || height > 480 ||

            width  &  3 || height &   3) {

            av_log(avctx, AV_LOG_ERROR,

                   "Invalid picture dimensions: %d x %d!\n", width, height);

            return AVERROR_INVALIDDATA;

        }



        ctx->width  = width;

        ctx->height = height;



        free_frame_buffers(ctx);

        if ((res = allocate_frame_buffers(ctx, avctx)) < 0)

             return res;

        avcodec_set_dimensions(avctx, width, height);

    }



    y_offset = bytestream2_get_le32(&gb);

    v_offset = bytestream2_get_le32(&gb);

    u_offset = bytestream2_get_le32(&gb);

    bytestream2_skip(&gb, 4);



    

    

    starts[0] = y_offset;

    starts[1] = v_offset;

    starts[2] = u_offset;



    for (j = 0; j < 3; j++) {

        ends[j] = ctx->data_size;

        for (i = 2; i >= 0; i--)

            if (starts[i] < ends[j] && starts[i] > starts[j])

                ends[j] = starts[i];

    }



    ctx->y_data_size = ends[0] - starts[0];

    ctx->v_data_size = ends[1] - starts[1];

    ctx->u_data_size = ends[2] - starts[2];

    if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||

        FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 ||

        FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {

        av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");

        return AVERROR_INVALIDDATA;

    }



    ctx->y_data_ptr = bs_hdr + y_offset;

    ctx->v_data_ptr = bs_hdr + v_offset;

    ctx->u_data_ptr = bs_hdr + u_offset;

    ctx->alt_quant  = gb.buffer;



    if (ctx->data_size == 16) {

        av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");

        return 16;

    }



    if (ctx->frame_flags & BS_8BIT_PEL) {

        avpriv_request_sample(avctx, "8-bit pixel format");

        return AVERROR_PATCHWELCOME;

    }



    if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {

        avpriv_request_sample(avctx, "Halfpel motion vectors");

        return AVERROR_PATCHWELCOME;

    }



    return 0;

}

    if (ctx->data_size > buf_size)         ctx->data_size = buf_size;
static int FUNC_0(Indeo3DecodeContext *VAR_0, AVCodecContext *VAR_1,

                                const uint8_t *VAR_2, int VAR_3)

{

    GetByteContext gb;

    const uint8_t   *VAR_4;

    uint32_t        frame_num, word2, check_sum, data_size;

    uint32_t        y_offset, u_offset, v_offset, starts[3], ends[3];

    uint16_t        height, width;

    int             VAR_5, VAR_6;



    bytestream2_init(&gb, VAR_2, VAR_3);



    

    frame_num = bytestream2_get_le32(&gb);

    word2     = bytestream2_get_le32(&gb);

    check_sum = bytestream2_get_le32(&gb);

    data_size = bytestream2_get_le32(&gb);



    if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {

        av_log(VAR_1, AV_LOG_ERROR, "OS header checksum mismatch!\n");

        return AVERROR_INVALIDDATA;

    }



    

    VAR_4 = gb.buffer;



    if (bytestream2_get_le16(&gb) != 32) {

        av_log(VAR_1, AV_LOG_ERROR, "Unsupported codec version!\n");

        return AVERROR_INVALIDDATA;

    }



    VAR_0->frame_num   =  frame_num;

    VAR_0->frame_flags =  bytestream2_get_le16(&gb);

    VAR_0->data_size   = (bytestream2_get_le32(&gb) + 7) >> 3;

    VAR_0->cb_offset   =  bytestream2_get_byte(&gb);



    if (VAR_0->data_size == 16)

        return 4;

    if (VAR_0->data_size > VAR_3)

        VAR_0->data_size = VAR_3;



    bytestream2_skip(&gb, 3); 



    

    height = bytestream2_get_le16(&gb);

    width  = bytestream2_get_le16(&gb);

    if (av_image_check_size(width, height, 0, VAR_1))

        return AVERROR_INVALIDDATA;



    if (width != VAR_0->width || height != VAR_0->height) {

        int VAR_7;



        av_dlog(VAR_1, "Frame dimensions changed!\n");



        if (width  < 16 || width  > 640 ||

            height < 16 || height > 480 ||

            width  &  3 || height &   3) {

            av_log(VAR_1, AV_LOG_ERROR,

                   "Invalid picture dimensions: %d x %d!\n", width, height);

            return AVERROR_INVALIDDATA;

        }



        VAR_0->width  = width;

        VAR_0->height = height;



        free_frame_buffers(VAR_0);

        if ((VAR_7 = allocate_frame_buffers(VAR_0, VAR_1)) < 0)

             return VAR_7;

        avcodec_set_dimensions(VAR_1, width, height);

    }



    y_offset = bytestream2_get_le32(&gb);

    v_offset = bytestream2_get_le32(&gb);

    u_offset = bytestream2_get_le32(&gb);

    bytestream2_skip(&gb, 4);



    

    

    starts[0] = y_offset;

    starts[1] = v_offset;

    starts[2] = u_offset;



    for (VAR_6 = 0; VAR_6 < 3; VAR_6++) {

        ends[VAR_6] = VAR_0->data_size;

        for (VAR_5 = 2; VAR_5 >= 0; VAR_5--)

            if (starts[VAR_5] < ends[VAR_6] && starts[VAR_5] > starts[VAR_6])

                ends[VAR_6] = starts[VAR_5];

    }



    VAR_0->y_data_size = ends[0] - starts[0];

    VAR_0->v_data_size = ends[1] - starts[1];

    VAR_0->u_data_size = ends[2] - starts[2];

    if (FFMAX3(y_offset, v_offset, u_offset) >= VAR_0->data_size - 16 ||

        FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - VAR_4 + 16 ||

        FFMIN3(VAR_0->y_data_size, VAR_0->v_data_size, VAR_0->u_data_size) <= 0) {

        av_log(VAR_1, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");

        return AVERROR_INVALIDDATA;

    }



    VAR_0->y_data_ptr = VAR_4 + y_offset;

    VAR_0->v_data_ptr = VAR_4 + v_offset;

    VAR_0->u_data_ptr = VAR_4 + u_offset;

    VAR_0->alt_quant  = gb.buffer;



    if (VAR_0->data_size == 16) {

        av_log(VAR_1, AV_LOG_DEBUG, "Sync frame encountered!\n");

        return 16;

    }



    if (VAR_0->frame_flags & BS_8BIT_PEL) {

        avpriv_request_sample(VAR_1, "8-bit pixel format");

        return AVERROR_PATCHWELCOME;

    }



    if (VAR_0->frame_flags & BS_MV_X_HALF || VAR_0->frame_flags & BS_MV_Y_HALF) {

        avpriv_request_sample(VAR_1, "Halfpel motion vectors");

        return AVERROR_PATCHWELCOME;

    }



    return 0;

}

static int FUNC_0(Indeo3DecodeContext *VAR_0, AVCodecContext *VAR_1,
const uint8_t *VAR_2, int VAR_3)
{ GetByteContext gb; const uint8_t   *VAR_4; uint32_t        frame_num, word2, check_sum, data_size; uint32_t        y_offset, u_offset, v_offset, starts[3], ends[3]; uint16_t        height, width; int             VAR_5, VAR_6; bytestream2_init(&gb, VAR_2, VAR_3); frame_num = bytestream2_get_le32(&gb); word2     = bytestream2_get_le32(&gb); check_sum = bytestream2_get_le32(&gb); data_size = bytestream2_get_le32(&gb); if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) { av_log(VAR_1, AV_LOG_ERROR, "OS header checksum mismatch!\n"); return AVERROR_INVALIDDATA; } VAR_4 = gb.buffer; if (bytestream2_get_le16(&gb) != 32) { av_log(VAR_1, AV_LOG_ERROR, "Unsupported codec version!\n"); return AVERROR_INVALIDDATA; } VAR_0->frame_num   =  frame_num; VAR_0->frame_flags =  bytestream2_get_le16(&gb); VAR_0->data_size   = (bytestream2_get_le32(&gb) + 7) >> 3; VAR_0->cb_offset   =  bytestream2_get_byte(&gb); if (VAR_0->data_size == 16)
return 4; if (VAR_0->data_size > VAR_3)
VAR_0->data_size = VAR_3; bytestream2_skip(&gb, 3); height = bytestream2_get_le16(&gb); width  = bytestream2_get_le16(&gb); if (av_image_check_size(width, height, 0, VAR_1))
return AVERROR_INVALIDDATA; if (width != VAR_0->width || height != VAR_0->height) { int VAR_7; av_dlog(VAR_1, "Frame dimensions changed!\n"); if (width  < 16 || width  > 640 ||
height < 16 || height > 480 ||
width  &  3 || height &   3) { av_log(VAR_1, AV_LOG_ERROR,
"Invalid picture dimensions: %d x %d!\n", width, height); return AVERROR_INVALIDDATA; } VAR_0->width  = width; VAR_0->height = height; free_frame_buffers(VAR_0); if ((VAR_7 = allocate_frame_buffers(VAR_0, VAR_1)) < 0)
return VAR_7; avcodec_set_dimensions(VAR_1, width, height); } y_offset = bytestream2_get_le32(&gb); v_offset = bytestream2_get_le32(&gb); u_offset = bytestream2_get_le32(&gb); bytestream2_skip(&gb, 4); starts[0] = y_offset; starts[1] = v_offset; starts[2] = u_offset; for (VAR_6 = 0; VAR_6 < 3; VAR_6++) { ends[VAR_6] = VAR_0->data_size; for (VAR_5 = 2; VAR_5 >= 0; VAR_5--) if (starts[VAR_5] < ends[VAR_6] && starts[VAR_5] > starts[VAR_6])
ends[VAR_6] = starts[VAR_5]; } VAR_0->y_data_size = ends[0] - starts[0]; VAR_0->v_data_size = ends[1] - starts[1]; VAR_0->u_data_size = ends[2] - starts[2]; if (FFMAX3(y_offset, v_offset, u_offset) >= VAR_0->data_size - 16 ||
FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - VAR_4 + 16 ||
FFMIN3(VAR_0->y_data_size, VAR_0->v_data_size, VAR_0->u_data_size) <= 0) { av_log(VAR_1, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n"); return AVERROR_INVALIDDATA; } VAR_0->y_data_ptr = VAR_4 + y_offset; VAR_0->v_data_ptr = VAR_4 + v_offset; VAR_0->u_data_ptr = VAR_4 + u_offset; VAR_0->alt_quant  = gb.buffer; if (VAR_0->data_size == 16) { av_log(VAR_1, AV_LOG_DEBUG, "Sync frame encountered!\n"); return 16; } if (VAR_0->frame_flags & BS_8BIT_PEL) { avpriv_request_sample(VAR_1, "8-bit pixel format"); return AVERROR_PATCHWELCOME; } if (VAR_0->frame_flags & BS_MV_X_HALF || VAR_0->frame_flags & BS_MV_Y_HALF) { avpriv_request_sample(VAR_1, "Halfpel motion vectors"); return AVERROR_PATCHWELCOME; } return 0; }