/*
 * Indeo Video Interactive v4 compatible decoder
 * Copyright (c) 2009-2011 Maxim Poliakovski
 *
 * This file is part of Libav.
 *
 * Libav 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.
 *
 * Libav 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 Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Indeo Video Interactive version 4 decoder
 *
 * Indeo 4 data is usually transported within .avi or .mov files.
 * Known FOURCCs: 'IV41'
 */

#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "get_bits.h"
#include "ivi_dsp.h"
#include "ivi_common.h"
#include "indeo4data.h"

/**
 *  Indeo 4 frame types.
 */
enum {
    FRAMETYPE_INTRA       = 0,
    FRAMETYPE_INTRA1      = 1,  ///< intra frame with slightly different bitstream coding
    FRAMETYPE_INTER       = 2,  ///< non-droppable P-frame
    FRAMETYPE_BIDIR       = 3,  ///< bidirectional frame
    FRAMETYPE_INTER_NOREF = 4,  ///< droppable P-frame
    FRAMETYPE_NULL_FIRST  = 5,  ///< empty frame with no data
    FRAMETYPE_NULL_LAST   = 6   ///< empty frame with no data
};

#define IVI4_PIC_SIZE_ESC   7


static const struct {
    InvTransformPtr *inv_trans;
    DCTransformPtr  *dc_trans;
    int             is_2d_trans;
} transforms[18] = {
    { ff_ivi_inverse_haar_8x8,  ff_ivi_dc_haar_2d,       1 },
    { ff_ivi_row_haar8,         ff_ivi_dc_haar_2d,       0 },
    { ff_ivi_col_haar8,         ff_ivi_dc_haar_2d,       0 },
    { ff_ivi_put_pixels_8x8,    ff_ivi_put_dc_pixel_8x8, 1 },
    { ff_ivi_inverse_slant_8x8, ff_ivi_dc_slant_2d,      1 },
    { ff_ivi_row_slant8,        ff_ivi_dc_row_slant,     1 },
    { ff_ivi_col_slant8,        ff_ivi_dc_col_slant,     1 },
    { NULL, NULL, 0 }, /* inverse DCT 8x8 */
    { NULL, NULL, 0 }, /* inverse DCT 8x1 */
    { NULL, NULL, 0 }, /* inverse DCT 1x8 */
    { ff_ivi_inverse_haar_4x4,  ff_ivi_dc_haar_2d,       1 },
    { ff_ivi_inverse_slant_4x4, ff_ivi_dc_slant_2d,      1 },
    { NULL, NULL, 0 }, /* no transform 4x4 */
    { ff_ivi_row_haar4,         ff_ivi_dc_haar_2d,       0 },
    { ff_ivi_col_haar4,         ff_ivi_dc_haar_2d,       0 },
    { ff_ivi_row_slant4,        ff_ivi_dc_row_slant,     0 },
    { ff_ivi_col_slant4,        ff_ivi_dc_col_slant,     0 },
    { NULL, NULL, 0 }, /* inverse DCT 4x4 */
};

/**
 *  Decode subdivision of a plane.
 *  This is a simplified version that checks for two supported subdivisions:
 *  - 1 wavelet band  per plane, size factor 1:1, code pattern: 3
 *  - 4 wavelet bands per plane, size factor 1:4, code pattern: 2,3,3,3,3
 *  Anything else is either unsupported or corrupt.
 *
 *  @param[in,out] gb    the GetBit context
 *  @return        number of wavelet bands or 0 on error
 */
static int decode_plane_subdivision(GetBitContext *gb)
{
    int i;

    switch (get_bits(gb, 2)) {
    case 3:
        return 1;
    case 2:
        for (i = 0; i < 4; i++)
            if (get_bits(gb, 2) != 3)
                return 0;
        return 4;
    default:
        return 0;
    }
}

static inline int scale_tile_size(int def_size, int size_factor)
{
    return size_factor == 15 ? def_size : (size_factor + 1) << 5;
}

