/*
 * Indeo Video v3 compatible decoder
 * Copyright (c) 2009 - 2011 Maxim Poliakovski
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * This is a decoder for Intel Indeo Video v3.
 * It is based on vector quantization, run-length coding and motion compensation.
 * Known container formats: .avi and .mov
 * Known FOURCCs: 'IV31', 'IV32'
 *
 * @see http://wiki.multimedia.cx/index.php?title=Indeo_3
 */

#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "copy_block.h"
#include "bytestream.h"
#include "get_bits.h"
#include "hpeldsp.h"
#include "internal.h"

#include "indeo3data.h"

/* RLE opcodes. */
enum {
    RLE_ESC_F9    = 249, ///< same as RLE_ESC_FA + do the same with next block
    RLE_ESC_FA    = 250, ///< INTRA: skip block, INTER: copy data from reference
    RLE_ESC_FB    = 251, ///< apply null delta to N blocks / skip N blocks
    RLE_ESC_FC    = 252, ///< same as RLE_ESC_FD + do the same with next block
    RLE_ESC_FD    = 253, ///< apply null delta to all remaining lines of this block
    RLE_ESC_FE    = 254, ///< apply null delta to all lines up to the 3rd line
    RLE_ESC_FF    = 255  ///< apply null delta to all lines up to the 2nd line
};


/* Some constants for parsing frame bitstream flags. */
#define BS_8BIT_PEL     (1 << 1) ///< 8-bit pixel bitdepth indicator
#define BS_KEYFRAME     (1 << 2) ///< intra frame indicator
#define BS_MV_Y_HALF    (1 << 4) ///< vertical mv halfpel resolution indicator
#define BS_MV_X_HALF    (1 << 5) ///< horizontal mv halfpel resolution indicator
#define BS_NONREF       (1 << 8) ///< nonref (discardable) frame indicator
#define BS_BUFFER        9       ///< indicates which of two frame buffers should be used


typedef struct Plane {
    uint8_t         *buffers[2];
    uint8_t         *pixels[2]; ///< pointer to the actual pixel data of the buffers above
    uint32_t        width;
    uint32_t        height;
    ptrdiff_t       pitch;
} Plane;

#define CELL_STACK_MAX  20

typedef struct Cell {
    int16_t         xpos;       ///< cell coordinates in 4x4 blocks
    int16_t         ypos;
    int16_t         width;      ///< cell width  in 4x4 blocks
    int16_t         height;     ///< cell height in 4x4 blocks
    uint8_t         tree;       ///< tree id: 0- MC tree, 1 - VQ tree
    const int8_t    *mv_ptr;    ///< ptr to the motion vector if any
} Cell;

typedef struct Indeo3DecodeContext {
    AVCodecContext *avctx;
    HpelDSPContext  hdsp;

    GetBitContext   gb;
    int             need_resync;
    int             skip_bits;
    const uint8_t   *next_cell_data;
    const uint8_t   *last_byte;
    const int8_t    *mc_vectors;
    unsigned        num_vectors;    ///< number of motion vectors in mc_vectors

    int16_t         width, height;
    uint32_t        frame_num;      ///< current frame number (zero-based)
    int             data_size;      ///< size of the frame data in bytes
    uint16_t        frame_flags;    ///< frame properties
    uint8_t         cb_offset;      ///< needed for selecting VQ tables
    uint8_t         buf_sel;        ///< active frame buffer: 0 - primary, 1 -secondary
    const uint8_t   *y_data_ptr;
    const uint8_t   *v_data_ptr;
    const uint8_t   *u_data_ptr;
    int32_t         y_data_size;
    int32_t         v_data_size;
    int32_t         u_data_size;
    const uint8_t   *alt_quant;     ///< secondary VQ table set for the modes 1 and 4
    Plane           planes[3];
} Indeo3DecodeContext;


static uint8_t requant_tab[8][128];

/*
 *  Build the static requantization table.
 *  This table is used to remap pixel values according to a specific
 *  quant index and thus avoid overflows while adding deltas.
 */
