/*
 * 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) ///< 8bit 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;
    uint32_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_pitch, chroma_pitch, luma_size, chroma_size;

    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 64bit 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,
                            int pitch, 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           row_offset, blk_row_offset, line_offset;

    row_offset     =  pitch;
    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,
                         int dst_pitch, int dst_height)
{
    int             x,y;
    const uint8_t   *src  = plane->pixels[buf_sel];
    uint32_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,
};