/**
 *  Decode Indeo 4 picture header.
 *
 *  @param[in,out] ctx       pointer to the decoder context
 *  @param[in]     avctx     pointer to the AVCodecContext
 *  @return        result code: 0 = OK, negative number = error
 */
static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
{
    int             pic_size_indx, i, p;
    IVIPicConfig    pic_conf;

    if (get_bits(&ctx->gb, 18) != 0x3FFF8) {
        av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
        return AVERROR_INVALIDDATA;
    }

    ctx->prev_frame_type = ctx->frame_type;
    ctx->frame_type      = get_bits(&ctx->gb, 3);
    if (ctx->frame_type == 7) {
        av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d\n", ctx->frame_type);
        return AVERROR_INVALIDDATA;
    }

#if IVI4_STREAM_ANALYSER
    if (ctx->frame_type == FRAMETYPE_BIDIR)
        ctx->has_b_frames = 1;
#endif

    ctx->transp_status = get_bits1(&ctx->gb);
#if IVI4_STREAM_ANALYSER
    if (ctx->transp_status) {
        ctx->has_transp = 1;
    }
#endif

    /* unknown bit: Mac decoder ignores this bit, XANIM returns error */
    if (get_bits1(&ctx->gb)) {
        av_log(avctx, AV_LOG_ERROR, "Sync bit is set!\n");
        return AVERROR_INVALIDDATA;
    }

    ctx->data_size = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 24) : 0;

    /* null frames don't contain anything else so we just return */
    if (ctx->frame_type >= FRAMETYPE_NULL_FIRST) {
        av_dlog(avctx, "Null frame encountered!\n");
        return 0;
    }

    /* Check key lock status. If enabled - ignore lock word.         */
    /* Usually we have to prompt the user for the password, but      */
    /* we don't do that because Indeo 4 videos can be decoded anyway */
    if (get_bits1(&ctx->gb)) {
        skip_bits_long(&ctx->gb, 32);
        av_dlog(avctx, "Password-protected clip!\n");
    }

    pic_size_indx = get_bits(&ctx->gb, 3);
    if (pic_size_indx == IVI4_PIC_SIZE_ESC) {
        pic_conf.pic_height = get_bits(&ctx->gb, 16);
        pic_conf.pic_width  = get_bits(&ctx->gb, 16);
    } else {
        pic_conf.pic_height = ivi4_common_pic_sizes[pic_size_indx * 2 + 1];
        pic_conf.pic_width  = ivi4_common_pic_sizes[pic_size_indx * 2    ];
    }

    /* Decode tile dimensions. */
    if (get_bits1(&ctx->gb)) {
        pic_conf.tile_height = scale_tile_size(pic_conf.pic_height, get_bits(&ctx->gb, 4));
        pic_conf.tile_width  = scale_tile_size(pic_conf.pic_width,  get_bits(&ctx->gb, 4));
#if IVI4_STREAM_ANALYSER
        ctx->uses_tiling = 1;
#endif
    } else {
        pic_conf.tile_height = pic_conf.pic_height;
        pic_conf.tile_width  = pic_conf.pic_width;
    }

    /* Decode chroma subsampling. We support only 4:4 aka YVU9. */
    if (get_bits(&ctx->gb, 2)) {
        av_log(avctx, AV_LOG_ERROR, "Only YVU9 picture format is supported!\n");
        return AVERROR_INVALIDDATA;
    }
    pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2;
    pic_conf.chroma_width  = (pic_conf.pic_width  + 3) >> 2;

    /* decode subdivision of the planes */
    pic_conf.luma_bands = decode_plane_subdivision(&ctx->gb);
    pic_conf.chroma_bands = 0;
    if (pic_conf.luma_bands)
        pic_conf.chroma_bands = decode_plane_subdivision(&ctx->gb);
    ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
    if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
        av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
               pic_conf.luma_bands, pic_conf.chroma_bands);
        return AVERROR_INVALIDDATA;
    }

    /* check if picture layout was changed and reallocate buffers */
    if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) {
        if (ff_ivi_init_planes(ctx->planes, &pic_conf)) {
            av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n");
            return AVERROR(ENOMEM);
        }

        ctx->pic_conf = pic_conf;

        /* set default macroblock/block dimensions */
        for (p = 0; p <= 2; p++) {
            for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) {
                ctx->planes[p].bands[i].mb_size  = !p ? (!ctx->is_scalable ? 16 : 8) : 4;
                ctx->planes[p].bands[i].blk_size = !p ? 8 : 4;
            }
        }

        if (ff_ivi_init_tiles(ctx->planes, ctx->pic_conf.tile_width,
                              ctx->pic_conf.tile_height)) {
            av_log(avctx, AV_LOG_ERROR,
                   "Couldn't reallocate internal structures!\n");
            return AVERROR(ENOMEM);
        }
    }

    ctx->frame_num = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 20) : 0;

    /* skip decTimeEst field if present */
    if (get_bits1(&ctx->gb))
        skip_bits(&ctx->gb, 8);

    /* decode macroblock and block huffman codebooks */
    if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_MB_HUFF,  &ctx->mb_vlc,  avctx) ||
        ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF, &ctx->blk_vlc, avctx))
        return AVERROR_INVALIDDATA;

    ctx->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8;

    ctx->in_imf = get_bits1(&ctx->gb);
    ctx->in_q   = get_bits1(&ctx->gb);

    ctx->pic_glob_quant = get_bits(&ctx->gb, 5);

    /* TODO: ignore this parameter if unused */
    ctx->unknown1 = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 0;

    ctx->checksum = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 16) : 0;

    /* skip picture header extension if any */
    while (get_bits1(&ctx->gb)) {
        av_dlog(avctx, "Pic hdr extension encountered!\n");
        skip_bits(&ctx->gb, 8);
    }

    if (get_bits1(&ctx->gb)) {
        av_log(avctx, AV_LOG_ERROR, "Bad blocks bits encountered!\n");
    }

    align_get_bits(&ctx->gb);

    return 0;
}


