/*
 * 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])
            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,
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
};