static av_cold void build_requant_tab(void)
{
    static const int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 };
    static const int8_t deltas [8] = { 0, 1, 0,  4,  4, 1, 0, 1 };

    int i, j, step;

    for (i = 0; i < 8; i++) {
        step = i + 2;
        for (j = 0; j < 128; j++)
                requant_tab[i][j] = (j + offsets[i]) / step * step + deltas[i];
    }

    /* some last elements calculated above will have values >= 128 */
    /* pixel values shall never exceed 127 so set them to non-overflowing values */
    /* according with the quantization step of the respective section */
    requant_tab[0][127] = 126;
    requant_tab[1][119] = 118;
    requant_tab[1][120] = 118;
    requant_tab[2][126] = 124;
    requant_tab[2][127] = 124;
    requant_tab[6][124] = 120;
    requant_tab[6][125] = 120;
    requant_tab[6][126] = 120;
    requant_tab[6][127] = 120;

    /* Patch for compatibility with the Intel's binary decoders */
    requant_tab[1][7] = 10;
    requant_tab[4][8] = 10;
}


static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
{
    int p;

    ctx->width = ctx->height = 0;

    for (p = 0; p < 3; p++) {
        av_freep(&ctx->planes[p].buffers[0]);
        av_freep(&ctx->planes[p].buffers[1]);
        ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0;
    }
}


static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
                                          AVCodecContext *avctx, int luma_width, int luma_height)
{
    int p, chroma_width, chroma_height;
    int luma_size, chroma_size;
    ptrdiff_t luma_pitch, chroma_pitch;

    if (luma_width  < 16 || luma_width  > 640 ||
        luma_height < 16 || luma_height > 480 ||
        luma_width  &  3 || luma_height &   3) {
        av_log(avctx, AV_LOG_ERROR, "Invalid picture dimensions: %d x %d!\n",
               luma_width, luma_height);
        return AVERROR_INVALIDDATA;
    }

    ctx->width  = luma_width ;
    ctx->height = luma_height;

    chroma_width  = FFALIGN(luma_width  >> 2, 4);
    chroma_height = FFALIGN(luma_height >> 2, 4);

    luma_pitch   = FFALIGN(luma_width,   16);
    chroma_pitch = FFALIGN(chroma_width, 16);

    /* Calculate size of the luminance plane.  */
    /* Add one line more for INTRA prediction. */
    luma_size = luma_pitch * (luma_height + 1);

    /* Calculate size of a chrominance planes. */
    /* Add one line more for INTRA prediction. */
    chroma_size = chroma_pitch * (chroma_height + 1);

    /* allocate frame buffers */
    for (p = 0; p < 3; p++) {
        ctx->planes[p].pitch  = !p ? luma_pitch  : chroma_pitch;
        ctx->planes[p].width  = !p ? luma_width  : chroma_width;
        ctx->planes[p].height = !p ? luma_height : chroma_height;

        ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size);
        ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size);

        if (!ctx->planes[p].buffers[0] || !ctx->planes[p].buffers[1]) {
            free_frame_buffers(ctx);
            return AVERROR(ENOMEM);
        }

        /* fill the INTRA prediction lines with the middle pixel value = 64 */
        memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch);
        memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch);

        /* set buffer pointers = buf_ptr + pitch and thus skip the INTRA prediction line */
        ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch;
        ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch;
        memset(ctx->planes[p].pixels[0], 0, ctx->planes[p].pitch * ctx->planes[p].height);
        memset(ctx->planes[p].pixels[1], 0, ctx->planes[p].pitch * ctx->planes[p].height);
    }

    return 0;
}

/**
 *  Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into
 *  the cell(x, y) in the current frame.
 *
 *  @param ctx      pointer to the decoder context
 *  @param plane    pointer to the plane descriptor
 *  @param cell     pointer to the cell  descriptor
 */
static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
{
    int     h, w, mv_x, mv_y, offset, offset_dst;
    uint8_t *src, *dst;

    /* setup output and reference pointers */
    offset_dst  = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
    dst         = plane->pixels[ctx->buf_sel] + offset_dst;
    if(cell->mv_ptr){
    mv_y        = cell->mv_ptr[0];
    mv_x        = cell->mv_ptr[1];
    }else
        mv_x= mv_y= 0;

    /* -1 because there is an extra line on top for prediction */
    if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
        ((cell->ypos + cell->height) << 2) + mv_y > plane->height     ||
        ((cell->xpos + cell->width)  << 2) + mv_x > plane->width) {
        av_log(ctx->avctx, AV_LOG_ERROR,
               "Motion vectors point out of the frame.\n");
        return AVERROR_INVALIDDATA;
    }

    offset      = offset_dst + mv_y * plane->pitch + mv_x;
    src         = plane->pixels[ctx->buf_sel ^ 1] + offset;

    h = cell->height << 2;

    for (w = cell->width; w > 0;) {
        /* copy using 16xH blocks */
        if (!((cell->xpos << 2) & 15) && w >= 4) {
            for (; w >= 4; src += 16, dst += 16, w -= 4)
                ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h);
        }

        /* copy using 8xH blocks */
        if (!((cell->xpos << 2) & 7) && w >= 2) {
            ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h);
            w -= 2;
            src += 8;
            dst += 8;
        } else if (w >= 1) {
            ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h);
            w--;
            src += 4;
            dst += 4;
        }
    }

    return 0;
}