/**
 *  Decode Indeo 4 band header.
 *
 *  @param[in,out] ctx       pointer to the decoder context
 *  @param[in,out] band      pointer to the band descriptor
 *  @param[in]     avctx     pointer to the AVCodecContext
 *  @return        result code: 0 = OK, negative number = error
 */
static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
                           AVCodecContext *avctx)
{
    int plane, band_num, indx, transform_id, scan_indx;
    int i;
    int quant_mat;

    plane    = get_bits(&ctx->gb, 2);
    band_num = get_bits(&ctx->gb, 4);
    if (band->plane != plane || band->band_num != band_num) {
        av_log(avctx, AV_LOG_ERROR, "Invalid band header sequence!\n");
        return AVERROR_INVALIDDATA;
    }

    band->is_empty = get_bits1(&ctx->gb);
    if (!band->is_empty) {
        /* skip header size
         * If header size is not given, header size is 4 bytes. */
        if (get_bits1(&ctx->gb))
            skip_bits(&ctx->gb, 16);

        band->is_halfpel = get_bits(&ctx->gb, 2);
        if (band->is_halfpel >= 2) {
            av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported mv resolution: %d!\n",
                   band->is_halfpel);
            return AVERROR_INVALIDDATA;
        }
#if IVI4_STREAM_ANALYSER
        if (!band->is_halfpel)
            ctx->uses_fullpel = 1;
#endif

        band->checksum_present = get_bits1(&ctx->gb);
        if (band->checksum_present)
            band->checksum = get_bits(&ctx->gb, 16);

        indx = get_bits(&ctx->gb, 2);
        if (indx == 3) {
            av_log(avctx, AV_LOG_ERROR, "Invalid block size!\n");
            return AVERROR_INVALIDDATA;
        }
        band->mb_size  = 16 >> indx;
        band->blk_size = 8 >> (indx >> 1);

        band->inherit_mv     = get_bits1(&ctx->gb);
        band->inherit_qdelta = get_bits1(&ctx->gb);

        band->glob_quant = get_bits(&ctx->gb, 5);

        if (!get_bits1(&ctx->gb) || ctx->frame_type == FRAMETYPE_INTRA) {
            transform_id = get_bits(&ctx->gb, 5);
            if (transform_id >= FF_ARRAY_ELEMS(transforms) ||
                !transforms[transform_id].inv_trans) {
                avpriv_request_sample(avctx, "Transform %d", transform_id);
                return AVERROR_PATCHWELCOME;
            }
            if ((transform_id >= 7 && transform_id <= 9) ||
                 transform_id == 17) {
                avpriv_request_sample(avctx, "DCT transform");
                return AVERROR_PATCHWELCOME;
            }

            if (transform_id < 10 && band->blk_size < 8) {
                av_log(avctx, AV_LOG_ERROR, "wrong transform size!\n");
                return AVERROR_INVALIDDATA;
            }
#if IVI4_STREAM_ANALYSER
            if ((transform_id >= 0 && transform_id <= 2) || transform_id == 10)
                ctx->uses_haar = 1;
#endif

            band->inv_transform = transforms[transform_id].inv_trans;
            band->dc_transform  = transforms[transform_id].dc_trans;
            band->is_2d_trans   = transforms[transform_id].is_2d_trans;
            band->transform_size= (transform_id < 10) ? 8 : 4;

            scan_indx = get_bits(&ctx->gb, 4);
            if ((scan_indx>4 && scan_indx<10) != (band->blk_size==4)) {
                av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
                return AVERROR_INVALIDDATA;
            }
            if (scan_indx == 15) {
                av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n");
                return AVERROR_INVALIDDATA;
            }
            band->scan = scan_index_to_tab[scan_indx];
            band->scan_size = band->blk_size;

            quant_mat = get_bits(&ctx->gb, 5);
            if (quant_mat == 31) {
                av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
                return AVERROR_INVALIDDATA;
            }
            if (quant_mat > 21) {
                av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n");
                return AVERROR_INVALIDDATA;
            }
            band->quant_mat = quant_mat;
        }
        if (quant_index_to_tab[band->quant_mat] > 4 && band->blk_size == 4) {
            av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix for 4x4 block encountered!\n");
            band->quant_mat = 0;
            return AVERROR_INVALIDDATA;
        }
        if (band->scan_size != band->blk_size) {
            av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
            return AVERROR_INVALIDDATA;
        }
        if (band->transform_size == 8 && band->blk_size < 8) {
            av_log(avctx, AV_LOG_ERROR, "mismatching transform_size!\n");
            return AVERROR_INVALIDDATA;
        }

        /* decode block huffman codebook */
        if (!get_bits1(&ctx->gb))
            band->blk_vlc.tab = ctx->blk_vlc.tab;
        else
            if (ff_ivi_dec_huff_desc(&ctx->gb, 1, IVI_BLK_HUFF,
                                     &band->blk_vlc, avctx))
                return AVERROR_INVALIDDATA;

        /* select appropriate rvmap table for this band */
        band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8;

        /* decode rvmap probability corrections if any */
        band->num_corr = 0; /* there is no corrections */
        if (get_bits1(&ctx->gb)) {
            band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */
            if (band->num_corr > 61) {
                av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n",
                       band->num_corr);
                return AVERROR_INVALIDDATA;
            }

            /* read correction pairs */
            for (i = 0; i < band->num_corr * 2; i++)
                band->corr[i] = get_bits(&ctx->gb, 8);
        }
    }

    if (band->blk_size == 8) {
        band->intra_base = &ivi4_quant_8x8_intra[quant_index_to_tab[band->quant_mat]][0];
        band->inter_base = &ivi4_quant_8x8_inter[quant_index_to_tab[band->quant_mat]][0];
    } else {
        band->intra_base = &ivi4_quant_4x4_intra[quant_index_to_tab[band->quant_mat]][0];
        band->inter_base = &ivi4_quant_4x4_inter[quant_index_to_tab[band->quant_mat]][0];
    }

    /* Indeo 4 doesn't use scale tables */
    band->intra_scale = NULL;
    band->inter_scale = NULL;

    align_get_bits(&ctx->gb);

    if (!band->scan) {
        av_log(avctx, AV_LOG_ERROR, "band->scan not set\n");
        return AVERROR_INVALIDDATA;
    }

    return 0;
}


