/* * Bink video decoder * Copyright (c) 2009 Konstantin Shishkov * Copyright (C) 2011 Peter Ross <pross@xvid.org> * * 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 */ #include "libavutil/attributes.h"#include "libavutil/emms.h"#include "libavutil/imgutils.h"#include "libavutil/mem.h"#include "libavutil/mem_internal.h"#include "libavutil/thread.h" #define BITSTREAM_READER_LE#include "avcodec.h"#include "binkdata.h"#include "binkdsp.h"#include "blockdsp.h"#include "codec_internal.h"#include "decode.h"#include "get_bits.h"#include "hpeldsp.h" #define BINK_FLAG_ALPHA 0x00100000#define BINK_FLAG_GRAY 0x00020000 static VLC bink_trees[16]; /** * IDs for different data types used in old version of Bink video codec */enum OldSources { BINKB_SRC_BLOCK_TYPES = 0, ///< 8x8 block types BINKB_SRC_COLORS, ///< pixel values used for different block types BINKB_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill BINKB_SRC_X_OFF, ///< X components of motion value BINKB_SRC_Y_OFF, ///< Y components of motion value BINKB_SRC_INTRA_DC, ///< DC values for intrablocks with DCT BINKB_SRC_INTER_DC, ///< DC values for interblocks with DCT BINKB_SRC_INTRA_Q, ///< quantizer values for intrablocks with DCT BINKB_SRC_INTER_Q, ///< quantizer values for interblocks with DCT BINKB_SRC_INTER_COEFS, ///< number of coefficients for residue blocks BINKB_NB_SRC}; static const uint8_t binkb_bundle_sizes[BINKB_NB_SRC] = { 4, 8, 8, 5, 5, 11, 11, 4, 4, 7}; static const uint8_t binkb_bundle_signed[BINKB_NB_SRC] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0}; static int32_t binkb_intra_quant[16][64];static int32_t binkb_inter_quant[16][64]; /** * IDs for different data types used in Bink video codec */enum Sources { BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types) BINK_SRC_COLORS, ///< pixel values used for different block types BINK_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill BINK_SRC_X_OFF, ///< X components of motion value BINK_SRC_Y_OFF, ///< Y components of motion value BINK_SRC_INTRA_DC, ///< DC values for intrablocks with DCT BINK_SRC_INTER_DC, ///< DC values for interblocks with DCT BINK_SRC_RUN, ///< run lengths for special fill block BINK_NB_SRC}; /** * data needed to decode 4-bit Huffman-coded value */typedef struct Tree { int vlc_num; ///< tree number (in bink_trees[]) uint8_t syms[16]; ///< leaf value to symbol mapping} Tree; #define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ bink_trees[(tree).vlc_num].bits, 1)] /** * data structure used for decoding single Bink data type */typedef struct Bundle { int len; ///< length of number of entries to decode (in bits) Tree tree; ///< Huffman tree-related data uint8_t *data; ///< buffer for decoded symbols uint8_t *data_end; ///< buffer end uint8_t *cur_dec; ///< pointer to the not yet decoded part of the buffer uint8_t *cur_ptr; ///< pointer to the data that is not read from buffer yet} Bundle; /* * Decoder context */typedef struct BinkContext { AVCodecContext *avctx; BlockDSPContext bdsp; op_pixels_func put_pixels_tab; BinkDSPContext binkdsp; AVFrame *last; int version; ///< internal Bink file version int has_alpha; int swap_planes; unsigned frame_num; Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type int col_lastval; ///< value of last decoded high nibble in "colours" data type} BinkContext; /** * Bink video block types */enum BlockTypes { SKIP_BLOCK = 0, ///< skipped block SCALED_BLOCK, ///< block has size 16x16 MOTION_BLOCK, ///< block is copied from previous frame with some offset RUN_BLOCK, ///< block is composed from runs of colours with custom scan order RESIDUE_BLOCK, ///< motion block with some difference added INTRA_BLOCK, ///< intra DCT block FILL_BLOCK, ///< block is filled with single colour INTER_BLOCK, ///< motion block with DCT applied to the difference PATTERN_BLOCK, ///< block is filled with two colours following custom pattern RAW_BLOCK, ///< uncoded 8x8 block}; /** * Initialize length in all bundles. * * @param c decoder context * @param width plane width * @param bw plane width in 8x8 blocks */static void init_lengths(BinkContext *c, int width, int bw){ width = FFALIGN(width, 8); c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1; c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1; c->bundle[BINK_SRC_COLORS].len = av_log2(bw*64 + 511) + 1; c->bundle[BINK_SRC_INTRA_DC].len = c->bundle[BINK_SRC_INTER_DC].len = c->bundle[BINK_SRC_X_OFF].len = c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1; c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1; c->bundle[BINK_SRC_RUN].len = av_log2(bw*48 + 511) + 1;} /** * Allocate memory for bundles. * * @param c decoder context */static av_cold int init_bundles(BinkContext *c){ int bw, bh, blocks; uint8_t *tmp; int i; bw = (c->avctx->width + 7) >> 3; bh = (c->avctx->height + 7) >> 3; blocks = bw * bh; tmp = av_calloc(blocks, 64 * BINKB_NB_SRC); if (!tmp) return AVERROR(ENOMEM); for (i = 0; i < BINKB_NB_SRC; i++) { c->bundle[i].data = tmp; tmp += blocks * 64; c->bundle[i].data_end = tmp; } return 0;} /** * Free memory used by bundles. * * @param c decoder context */static av_cold void free_bundles(BinkContext *c){ av_freep(&c->bundle[0].data);} /** * Merge two consequent lists of equal size depending on bits read. * * @param gb context for reading bits * @param dst buffer where merged list will be written to * @param src pointer to the head of the first list (the second lists starts at src+size) * @param size input lists size */static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size){ uint8_t *src2 = src + size; int size2 = size; do { if (!get_bits1(gb)) { *dst++ = *src++; size--; } else { *dst++ = *src2++; size2--; } } while (size && size2); while (size--) *dst++ = *src++; while (size2--) *dst++ = *src2++;} /** * Read information about Huffman tree used to decode data. * * @param gb context for reading bits * @param tree pointer for storing tree data */static int read_tree(GetBitContext *gb, Tree *tree){ uint8_t tmp1[16] = { 0 }, tmp2[16], *in = tmp1, *out = tmp2; int i, t, len; if (get_bits_left(gb) < 4) return AVERROR_INVALIDDATA; tree->vlc_num = get_bits(gb, 4); if (!tree->vlc_num) { for (i = 0; i < 16; i++) tree->syms[i] = i; return 0; } if (get_bits1(gb)) { len = get_bits(gb, 3); for (i = 0; i <= len; i++) { tree->syms[i] = get_bits(gb, 4); tmp1[tree->syms[i]] = 1; } for (i = 0; i < 16 && len < 16 - 1; i++) if (!tmp1[i]) tree->syms[++len] = i; } else { len = get_bits(gb, 2); for (i = 0; i < 16; i++) in[i] = i; for (i = 0; i <= len; i++) { int size = 1 << i; for (t = 0; t < 16; t += size << 1) merge(gb, out + t, in + t, size); FFSWAP(uint8_t*, in, out); } memcpy(tree->syms, in, 16); } return 0;} /** * Prepare bundle for decoding data. * * @param gb context for reading bits * @param c decoder context * @param bundle_num number of the bundle to initialize */static int read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num){ int i; if (bundle_num == BINK_SRC_COLORS) { for (i = 0; i < 16; i++) { int ret = read_tree(gb, &c->col_high[i]); if (ret < 0) return ret; } c->col_lastval = 0; } if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) { int ret = read_tree(gb, &c->bundle[bundle_num].tree); if (ret < 0) return ret; } c->bundle[bundle_num].cur_dec = c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; return 0;} /** * common check before starting decoding bundle data * * @param gb context for reading bits * @param b bundle * @param t variable where number of elements to decode will be stored */#define CHECK_READ_VAL(gb, b, t) \ if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ return 0; \ t = get_bits(gb, b->len); \ if (!t) { \ b->cur_dec = NULL; \ return 0; \ } \ static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b){ int t, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { v = get_bits(gb, 4); memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) *b->cur_dec++ = GET_HUFF(gb, b->tree); } return 0;} static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b){ int t, sign, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { v = get_bits(gb, 4); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } *b->cur_dec++ = v; } } return 0;} static const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b){ BinkContext * const c = avctx->priv_data; int t, v; int last = 0; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); if (c->version == 'k') { t ^= 0xBBu; if (t == 0) { b->cur_dec = NULL; return 0; } } dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { v = get_bits(gb, 4); memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v < 12) { last = v; *b->cur_dec++ = v; } else { int run = bink_rlelens[v - 12]; if (dec_end - b->cur_dec < run) return AVERROR_INVALIDDATA; memset(b->cur_dec, last, run); b->cur_dec += run; } } } return 0;} static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b){ int t, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); return AVERROR_INVALIDDATA; } while (b->cur_dec < dec_end) { if (get_bits_left(gb) < 2) return AVERROR_INVALIDDATA; v = GET_HUFF(gb, b->tree); v |= GET_HUFF(gb, b->tree) << 4; *b->cur_dec++ = v; } return 0;} static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c){ int t, sign, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); v = GET_HUFF(gb, b->tree); v = (c->col_lastval << 4) | v; if (c->version < 'i') { sign = ((int8_t) v) >> 7; v = ((v & 0x7F) ^ sign) - sign; v += 0x80; } memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { if (get_bits_left(gb) < 2) return AVERROR_INVALIDDATA; c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); v = GET_HUFF(gb, b->tree); v = (c->col_lastval << 4) | v; if (c->version < 'i') { sign = ((int8_t) v) >> 7; v = ((v & 0x7F) ^ sign) - sign; v += 0x80; } *b->cur_dec++ = v; } } return 0;} Lines 1–500 of 1433. Load more
/* * Bink video decoder * Copyright (c) 2009 Konstantin Shishkov * Copyright (C) 2011 Peter Ross <pross@xvid.org> * * 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 */ #include "libavutil/attributes.h" #include "libavutil/emms.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "libavutil/mem_internal.h" #include "libavutil/thread.h" #define BITSTREAM_READER_LE #include "avcodec.h" #include "binkdata.h" #include "binkdsp.h" #include "blockdsp.h" #include "codec_internal.h" #include "decode.h" #include "get_bits.h" #include "hpeldsp.h" #define BINK_FLAG_ALPHA 0x00100000 #define BINK_FLAG_GRAY 0x00020000 static VLC bink_trees[16]; /** * IDs for different data types used in old version of Bink video codec */ enum OldSources { BINKB_SRC_BLOCK_TYPES = 0, ///< 8x8 block types BINKB_SRC_COLORS, ///< pixel values used for different block types BINKB_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill BINKB_SRC_X_OFF, ///< X components of motion value BINKB_SRC_Y_OFF, ///< Y components of motion value BINKB_SRC_INTRA_DC, ///< DC values for intrablocks with DCT BINKB_SRC_INTER_DC, ///< DC values for interblocks with DCT BINKB_SRC_INTRA_Q, ///< quantizer values for intrablocks with DCT BINKB_SRC_INTER_Q, ///< quantizer values for interblocks with DCT BINKB_SRC_INTER_COEFS, ///< number of coefficients for residue blocks BINKB_NB_SRC }; static const uint8_t binkb_bundle_sizes[BINKB_NB_SRC] = { 4, 8, 8, 5, 5, 11, 11, 4, 4, 7 }; static const uint8_t binkb_bundle_signed[BINKB_NB_SRC] = { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 }; static int32_t binkb_intra_quant[16][64]; static int32_t binkb_inter_quant[16][64]; /** * IDs for different data types used in Bink video codec */ enum Sources { BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types) BINK_SRC_COLORS, ///< pixel values used for different block types BINK_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill BINK_SRC_X_OFF, ///< X components of motion value BINK_SRC_Y_OFF, ///< Y components of motion value BINK_SRC_INTRA_DC, ///< DC values for intrablocks with DCT BINK_SRC_INTER_DC, ///< DC values for interblocks with DCT BINK_SRC_RUN, ///< run lengths for special fill block BINK_NB_SRC }; /** * data needed to decode 4-bit Huffman-coded value */ typedef struct Tree { int vlc_num; ///< tree number (in bink_trees[]) uint8_t syms[16]; ///< leaf value to symbol mapping } Tree; #define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ bink_trees[(tree).vlc_num].bits, 1)] /** * data structure used for decoding single Bink data type */ typedef struct Bundle { int len; ///< length of number of entries to decode (in bits) Tree tree; ///< Huffman tree-related data uint8_t *data; ///< buffer for decoded symbols uint8_t *data_end; ///< buffer end uint8_t *cur_dec; ///< pointer to the not yet decoded part of the buffer uint8_t *cur_ptr; ///< pointer to the data that is not read from buffer yet } Bundle; /* * Decoder context */ typedef struct BinkContext { AVCodecContext *avctx; BlockDSPContext bdsp; op_pixels_func put_pixels_tab; BinkDSPContext binkdsp; AVFrame *last; int version; ///< internal Bink file version int has_alpha; int swap_planes; unsigned frame_num; Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type int col_lastval; ///< value of last decoded high nibble in "colours" data type } BinkContext; /** * Bink video block types */ enum BlockTypes { SKIP_BLOCK = 0, ///< skipped block SCALED_BLOCK, ///< block has size 16x16 MOTION_BLOCK, ///< block is copied from previous frame with some offset RUN_BLOCK, ///< block is composed from runs of colours with custom scan order RESIDUE_BLOCK, ///< motion block with some difference added INTRA_BLOCK, ///< intra DCT block FILL_BLOCK, ///< block is filled with single colour INTER_BLOCK, ///< motion block with DCT applied to the difference PATTERN_BLOCK, ///< block is filled with two colours following custom pattern RAW_BLOCK, ///< uncoded 8x8 block }; /** * Initialize length in all bundles. * * @param c decoder context * @param width plane width * @param bw plane width in 8x8 blocks */ static void init_lengths(BinkContext *c, int width, int bw) { width = FFALIGN(width, 8); c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1; c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1; c->bundle[BINK_SRC_COLORS].len = av_log2(bw*64 + 511) + 1; c->bundle[BINK_SRC_INTRA_DC].len = c->bundle[BINK_SRC_INTER_DC].len = c->bundle[BINK_SRC_X_OFF].len = c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1; c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1; c->bundle[BINK_SRC_RUN].len = av_log2(bw*48 + 511) + 1; } /** * Allocate memory for bundles. * * @param c decoder context */ static av_cold int init_bundles(BinkContext *c) { int bw, bh, blocks; uint8_t *tmp; int i; bw = (c->avctx->width + 7) >> 3; bh = (c->avctx->height + 7) >> 3; blocks = bw * bh; tmp = av_calloc(blocks, 64 * BINKB_NB_SRC); if (!tmp) return AVERROR(ENOMEM); for (i = 0; i < BINKB_NB_SRC; i++) { c->bundle[i].data = tmp; tmp += blocks * 64; c->bundle[i].data_end = tmp; } return 0; } /** * Free memory used by bundles. * * @param c decoder context */ static av_cold void free_bundles(BinkContext *c) { av_freep(&c->bundle[0].data); } /** * Merge two consequent lists of equal size depending on bits read. * * @param gb context for reading bits * @param dst buffer where merged list will be written to * @param src pointer to the head of the first list (the second lists starts at src+size) * @param size input lists size */ static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) { uint8_t *src2 = src + size; int size2 = size; do { if (!get_bits1(gb)) { *dst++ = *src++; size--; } else { *dst++ = *src2++; size2--; } } while (size && size2); while (size--) *dst++ = *src++; while (size2--) *dst++ = *src2++; } /** * Read information about Huffman tree used to decode data. * * @param gb context for reading bits * @param tree pointer for storing tree data */ static int read_tree(GetBitContext *gb, Tree *tree) { uint8_t tmp1[16] = { 0 }, tmp2[16], *in = tmp1, *out = tmp2; int i, t, len; if (get_bits_left(gb) < 4) return AVERROR_INVALIDDATA; tree->vlc_num = get_bits(gb, 4); if (!tree->vlc_num) { for (i = 0; i < 16; i++) tree->syms[i] = i; return 0; } if (get_bits1(gb)) { len = get_bits(gb, 3); for (i = 0; i <= len; i++) { tree->syms[i] = get_bits(gb, 4); tmp1[tree->syms[i]] = 1; } for (i = 0; i < 16 && len < 16 - 1; i++) if (!tmp1[i]) tree->syms[++len] = i; } else { len = get_bits(gb, 2); for (i = 0; i < 16; i++) in[i] = i; for (i = 0; i <= len; i++) { int size = 1 << i; for (t = 0; t < 16; t += size << 1) merge(gb, out + t, in + t, size); FFSWAP(uint8_t*, in, out); } memcpy(tree->syms, in, 16); } return 0; } /** * Prepare bundle for decoding data. * * @param gb context for reading bits * @param c decoder context * @param bundle_num number of the bundle to initialize */ static int read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) { int i; if (bundle_num == BINK_SRC_COLORS) { for (i = 0; i < 16; i++) { int ret = read_tree(gb, &c->col_high[i]); if (ret < 0) return ret; } c->col_lastval = 0; } if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) { int ret = read_tree(gb, &c->bundle[bundle_num].tree); if (ret < 0) return ret; } c->bundle[bundle_num].cur_dec = c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; return 0; } /** * common check before starting decoding bundle data * * @param gb context for reading bits * @param b bundle * @param t variable where number of elements to decode will be stored */ #define CHECK_READ_VAL(gb, b, t) \ if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ return 0; \ t = get_bits(gb, b->len); \ if (!t) { \ b->cur_dec = NULL; \ return 0; \ } \ static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) { int t, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { v = get_bits(gb, 4); memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) *b->cur_dec++ = GET_HUFF(gb, b->tree); } return 0; } static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) { int t, sign, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { v = get_bits(gb, 4); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } *b->cur_dec++ = v; } } return 0; } static const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) { BinkContext * const c = avctx->priv_data; int t, v; int last = 0; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); if (c->version == 'k') { t ^= 0xBBu; if (t == 0) { b->cur_dec = NULL; return 0; } } dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { v = get_bits(gb, 4); memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v < 12) { last = v; *b->cur_dec++ = v; } else { int run = bink_rlelens[v - 12]; if (dec_end - b->cur_dec < run) return AVERROR_INVALIDDATA; memset(b->cur_dec, last, run); b->cur_dec += run; } } } return 0; } static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) { int t, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); return AVERROR_INVALIDDATA; } while (b->cur_dec < dec_end) { if (get_bits_left(gb) < 2) return AVERROR_INVALIDDATA; v = GET_HUFF(gb, b->tree); v |= GET_HUFF(gb, b->tree) << 4; *b->cur_dec++ = v; } return 0; } static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) { int t, sign, v; const uint8_t *dec_end; CHECK_READ_VAL(gb, b, t); dec_end = b->cur_dec + t; if (dec_end > b->data_end) { av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); return AVERROR_INVALIDDATA; } if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; if (get_bits1(gb)) { c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); v = GET_HUFF(gb, b->tree); v = (c->col_lastval << 4) | v; if (c->version < 'i') { sign = ((int8_t) v) >> 7; v = ((v & 0x7F) ^ sign) - sign; v += 0x80; } memset(b->cur_dec, v, t); b->cur_dec += t; } else { while (b->cur_dec < dec_end) { if (get_bits_left(gb) < 2) return AVERROR_INVALIDDATA; c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); v = GET_HUFF(gb, b->tree); v = (c->col_lastval << 4) | v; if (c->version < 'i') { sign = ((int8_t) v) >> 7; v = ((v & 0x7F) ^ sign) - sign; v += 0x80; } *b->cur_dec++ = v; } } return 0; }