/* Average 4/8 pixels at once without rounding using SWAR */
#define AVG_32(dst, src, ref) \
    AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL)

#define AVG_64(dst, src, ref) \
    AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)


/*
 *  Replicate each even pixel as follows:
 *  ABCDEFGH -> AACCEEGG
 */
static inline uint64_t replicate64(uint64_t a) {
#if HAVE_BIGENDIAN
    a &= 0xFF00FF00FF00FF00ULL;
    a |= a >> 8;
#else
    a &= 0x00FF00FF00FF00FFULL;
    a |= a << 8;
#endif
    return a;
}

static inline uint32_t replicate32(uint32_t a) {
#if HAVE_BIGENDIAN
    a &= 0xFF00FF00UL;
    a |= a >> 8;
#else
    a &= 0x00FF00FFUL;
    a |= a << 8;
#endif
    return a;
}


/* Fill n lines with 64-bit pixel value pix */
static inline void fill_64(uint8_t *dst, const uint64_t pix, int32_t n,
                           int32_t row_offset)
{
    for (; n > 0; dst += row_offset, n--)
        AV_WN64A(dst, pix);
}


/* Error codes for cell decoding. */
enum {
    IV3_NOERR       = 0,
    IV3_BAD_RLE     = 1,
    IV3_BAD_DATA    = 2,
    IV3_BAD_COUNTER = 3,
    IV3_UNSUPPORTED = 4,
    IV3_OUT_OF_DATA = 5
};


#define BUFFER_PRECHECK \
if (*data_ptr >= last_ptr) \
    return IV3_OUT_OF_DATA; \

#define RLE_BLOCK_COPY \
    if (cell->mv_ptr || !skip_flag) \
        copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)

#define RLE_BLOCK_COPY_8 \
    pix64 = AV_RN64(ref);\
    if (is_first_row) {/* special prediction case: top line of a cell */\
        pix64 = replicate64(pix64);\
        fill_64(dst + row_offset, pix64, 7, row_offset);\
        AVG_64(dst, ref, dst + row_offset);\
    } else \
        fill_64(dst, pix64, 8, row_offset)

#define RLE_LINES_COPY \
    copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)

#define RLE_LINES_COPY_M10 \
    pix64 = AV_RN64(ref);\
    if (is_top_of_cell) {\
        pix64 = replicate64(pix64);\
        fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\
        AVG_64(dst, ref, dst + row_offset);\
    } else \
        fill_64(dst, pix64, num_lines << 1, row_offset)