/**
 *  Decode information (block type, cbp, quant delta, motion vector)
 *  for all macroblocks in the current tile.
 *
 *  @param[in,out] ctx       pointer to the decoder context
 *  @param[in,out] band      pointer to the band descriptor
 *  @param[in,out] tile      pointer to the tile descriptor
 *  @param[in]     avctx     pointer to the AVCodecContext
 *  @return        result code: 0 = OK, negative number = error
 */
static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band,
                          IVITile *tile, AVCodecContext *avctx)
{
    int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
                mv_scale, mb_type_bits, s;
    IVIMbInfo   *mb, *ref_mb;
    int         row_offset = band->mb_size * band->pitch;

    mb     = tile->mbs;
    ref_mb = tile->ref_mbs;
    offs   = tile->ypos * band->pitch + tile->xpos;

    blks_per_mb  = band->mb_size   != band->blk_size  ? 4 : 1;
    mb_type_bits = ctx->frame_type == FRAMETYPE_BIDIR ? 2 : 1;

    /* scale factor for motion vectors */
    mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
    mv_x = mv_y = 0;

    if (((tile->width + band->mb_size-1)/band->mb_size) * ((tile->height + band->mb_size-1)/band->mb_size) != tile->num_MBs) {
        av_log(avctx, AV_LOG_ERROR, "num_MBs mismatch %d %d %d %d\n", tile->width, tile->height, band->mb_size, tile->num_MBs);
        return -1;
    }

    for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) {
        mb_offset = offs;

        for (x = tile->xpos; x < tile->xpos + tile->width; x += band->mb_size) {
            mb->xpos     = x;
            mb->ypos     = y;
            mb->buf_offs = mb_offset;

            if (get_bits1(&ctx->gb)) {
                if (ctx->frame_type == FRAMETYPE_INTRA) {
                    av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");
                    return AVERROR_INVALIDDATA;
                }
                mb->type = 1; /* empty macroblocks are always INTER */
                mb->cbp  = 0; /* all blocks are empty */

                mb->q_delta = 0;
                if (!band->plane && !band->band_num && ctx->in_q) {
                    mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
                                           IVI_VLC_BITS, 1);
                    mb->q_delta = IVI_TOSIGNED(mb->q_delta);
                }

                mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
                if (band->inherit_mv && ref_mb) {
                    /* motion vector inheritance */
                    if (mv_scale) {
                        mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
                        mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
                    } else {
                        mb->mv_x = ref_mb->mv_x;
                        mb->mv_y = ref_mb->mv_y;
                    }
                }
            } else {
                if (band->inherit_mv && ref_mb) {
                    mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
                } else if (ctx->frame_type == FRAMETYPE_INTRA ||
                           ctx->frame_type == FRAMETYPE_INTRA1) {
                    mb->type = 0; /* mb_type is always INTRA for intra-frames */
                } else {
                    mb->type = get_bits(&ctx->gb, mb_type_bits);
                }

                mb->cbp = get_bits(&ctx->gb, blks_per_mb);

                mb->q_delta = 0;
                if (band->inherit_qdelta) {
                    if (ref_mb) mb->q_delta = ref_mb->q_delta;
                } else if (mb->cbp || (!band->plane && !band->band_num &&
                           ctx->in_q)) {
                    mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
                                           IVI_VLC_BITS, 1);
                    mb->q_delta = IVI_TOSIGNED(mb->q_delta);
                }

                if (!mb->type) {
                    mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
                } else {
                    if (band->inherit_mv && ref_mb) {
                        /* motion vector inheritance */
                        if (mv_scale) {
                            mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
                            mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);
                        } else {
                            mb->mv_x = ref_mb->mv_x;
                            mb->mv_y = ref_mb->mv_y;
                        }
                    } else {
                        /* decode motion vector deltas */
                        mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
                                            IVI_VLC_BITS, 1);
                        mv_y += IVI_TOSIGNED(mv_delta);
                        mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,
                                            IVI_VLC_BITS, 1);
                        mv_x += IVI_TOSIGNED(mv_delta);
                        mb->mv_x = mv_x;
                        mb->mv_y = mv_y;
                    }
                }
            }

            s= band->is_halfpel;
            if (mb->type)
            if ( x +  (mb->mv_x   >>s) +                 (y+               (mb->mv_y   >>s))*band->pitch < 0 ||
                 x + ((mb->mv_x+s)>>s) + band->mb_size - 1
                   + (y+band->mb_size - 1 +((mb->mv_y+s)>>s))*band->pitch > band->bufsize -1) {
                av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mb->mv_x, y*s + mb->mv_y);
                return AVERROR_INVALIDDATA;
            }

            mb++;
            if (ref_mb)
                ref_mb++;
            mb_offset += band->mb_size;
        }

        offs += row_offset;
    }

    align_get_bits(&ctx->gb);

    return 0;
}


/**
 *  Rearrange decoding and reference buffers.
 *
 *  @param[in,out] ctx       pointer to the decoder context
 */
static void switch_buffers(IVI45DecContext *ctx)
{
    switch (ctx->prev_frame_type) {
    case FRAMETYPE_INTRA:
    case FRAMETYPE_INTRA1:
    case FRAMETYPE_INTER:
        ctx->buf_switch ^= 1;
        ctx->dst_buf     = ctx->buf_switch;
        ctx->ref_buf     = ctx->buf_switch ^ 1;
        break;
    case FRAMETYPE_INTER_NOREF:
        break;
    }

    switch (ctx->frame_type) {
    case FRAMETYPE_INTRA:
    case FRAMETYPE_INTRA1:
        ctx->buf_switch = 0;
        /* FALLTHROUGH */
    case FRAMETYPE_INTER:
        ctx->dst_buf = ctx->buf_switch;
        ctx->ref_buf = ctx->buf_switch ^ 1;
        break;
    case FRAMETYPE_INTER_NOREF:
    case FRAMETYPE_NULL_FIRST:
    case FRAMETYPE_NULL_LAST:
        break;
    }
}


static int is_nonnull_frame(IVI45DecContext *ctx)
{
    return ctx->frame_type < FRAMETYPE_NULL_FIRST;
}


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

    ff_ivi_init_static_vlc();

    /* copy rvmap tables in our context so we can apply changes to them */
    memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));

    /* Force allocation of the internal buffers */
    /* during picture header decoding.          */
    ctx->pic_conf.pic_width  = 0;
    ctx->pic_conf.pic_height = 0;

    avctx->pix_fmt = AV_PIX_FMT_YUV410P;

    ctx->decode_pic_hdr   = decode_pic_hdr;
    ctx->decode_band_hdr  = decode_band_hdr;
    ctx->decode_mb_info   = decode_mb_info;
    ctx->switch_buffers   = switch_buffers;
    ctx->is_nonnull_frame = is_nonnull_frame;

    return 0;
}


AVCodec ff_indeo4_decoder = {
    .name           = "indeo4",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_INDEO4,
    .priv_data_size = sizeof(IVI45DecContext),
    .init           = decode_init,
    .close          = ff_ivi_decode_close,
    .decode         = ff_ivi_decode_frame,
    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
    .capabilities   = CODEC_CAP_DR1,
};