#define APPLY_DELTA_4 \
    AV_WN16A(dst + line_offset    ,\
             (AV_RN16(ref    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
    AV_WN16A(dst + line_offset + 2,\
             (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
    if (mode >= 3) {\
        if (is_top_of_cell && !cell->ypos) {\
            AV_COPY32U(dst, dst + row_offset);\
        } else {\
            AVG_32(dst, ref, dst + row_offset);\
        }\
    }

#define APPLY_DELTA_8 \
    /* apply two 32-bit VQ deltas to next even line */\
    if (is_top_of_cell) { \
        AV_WN32A(dst + row_offset    , \
                 (replicate32(AV_RN32(ref    )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
        AV_WN32A(dst + row_offset + 4, \
                 (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
    } else { \
        AV_WN32A(dst + row_offset    , \
                 (AV_RN32(ref    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
        AV_WN32A(dst + row_offset + 4, \
                 (AV_RN32(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
    } \
    /* odd lines are not coded but rather interpolated/replicated */\
    /* first line of the cell on the top of image? - replicate */\
    /* otherwise - interpolate */\
    if (is_top_of_cell && !cell->ypos) {\
        AV_COPY64U(dst, dst + row_offset);\
    } else \
        AVG_64(dst, ref, dst + row_offset);


#define APPLY_DELTA_1011_INTER \
    if (mode == 10) { \
        AV_WN32A(dst                 , \
                 (AV_RN32(dst                 ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
        AV_WN32A(dst + 4             , \
                 (AV_RN32(dst + 4             ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
        AV_WN32A(dst + row_offset    , \
                 (AV_RN32(dst + row_offset    ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
        AV_WN32A(dst + row_offset + 4, \
                 (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
    } else { \
        AV_WN16A(dst                 , \
                 (AV_RN16(dst                 ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
        AV_WN16A(dst + 2             , \
                 (AV_RN16(dst + 2             ) + delta_tab->deltas[dyad2]) & 0x7F7F);\
        AV_WN16A(dst + row_offset    , \
                 (AV_RN16(dst + row_offset    ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
        AV_WN16A(dst + row_offset + 2, \
                 (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
    }


static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell,
                            uint8_t *block, uint8_t *ref_block,
                            ptrdiff_t row_offset, int h_zoom, int v_zoom, int mode,
                            const vqEntry *delta[2], int swap_quads[2],
                            const uint8_t **data_ptr, const uint8_t *last_ptr)
{
    int           x, y, line, num_lines;
    int           rle_blocks = 0;
    uint8_t       code, *dst, *ref;
    const vqEntry *delta_tab;
    unsigned int  dyad1, dyad2;
    uint64_t      pix64;
    int           skip_flag = 0, is_top_of_cell, is_first_row = 1;
    int           blk_row_offset, line_offset;

    blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2);
    line_offset    = v_zoom ? row_offset : 0;

    if (cell->height & v_zoom || cell->width & h_zoom)
        return IV3_BAD_DATA;

    for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) {
        for (x = 0; x < cell->width; x += 1 + h_zoom) {
            ref = ref_block;
            dst = block;

            if (rle_blocks > 0) {
                if (mode <= 4) {
                    RLE_BLOCK_COPY;
                } else if (mode == 10 && !cell->mv_ptr) {
                    RLE_BLOCK_COPY_8;
                }
                rle_blocks--;
            } else {
                for (line = 0; line < 4;) {
                    num_lines = 1;
                    is_top_of_cell = is_first_row && !line;

                    /* select primary VQ table for odd, secondary for even lines */
                    if (mode <= 4)
                        delta_tab = delta[line & 1];
                    else
                        delta_tab = delta[1];
                    BUFFER_PRECHECK;
                    code = bytestream_get_byte(data_ptr);
                    if (code < 248) {
                        if (code < delta_tab->num_dyads) {
                            BUFFER_PRECHECK;
                            dyad1 = bytestream_get_byte(data_ptr);
                            dyad2 = code;
                            if (dyad1 >= delta_tab->num_dyads || dyad1 >= 248)
                                return IV3_BAD_DATA;
                        } else {
                            /* process QUADS */
                            code -= delta_tab->num_dyads;
                            dyad1 = code / delta_tab->quad_exp;
                            dyad2 = code % delta_tab->quad_exp;
                            if (swap_quads[line & 1])
                                FFSWAP(unsigned int, dyad1, dyad2);
                        }
                        if (mode <= 4) {
                            APPLY_DELTA_4;
                        } else if (mode == 10 && !cell->mv_ptr) {
                            APPLY_DELTA_8;
                        } else {
                            APPLY_DELTA_1011_INTER;
                        }
                    } else {
                        /* process RLE codes */
                        switch (code) {
                        case RLE_ESC_FC:
                            skip_flag  = 0;
                            rle_blocks = 1;
                            code       = 253;
                            /* FALLTHROUGH */
                        case RLE_ESC_FF:
                        case RLE_ESC_FE:
                        case RLE_ESC_FD:
                            num_lines = 257 - code - line;
                            if (num_lines <= 0)
                                return IV3_BAD_RLE;
                            if (mode <= 4) {
                                RLE_LINES_COPY;
                            } else if (mode == 10 && !cell->mv_ptr) {
                                RLE_LINES_COPY_M10;
                            }
                            break;
                        case RLE_ESC_FB:
                            BUFFER_PRECHECK;
                            code = bytestream_get_byte(data_ptr);
                            rle_blocks = (code & 0x1F) - 1; /* set block counter */
                            if (code >= 64 || rle_blocks < 0)
                                return IV3_BAD_COUNTER;
                            skip_flag = code & 0x20;
                            num_lines = 4 - line; /* enforce next block processing */
                            if (mode >= 10 || (cell->mv_ptr || !skip_flag)) {
                                if (mode <= 4) {
                                    RLE_LINES_COPY;
                                } else if (mode == 10 && !cell->mv_ptr) {
                                    RLE_LINES_COPY_M10;
                                }
                            }
                            break;
                        case RLE_ESC_F9:
                            skip_flag  = 1;
                            rle_blocks = 1;
                            /* FALLTHROUGH */
                        case RLE_ESC_FA:
                            if (line)
                                return IV3_BAD_RLE;
                            num_lines = 4; /* enforce next block processing */
                            if (cell->mv_ptr) {
                                if (mode <= 4) {
                                    RLE_LINES_COPY;
                                } else if (mode == 10 && !cell->mv_ptr) {
                                    RLE_LINES_COPY_M10;
                                }
                            }
                            break;
                        default:
                            return IV3_UNSUPPORTED;
                        }
                    }

                    line += num_lines;
                    ref  += row_offset * (num_lines << v_zoom);
                    dst  += row_offset * (num_lines << v_zoom);
                }
            }

            /* move to next horizontal block */
            block     += 4 << h_zoom;
            ref_block += 4 << h_zoom;
        }

        /* move to next line of blocks */
        ref_block += blk_row_offset;
        block     += blk_row_offset;
    }
    return IV3_NOERR;
}


/**
 *  Decode a vector-quantized cell.
 *  It consists of several routines, each of which handles one or more "modes"
 *  with which a cell can be encoded.
 *
 *  @param ctx      pointer to the decoder context
 *  @param avctx    ptr to the AVCodecContext
 *  @param plane    pointer to the plane descriptor
 *  @param cell     pointer to the cell  descriptor
 *  @param data_ptr pointer to the compressed data
 *  @param last_ptr pointer to the last byte to catch reads past end of buffer
 *  @return         number of consumed bytes or negative number in case of error
 */
static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
                       Plane *plane, Cell *cell, const uint8_t *data_ptr,
                       const uint8_t *last_ptr)
{
    int           x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;
    int           zoom_fac;
    int           offset, error = 0, swap_quads[2];
    uint8_t       code, *block, *ref_block = 0;
    const vqEntry *delta[2];
    const uint8_t *data_start = data_ptr;

    /* get coding mode and VQ table index from the VQ descriptor byte */
    code     = *data_ptr++;
    mode     = code >> 4;
    vq_index = code & 0xF;

    /* setup output and reference pointers */
    offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
    block  =  plane->pixels[ctx->buf_sel] + offset;

    if (!cell->mv_ptr) {
        /* use previous line as reference for INTRA cells */
        ref_block = block - plane->pitch;
    } else if (mode >= 10) {
        /* for mode 10 and 11 INTER first copy the predicted cell into the current one */
        /* so we don't need to do data copying for each RLE code later */
        int ret = copy_cell(ctx, plane, cell);
        if (ret < 0)
            return ret;
    } else {
        /* set the pointer to the reference pixels for modes 0-4 INTER */
        mv_y      = cell->mv_ptr[0];
        mv_x      = cell->mv_ptr[1];

        /* -1 because there is an extra line on top for prediction */
        if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
            ((cell->ypos + cell->height) << 2) + mv_y > plane->height     ||
            ((cell->xpos + cell->width)  << 2) + mv_x > plane->width) {
            av_log(ctx->avctx, AV_LOG_ERROR,
                   "Motion vectors point out of the frame.\n");
            return AVERROR_INVALIDDATA;
        }

        offset   += mv_y * plane->pitch + mv_x;
        ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
    }

    /* select VQ tables as follows: */
    /* modes 0 and 3 use only the primary table for all lines in a block */
    /* while modes 1 and 4 switch between primary and secondary tables on alternate lines */
    if (mode == 1 || mode == 4) {
        code        = ctx->alt_quant[vq_index];
        prim_indx   = (code >> 4)  + ctx->cb_offset;
        second_indx = (code & 0xF) + ctx->cb_offset;
    } else {
        vq_index += ctx->cb_offset;
        prim_indx = second_indx = vq_index;
    }

    if (prim_indx >= 24 || second_indx >= 24) {
        av_log(avctx, AV_LOG_ERROR, "Invalid VQ table indexes! Primary: %d, secondary: %d!\n",
               prim_indx, second_indx);
        return AVERROR_INVALIDDATA;
    }

    delta[0] = &vq_tab[second_indx];
    delta[1] = &vq_tab[prim_indx];
    swap_quads[0] = second_indx >= 16;
    swap_quads[1] = prim_indx   >= 16;

    /* requantize the prediction if VQ index of this cell differs from VQ index */
    /* of the predicted cell in order to avoid overflows. */
    if (vq_index >= 8 && ref_block) {
        for (x = 0; x < cell->width << 2; x++)
            ref_block[x] = requant_tab[vq_index & 7][ref_block[x] & 127];
    }

    error = IV3_NOERR;

    switch (mode) {
    case 0: /*------------------ MODES 0 & 1 (4x4 block processing) --------------------*/
    case 1:
    case 3: /*------------------ MODES 3 & 4 (4x8 block processing) --------------------*/
    case 4:
        if (mode >= 3 && cell->mv_ptr) {
            av_log(avctx, AV_LOG_ERROR, "Attempt to apply Mode 3/4 to an INTER cell!\n");
            return AVERROR_INVALIDDATA;
        }

        zoom_fac = mode >= 3;
        error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
                                 0, zoom_fac, mode, delta, swap_quads,
                                 &data_ptr, last_ptr);
        break;
    case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/
    case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/
        if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */
            error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
                                     1, 1, mode, delta, swap_quads,
                                     &data_ptr, last_ptr);
        } else { /* mode 10 and 11 INTER processing */
            if (mode == 11 && !cell->mv_ptr) {
               av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
               return AVERROR_INVALIDDATA;
            }

            zoom_fac = mode == 10;
            error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
                                     zoom_fac, 1, mode, delta, swap_quads,
                                     &data_ptr, last_ptr);
        }
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unsupported coding mode: %d\n", mode);
        return AVERROR_INVALIDDATA;
    }//switch mode

    switch (error) {
    case IV3_BAD_RLE:
        av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE code %X is not allowed at the current line\n",
               mode, data_ptr[-1]);
        return AVERROR_INVALIDDATA;
    case IV3_BAD_DATA:
        av_log(avctx, AV_LOG_ERROR, "Mode %d: invalid VQ data\n", mode);
        return AVERROR_INVALIDDATA;
    case IV3_BAD_COUNTER:
        av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE-FB invalid counter: %d\n", mode, code);
        return AVERROR_INVALIDDATA;
    case IV3_UNSUPPORTED:
        av_log(avctx, AV_LOG_ERROR, "Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);
        return AVERROR_INVALIDDATA;
    case IV3_OUT_OF_DATA:
        av_log(avctx, AV_LOG_ERROR, "Mode %d: attempt to read past end of buffer\n", mode);
        return AVERROR_INVALIDDATA;
    }

    return data_ptr - data_start; /* report number of bytes consumed from the input buffer */
}


/* Binary tree codes. */
enum {
    H_SPLIT    = 0,
    V_SPLIT    = 1,
    INTRA_NULL = 2,
    INTER_DATA = 3
};


#define SPLIT_CELL(size, new_size) (new_size) = ((size) > 2) ? ((((size) + 2) >> 2) << 1) : 1

#define UPDATE_BITPOS(n) \
    ctx->skip_bits  += (n); \
    ctx->need_resync = 1

#define RESYNC_BITSTREAM \
    if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \
        skip_bits_long(&ctx->gb, ctx->skip_bits);              \
        ctx->skip_bits   = 0;                                  \
        ctx->need_resync = 0;                                  \
    }

#define CHECK_CELL \
    if (curr_cell.xpos + curr_cell.width > (plane->width >> 2) ||               \
        curr_cell.ypos + curr_cell.height > (plane->height >> 2)) {             \
        av_log(avctx, AV_LOG_ERROR, "Invalid cell: x=%d, y=%d, w=%d, h=%d\n",   \
               curr_cell.xpos, curr_cell.ypos, curr_cell.width, curr_cell.height); \
        return AVERROR_INVALIDDATA;                                                              \
    }


static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
                         Plane *plane, int code, Cell *ref_cell,
                         const int depth, const int strip_width)
{
    Cell    curr_cell;
    int     bytes_used, ret;

    if (depth <= 0) {
        av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
        return AVERROR_INVALIDDATA; // unwind recursion
    }

    curr_cell = *ref_cell; // clone parent cell
    if (code == H_SPLIT) {
        SPLIT_CELL(ref_cell->height, curr_cell.height);
        ref_cell->ypos   += curr_cell.height;
        ref_cell->height -= curr_cell.height;
        if (ref_cell->height <= 0 || curr_cell.height <= 0)
            return AVERROR_INVALIDDATA;
    } else if (code == V_SPLIT) {
        if (curr_cell.width > strip_width) {
            /* split strip */
            curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;
        } else
            SPLIT_CELL(ref_cell->width, curr_cell.width);
        ref_cell->xpos  += curr_cell.width;
        ref_cell->width -= curr_cell.width;
        if (ref_cell->width <= 0 || curr_cell.width <= 0)
            return AVERROR_INVALIDDATA;
    }

    while (get_bits_left(&ctx->gb) >= 2) { /* loop until return */
        RESYNC_BITSTREAM;
        switch (code = get_bits(&ctx->gb, 2)) {
        case H_SPLIT:
        case V_SPLIT:
            if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))
                return AVERROR_INVALIDDATA;
            break;
        case INTRA_NULL:
            if (!curr_cell.tree) { /* MC tree INTRA code */
                curr_cell.mv_ptr = 0; /* mark the current strip as INTRA */
                curr_cell.tree   = 1; /* enter the VQ tree */
            } else { /* VQ tree NULL code */
                RESYNC_BITSTREAM;
                code = get_bits(&ctx->gb, 2);
                if (code >= 2) {
                    av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);
                    return AVERROR_INVALIDDATA;
                }
                if (code == 1)
                    av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");

                CHECK_CELL
                if (!curr_cell.mv_ptr)
                    return AVERROR_INVALIDDATA;

                ret = copy_cell(ctx, plane, &curr_cell);
                return ret;
            }
            break;
        case INTER_DATA:
            if (!curr_cell.tree) { /* MC tree INTER code */
                unsigned mv_idx;
                /* get motion vector index and setup the pointer to the mv set */
                if (!ctx->need_resync)
                    ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
                if (ctx->next_cell_data >= ctx->last_byte) {
                    av_log(avctx, AV_LOG_ERROR, "motion vector out of array\n");
                    return AVERROR_INVALIDDATA;
                }
                mv_idx = *(ctx->next_cell_data++);
                if (mv_idx >= ctx->num_vectors) {
                    av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n");
                    return AVERROR_INVALIDDATA;
                }
                curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx << 1];
                curr_cell.tree   = 1; /* enter the VQ tree */
                UPDATE_BITPOS(8);
            } else { /* VQ tree DATA code */
                if (!ctx->need_resync)
                    ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];

                CHECK_CELL
                bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,
                                         ctx->next_cell_data, ctx->last_byte);
                if (bytes_used < 0)
                    return AVERROR_INVALIDDATA;

                UPDATE_BITPOS(bytes_used << 3);
                ctx->next_cell_data += bytes_used;
                return 0;
            }
            break;
        }
    }//while

    return AVERROR_INVALIDDATA;
}


static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
                        Plane *plane, const uint8_t *data, int32_t data_size,
                        int32_t strip_width)
{
    Cell            curr_cell;
    unsigned        num_vectors;

    /* each plane data starts with mc_vector_count field, */
    /* an optional array of motion vectors followed by the vq data */
    num_vectors = bytestream_get_le32(&data); data_size -= 4;
    if (num_vectors > 256) {
        av_log(ctx->avctx, AV_LOG_ERROR,
               "Read invalid number of motion vectors %d\n", num_vectors);
        return AVERROR_INVALIDDATA;
    }
    if (num_vectors * 2 > data_size)
        return AVERROR_INVALIDDATA;

    ctx->num_vectors = num_vectors;
    ctx->mc_vectors  = num_vectors ? data : 0;

    /* init the bitreader */
    init_get_bits(&ctx->gb, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3);
    ctx->skip_bits   = 0;
    ctx->need_resync = 0;

    ctx->last_byte = data + data_size;

    /* initialize the 1st cell and set its dimensions to whole plane */
    curr_cell.xpos   = curr_cell.ypos = 0;
    curr_cell.width  = plane->width  >> 2;
    curr_cell.height = plane->height >> 2;
    curr_cell.tree   = 0; // we are in the MC tree now
    curr_cell.mv_ptr = 0; // no motion vector = INTRA cell

    return parse_bintree(ctx, avctx, plane, INTRA_NULL, &curr_cell, CELL_STACK_MAX, strip_width);
}


#define OS_HDR_ID   MKBETAG('F', 'R', 'M', 'H')

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;
    int             y_offset, u_offset, v_offset;
    uint32_t        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;
    ctx->data_size = FFMIN(ctx->data_size, buf_size - 16);

    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;

        ff_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;
        }
        free_frame_buffers(ctx);
        if ((res = allocate_frame_buffers(ctx, avctx, width, height)) < 0)
             return res;
        if ((res = ff_set_dimensions(avctx, width, height)) < 0)
            return res;
    }

    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 (FFMIN3(y_offset, v_offset, u_offset) < 0 ||
        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;
}


/**
 *  Convert and output the current plane.
 *  All pixel values will be upsampled by shifting right by one bit.
 *
 *  @param[in]  plane        pointer to the descriptor of the plane being processed
 *  @param[in]  buf_sel      indicates which frame buffer the input data stored in
 *  @param[out] dst          pointer to the buffer receiving converted pixels
 *  @param[in]  dst_pitch    pitch for moving to the next y line
 *  @param[in]  dst_height   output plane height
 */
static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst,
                         ptrdiff_t dst_pitch, int dst_height)
{
    int             x,y;
    const uint8_t   *src  = plane->pixels[buf_sel];
    ptrdiff_t       pitch = plane->pitch;

    dst_height = FFMIN(dst_height, plane->height);
    for (y = 0; y < dst_height; y++) {
        /* convert four pixels at once using SWAR */
        for (x = 0; x < plane->width >> 2; x++) {
            AV_WN32A(dst, (AV_RN32A(src) & 0x7F7F7F7F) << 1);
            src += 4;
            dst += 4;
        }

        for (x <<= 2; x < plane->width; x++)
            *dst++ = *src++ << 1;

        src += pitch     - plane->width;
        dst += dst_pitch - plane->width;
    }
}


static av_cold int decode_init(AVCodecContext *avctx)
{
    Indeo3DecodeContext *ctx = avctx->priv_data;

    ctx->avctx     = avctx;
    avctx->pix_fmt = AV_PIX_FMT_YUV410P;

    build_requant_tab();

    ff_hpeldsp_init(&ctx->hdsp, avctx->flags);

    return allocate_frame_buffers(ctx, avctx, avctx->width, avctx->height);
}


static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                        AVPacket *avpkt)
{
    Indeo3DecodeContext *ctx = avctx->priv_data;
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    AVFrame *frame     = data;
    int res;

    res = decode_frame_headers(ctx, avctx, buf, buf_size);
    if (res < 0)
        return res;

    /* skip sync(null) frames */
    if (res) {
        // we have processed 16 bytes but no data was decoded
        *got_frame = 0;
        return buf_size;
    }

    /* skip droppable INTER frames if requested */
    if (ctx->frame_flags & BS_NONREF &&
       (avctx->skip_frame >= AVDISCARD_NONREF))
        return 0;

    /* skip INTER frames if requested */
    if (!(ctx->frame_flags & BS_KEYFRAME) && avctx->skip_frame >= AVDISCARD_NONKEY)
        return 0;

    /* use BS_BUFFER flag for buffer switching */
    ctx->buf_sel = (ctx->frame_flags >> BS_BUFFER) & 1;

    if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
        return res;

    /* decode luma plane */
    if ((res = decode_plane(ctx, avctx, ctx->planes, ctx->y_data_ptr, ctx->y_data_size, 40)))
        return res;

    /* decode chroma planes */
    if ((res = decode_plane(ctx, avctx, &ctx->planes[1], ctx->u_data_ptr, ctx->u_data_size, 10)))
        return res;

    if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
        return res;

    output_plane(&ctx->planes[0], ctx->buf_sel,
                 frame->data[0], frame->linesize[0],
                 avctx->height);
    output_plane(&ctx->planes[1], ctx->buf_sel,
                 frame->data[1], frame->linesize[1],
                 (avctx->height + 3) >> 2);
    output_plane(&ctx->planes[2], ctx->buf_sel,
                 frame->data[2], frame->linesize[2],
                 (avctx->height + 3) >> 2);

    *got_frame = 1;

    return buf_size;
}


static av_cold int decode_close(AVCodecContext *avctx)
{
    free_frame_buffers(avctx->priv_data);

    return 0;
}

AVCodec ff_indeo3_decoder = {
    .name           = "indeo3",
    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_INDEO3,
    .priv_data_size = sizeof(Indeo3DecodeContext),
    .init           = decode_init,
    .close          = decode_close,
    .decode         = decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
};
