aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-09-13 23:31:17 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-09-13 23:44:12 +0200
commitcac9877ed5150bb6feda64927bb327ee4698086a (patch)
tree17f92a30adce99c085b48a05f646f7cf13492952 /libavcodec
parent5ad01decef9993e4ec84c10e53a01f9f841c330b (diff)
parente0c3e0738757a92c2910bac83f2ef830b428ba11 (diff)
downloadffmpeg-cac9877ed5150bb6feda64927bb327ee4698086a.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: sws: implement MMX/SSE2/SSSE3/SSE4 versions for horizontal scaling. include stdint.h in adpcm_data.h mpeg12: reorder functions to avoid ugly forward declarations Fixed off by one packet size allocation in the smacker demuxer. Check for invalid packet size in the smacker demuxer. ape demuxer: fix segfault on memory allocation failure. xan: Add some buffer checks xan: Remove extra trailing newline Fixed size given to init_get_bits() in xan decoder. Conflicts: libavcodec/mpeg12.c libswscale/x86/swscale_template.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/adpcm_data.h2
-rw-r--r--libavcodec/mpeg12.c1059
-rw-r--r--libavcodec/xan.c44
3 files changed, 559 insertions, 546 deletions
diff --git a/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h
index 2aa7df5b64..97ab66c346 100644
--- a/libavcodec/adpcm_data.h
+++ b/libavcodec/adpcm_data.h
@@ -26,6 +26,8 @@
#ifndef AVCODEC_ADPCM_DATA_H
#define AVCODEC_ADPCM_DATA_H
+#include <stdint.h>
+
extern const int8_t ff_adpcm_index_table[16];
extern const int16_t ff_adpcm_step_table[89];
extern const int16_t ff_adpcm_AdaptationTable[];
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 6c4882671a..f40c704a79 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -50,533 +50,7 @@
#define MB_PTYPE_VLC_BITS 6
#define MB_BTYPE_VLC_BITS 6
-static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n);
-static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);
-static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
-static void exchange_uv(MpegEncContext *s);
-
-uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
-
-
-#define INIT_2D_VLC_RL(rl, static_size)\
-{\
- static RL_VLC_ELEM rl_vlc_table[static_size];\
- INIT_VLC_STATIC(&rl.vlc, TEX_VLC_BITS, rl.n + 2,\
- &rl.table_vlc[0][1], 4, 2,\
- &rl.table_vlc[0][0], 4, 2, static_size);\
-\
- rl.rl_vlc[0] = rl_vlc_table;\
- init_2d_vlc_rl(&rl);\
-}
-
-static void init_2d_vlc_rl(RLTable *rl)
-{
- int i;
-
- for (i = 0; i < rl->vlc.table_size; i++) {
- int code = rl->vlc.table[i][0];
- int len = rl->vlc.table[i][1];
- int level, run;
-
- if (len == 0) { // illegal code
- run = 65;
- level = MAX_LEVEL;
- } else if (len<0) { //more bits needed
- run = 0;
- level = code;
- } else {
- if (code == rl->n) { //esc
- run = 65;
- level = 0;
- } else if (code == rl->n+1) { //eob
- run = 0;
- level = 127;
- } else {
- run = rl->table_run [code] + 1;
- level = rl->table_level[code];
- }
- }
- rl->rl_vlc[0][i].len = len;
- rl->rl_vlc[0][i].level = level;
- rl->rl_vlc[0][i].run = run;
- }
-}
-
-void ff_mpeg12_common_init(MpegEncContext *s)
-{
-
- s->y_dc_scale_table =
- s->c_dc_scale_table = ff_mpeg2_dc_scale_table[s->intra_dc_precision];
-
-}
-
-void ff_mpeg1_clean_buffers(MpegEncContext *s)
-{
- s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
- s->last_dc[1] = s->last_dc[0];
- s->last_dc[2] = s->last_dc[0];
- memset(s->last_mv, 0, sizeof(s->last_mv));
-}
-
-
-/******************************************/
-/* decoding */
-
-VLC ff_dc_lum_vlc;
-VLC ff_dc_chroma_vlc;
-
static VLC mv_vlc;
-static VLC mbincr_vlc;
-static VLC mb_ptype_vlc;
-static VLC mb_btype_vlc;
-static VLC mb_pat_vlc;
-
-av_cold void ff_mpeg12_init_vlcs(void)
-{
- static int done = 0;
-
- if (!done) {
- done = 1;
-
- INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12,
- ff_mpeg12_vlc_dc_lum_bits, 1, 1,
- ff_mpeg12_vlc_dc_lum_code, 2, 2, 512);
- INIT_VLC_STATIC(&ff_dc_chroma_vlc, DC_VLC_BITS, 12,
- ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
- ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514);
- INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17,
- &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1,
- &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518);
- INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36,
- &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1,
- &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538);
- INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64,
- &ff_mpeg12_mbPatTable[0][1], 2, 1,
- &ff_mpeg12_mbPatTable[0][0], 2, 1, 512);
-
- INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,
- &table_mb_ptype[0][1], 2, 1,
- &table_mb_ptype[0][0], 2, 1, 64);
- INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,
- &table_mb_btype[0][1], 2, 1,
- &table_mb_btype[0][0], 2, 1, 64);
- init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
- init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
-
- INIT_2D_VLC_RL(ff_rl_mpeg1, 680);
- INIT_2D_VLC_RL(ff_rl_mpeg2, 674);
- }
-}
-
-static inline int get_dmv(MpegEncContext *s)
-{
- if (get_bits1(&s->gb))
- return 1 - (get_bits1(&s->gb) << 1);
- else
- return 0;
-}
-
-static inline int get_qscale(MpegEncContext *s)
-{
- int qscale = get_bits(&s->gb, 5);
- if (s->q_scale_type) {
- return non_linear_qscale[qscale];
- } else {
- return qscale << 1;
- }
-}
-
-/* motion type (for MPEG-2) */
-#define MT_FIELD 1
-#define MT_FRAME 2
-#define MT_16X8 2
-#define MT_DMV 3
-
-static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64])
-{
- int i, j, k, cbp, val, mb_type, motion_type;
- const int mb_block_count = 4 + (1 << s->chroma_format);
-
- av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
-
- assert(s->mb_skipped == 0);
-
- if (s->mb_skip_run-- != 0) {
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- s->mb_skipped = 1;
- s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
- } else {
- int mb_type;
-
- if (s->mb_x)
- mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
- else
- mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
- if (IS_INTRA(mb_type))
- return -1;
-
- s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
- mb_type | MB_TYPE_SKIP;
-// assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
-
- if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
- s->mb_skipped = 1;
- }
-
- return 0;
- }
-
- switch (s->pict_type) {
- default:
- case AV_PICTURE_TYPE_I:
- if (get_bits1(&s->gb) == 0) {
- if (get_bits1(&s->gb) == 0) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
- } else {
- mb_type = MB_TYPE_INTRA;
- }
- break;
- case AV_PICTURE_TYPE_P:
- mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
- if (mb_type < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- mb_type = ptype2mb_type[mb_type];
- break;
- case AV_PICTURE_TYPE_B:
- mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
- if (mb_type < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- mb_type = btype2mb_type[mb_type];
- break;
- }
- av_dlog(s->avctx, "mb_type=%x\n", mb_type);
-// motion_type = 0; /* avoid warning */
- if (IS_INTRA(mb_type)) {
- s->dsp.clear_blocks(s->block[0]);
-
- if (!s->chroma_y_shift) {
- s->dsp.clear_blocks(s->block[6]);
- }
-
- /* compute DCT type */
- if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?
- !s->frame_pred_frame_dct) {
- s->interlaced_dct = get_bits1(&s->gb);
- }
-
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
-
- if (s->concealment_motion_vectors) {
- /* just parse them */
- if (s->picture_structure != PICT_FRAME)
- skip_bits1(&s->gb); /* field select */
-
- s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
- mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
- s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
- mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
-
- skip_bits1(&s->gb); /* marker */
- } else
- memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
- s->mb_intra = 1;
- // if 1, we memcpy blocks in xvmcvideo
- if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
- ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
- if (s->swap_uv) {
- exchange_uv(s);
- }
- }
-
- if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
- if (s->flags2 & CODEC_FLAG2_FAST) {
- for (i = 0; i < 6; i++) {
- mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
- }
- } else {
- for (i = 0; i < mb_block_count; i++) {
- if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
- return -1;
- }
- }
- } else {
- for (i = 0; i < 6; i++) {
- if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
- return -1;
- }
- }
- } else {
- if (mb_type & MB_TYPE_ZERO_MV) {
- assert(mb_type & MB_TYPE_CBP);
-
- s->mv_dir = MV_DIR_FORWARD;
- if (s->picture_structure == PICT_FRAME) {
- if (!s->frame_pred_frame_dct)
- s->interlaced_dct = get_bits1(&s->gb);
- s->mv_type = MV_TYPE_16X16;
- } else {
- s->mv_type = MV_TYPE_FIELD;
- mb_type |= MB_TYPE_INTERLACED;
- s->field_select[0][0] = s->picture_structure - 1;
- }
-
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
-
- s->last_mv[0][0][0] = 0;
- s->last_mv[0][0][1] = 0;
- s->last_mv[0][1][0] = 0;
- s->last_mv[0][1][1] = 0;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- } else {
- assert(mb_type & MB_TYPE_L0L1);
- // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
- /* get additional motion vector type */
- if (s->frame_pred_frame_dct)
- motion_type = MT_FRAME;
- else {
- motion_type = get_bits(&s->gb, 2);
- if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
- s->interlaced_dct = get_bits1(&s->gb);
- }
-
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
-
- /* motion vectors */
- s->mv_dir = (mb_type >> 13) & 3;
- av_dlog(s->avctx, "motion_type=%d\n", motion_type);
- switch (motion_type) {
- case MT_FRAME: /* or MT_16X8 */
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x16;
- s->mv_type = MV_TYPE_16X16;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- /* MT_FRAME */
- s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
- mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
- s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
- mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);
- /* full_pel: only for MPEG-1 */
- if (s->full_pel[i]) {
- s->mv[i][0][0] <<= 1;
- s->mv[i][0][1] <<= 1;
- }
- }
- }
- } else {
- mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
- s->mv_type = MV_TYPE_16X8;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- /* MT_16X8 */
- for (j = 0; j < 2; j++) {
- s->field_select[i][j] = get_bits1(&s->gb);
- for (k = 0; k < 2; k++) {
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
- s->last_mv[i][j][k]);
- s->last_mv[i][j][k] = val;
- s->mv[i][j][k] = val;
- }
- }
- }
- }
- }
- break;
- case MT_FIELD:
- if(s->progressive_sequence){
- av_log(s->avctx, AV_LOG_ERROR, "MT_FIELD in progressive_sequence\n");
- return -1;
- }
- s->mv_type = MV_TYPE_FIELD;
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- for (j = 0; j < 2; j++) {
- s->field_select[i][j] = get_bits1(&s->gb);
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
- s->last_mv[i][j][0]);
- s->last_mv[i][j][0] = val;
- s->mv[i][j][0] = val;
- av_dlog(s->avctx, "fmx=%d\n", val);
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][j][1] >> 1);
- s->last_mv[i][j][1] = val << 1;
- s->mv[i][j][1] = val;
- av_dlog(s->avctx, "fmy=%d\n", val);
- }
- }
- }
- } else {
- mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- s->field_select[i][0] = get_bits1(&s->gb);
- for (k = 0; k < 2; k++) {
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
- s->last_mv[i][0][k]);
- s->last_mv[i][0][k] = val;
- s->last_mv[i][1][k] = val;
- s->mv[i][0][k] = val;
- }
- }
- }
- }
- break;
- case MT_DMV:
- if(s->progressive_sequence){
- av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");
- return -1;
- }
- s->mv_type = MV_TYPE_DMV;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- int dmx, dmy, mx, my, m;
- const int my_shift = s->picture_structure == PICT_FRAME;
-
- mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
- s->last_mv[i][0][0]);
- s->last_mv[i][0][0] = mx;
- s->last_mv[i][1][0] = mx;
- dmx = get_dmv(s);
- my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][0][1] >> my_shift);
- dmy = get_dmv(s);
-
-
- s->last_mv[i][0][1] = my << my_shift;
- s->last_mv[i][1][1] = my << my_shift;
-
- s->mv[i][0][0] = mx;
- s->mv[i][0][1] = my;
- s->mv[i][1][0] = mx; // not used
- s->mv[i][1][1] = my; // not used
-
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
-
- // m = 1 + 2 * s->top_field_first;
- m = s->top_field_first ? 1 : 3;
-
- /* top -> top pred */
- s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
- s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
- m = 4 - m;
- s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
- s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
- } else {
- mb_type |= MB_TYPE_16x16;
-
- s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
- s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
- if (s->picture_structure == PICT_TOP_FIELD)
- s->mv[i][2][1]--;
- else
- s->mv[i][2][1]++;
- }
- }
- }
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- }
-
- s->mb_intra = 0;
- if (HAS_CBP(mb_type)) {
- s->dsp.clear_blocks(s->block[0]);
-
- cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
- if (mb_block_count > 6) {
- cbp <<= mb_block_count - 6;
- cbp |= get_bits(&s->gb, mb_block_count - 6);
- s->dsp.clear_blocks(s->block[6]);
- }
- if (cbp <= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- //if 1, we memcpy blocks in xvmcvideo
- if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
- ff_xvmc_pack_pblocks(s, cbp);
- if (s->swap_uv) {
- exchange_uv(s);
- }
- }
-
- if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
- if (s->flags2 & CODEC_FLAG2_FAST) {
- for (i = 0; i < 6; i++) {
- if (cbp & 32) {
- mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
- } else {
- s->block_last_index[i] = -1;
- }
- cbp += cbp;
- }
- } else {
- cbp <<= 12-mb_block_count;
-
- for (i = 0; i < mb_block_count; i++) {
- if (cbp & (1 << 11)) {
- if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
- return -1;
- } else {
- s->block_last_index[i] = -1;
- }
- cbp += cbp;
- }
- }
- } else {
- if (s->flags2 & CODEC_FLAG2_FAST) {
- for (i = 0; i < 6; i++) {
- if (cbp & 32) {
- mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
- } else {
- s->block_last_index[i] = -1;
- }
- cbp += cbp;
- }
- } else {
- for (i = 0; i < 6; i++) {
- if (cbp & 32) {
- if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
- return -1;
- } else {
- s->block_last_index[i] = -1;
- }
- cbp += cbp;
- }
- }
- }
- } else {
- for (i = 0; i < 12; i++)
- s->block_last_index[i] = -1;
- }
- }
-
- s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
-
- return 0;
-}
/* as H.263, but only 17 codes */
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
@@ -1119,6 +593,530 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc
return 0;
}
+uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
+
+#define INIT_2D_VLC_RL(rl, static_size)\
+{\
+ static RL_VLC_ELEM rl_vlc_table[static_size];\
+ INIT_VLC_STATIC(&rl.vlc, TEX_VLC_BITS, rl.n + 2,\
+ &rl.table_vlc[0][1], 4, 2,\
+ &rl.table_vlc[0][0], 4, 2, static_size);\
+\
+ rl.rl_vlc[0] = rl_vlc_table;\
+ init_2d_vlc_rl(&rl);\
+}
+
+static void init_2d_vlc_rl(RLTable *rl)
+{
+ int i;
+
+ for (i = 0; i < rl->vlc.table_size; i++) {
+ int code = rl->vlc.table[i][0];
+ int len = rl->vlc.table[i][1];
+ int level, run;
+
+ if (len == 0) { // illegal code
+ run = 65;
+ level = MAX_LEVEL;
+ } else if (len<0) { //more bits needed
+ run = 0;
+ level = code;
+ } else {
+ if (code == rl->n) { //esc
+ run = 65;
+ level = 0;
+ } else if (code == rl->n+1) { //eob
+ run = 0;
+ level = 127;
+ } else {
+ run = rl->table_run [code] + 1;
+ level = rl->table_level[code];
+ }
+ }
+ rl->rl_vlc[0][i].len = len;
+ rl->rl_vlc[0][i].level = level;
+ rl->rl_vlc[0][i].run = run;
+ }
+}
+
+void ff_mpeg12_common_init(MpegEncContext *s)
+{
+
+ s->y_dc_scale_table =
+ s->c_dc_scale_table = ff_mpeg2_dc_scale_table[s->intra_dc_precision];
+
+}
+
+void ff_mpeg1_clean_buffers(MpegEncContext *s)
+{
+ s->last_dc[0] = 1 << (7 + s->intra_dc_precision);
+ s->last_dc[1] = s->last_dc[0];
+ s->last_dc[2] = s->last_dc[0];
+ memset(s->last_mv, 0, sizeof(s->last_mv));
+}
+
+
+/******************************************/
+/* decoding */
+
+VLC ff_dc_lum_vlc;
+VLC ff_dc_chroma_vlc;
+
+static VLC mbincr_vlc;
+static VLC mb_ptype_vlc;
+static VLC mb_btype_vlc;
+static VLC mb_pat_vlc;
+
+av_cold void ff_mpeg12_init_vlcs(void)
+{
+ static int done = 0;
+
+ if (!done) {
+ done = 1;
+
+ INIT_VLC_STATIC(&ff_dc_lum_vlc, DC_VLC_BITS, 12,
+ ff_mpeg12_vlc_dc_lum_bits, 1, 1,
+ ff_mpeg12_vlc_dc_lum_code, 2, 2, 512);
+ INIT_VLC_STATIC(&ff_dc_chroma_vlc, DC_VLC_BITS, 12,
+ ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
+ ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514);
+ INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17,
+ &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1,
+ &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518);
+ INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36,
+ &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1,
+ &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538);
+ INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64,
+ &ff_mpeg12_mbPatTable[0][1], 2, 1,
+ &ff_mpeg12_mbPatTable[0][0], 2, 1, 512);
+
+ INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,
+ &table_mb_ptype[0][1], 2, 1,
+ &table_mb_ptype[0][0], 2, 1, 64);
+ INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,
+ &table_mb_btype[0][1], 2, 1,
+ &table_mb_btype[0][0], 2, 1, 64);
+ init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
+ init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
+
+ INIT_2D_VLC_RL(ff_rl_mpeg1, 680);
+ INIT_2D_VLC_RL(ff_rl_mpeg2, 674);
+ }
+}
+
+static inline int get_dmv(MpegEncContext *s)
+{
+ if (get_bits1(&s->gb))
+ return 1 - (get_bits1(&s->gb) << 1);
+ else
+ return 0;
+}
+
+static inline int get_qscale(MpegEncContext *s)
+{
+ int qscale = get_bits(&s->gb, 5);
+ if (s->q_scale_type) {
+ return non_linear_qscale[qscale];
+ } else {
+ return qscale << 1;
+ }
+}
+
+static void exchange_uv(MpegEncContext *s)
+{
+ DCTELEM (*tmp)[64];
+
+ tmp = s->pblocks[4];
+ s->pblocks[4] = s->pblocks[5];
+ s->pblocks[5] = tmp;
+}
+
+/* motion type (for MPEG-2) */
+#define MT_FIELD 1
+#define MT_FRAME 2
+#define MT_16X8 2
+#define MT_DMV 3
+
+static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64])
+{
+ int i, j, k, cbp, val, mb_type, motion_type;
+ const int mb_block_count = 4 + (1 << s->chroma_format);
+
+ av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
+
+ assert(s->mb_skipped == 0);
+
+ if (s->mb_skip_run-- != 0) {
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ s->mb_skipped = 1;
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+ } else {
+ int mb_type;
+
+ if (s->mb_x)
+ mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
+ else
+ mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
+ if (IS_INTRA(mb_type))
+ return -1;
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
+ mb_type | MB_TYPE_SKIP;
+// assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
+
+ if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
+ s->mb_skipped = 1;
+ }
+
+ return 0;
+ }
+
+ switch (s->pict_type) {
+ default:
+ case AV_PICTURE_TYPE_I:
+ if (get_bits1(&s->gb) == 0) {
+ if (get_bits1(&s->gb) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
+ } else {
+ mb_type = MB_TYPE_INTRA;
+ }
+ break;
+ case AV_PICTURE_TYPE_P:
+ mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mb_type = ptype2mb_type[mb_type];
+ break;
+ case AV_PICTURE_TYPE_B:
+ mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mb_type = btype2mb_type[mb_type];
+ break;
+ }
+ av_dlog(s->avctx, "mb_type=%x\n", mb_type);
+// motion_type = 0; /* avoid warning */
+ if (IS_INTRA(mb_type)) {
+ s->dsp.clear_blocks(s->block[0]);
+
+ if (!s->chroma_y_shift) {
+ s->dsp.clear_blocks(s->block[6]);
+ }
+
+ /* compute DCT type */
+ if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?
+ !s->frame_pred_frame_dct) {
+ s->interlaced_dct = get_bits1(&s->gb);
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ if (s->concealment_motion_vectors) {
+ /* just parse them */
+ if (s->picture_structure != PICT_FRAME)
+ skip_bits1(&s->gb); /* field select */
+
+ s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
+ mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
+ s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
+ mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
+
+ skip_bits1(&s->gb); /* marker */
+ } else
+ memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
+ s->mb_intra = 1;
+ // if 1, we memcpy blocks in xvmcvideo
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
+ ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
+ if (s->swap_uv) {
+ exchange_uv(s);
+ }
+ }
+
+ if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
+ if (s->flags2 & CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
+ }
+ } else {
+ for (i = 0; i < mb_block_count; i++) {
+ if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
+ return -1;
+ }
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
+ return -1;
+ }
+ }
+ } else {
+ if (mb_type & MB_TYPE_ZERO_MV) {
+ assert(mb_type & MB_TYPE_CBP);
+
+ s->mv_dir = MV_DIR_FORWARD;
+ if (s->picture_structure == PICT_FRAME) {
+ if (!s->frame_pred_frame_dct)
+ s->interlaced_dct = get_bits1(&s->gb);
+ s->mv_type = MV_TYPE_16X16;
+ } else {
+ s->mv_type = MV_TYPE_FIELD;
+ mb_type |= MB_TYPE_INTERLACED;
+ s->field_select[0][0] = s->picture_structure - 1;
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ s->last_mv[0][1][0] = 0;
+ s->last_mv[0][1][1] = 0;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ } else {
+ assert(mb_type & MB_TYPE_L0L1);
+ // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
+ /* get additional motion vector type */
+ if (s->frame_pred_frame_dct)
+ motion_type = MT_FRAME;
+ else {
+ motion_type = get_bits(&s->gb, 2);
+ if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
+ s->interlaced_dct = get_bits1(&s->gb);
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ /* motion vectors */
+ s->mv_dir = (mb_type >> 13) & 3;
+ av_dlog(s->avctx, "motion_type=%d\n", motion_type);
+ switch (motion_type) {
+ case MT_FRAME: /* or MT_16X8 */
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x16;
+ s->mv_type = MV_TYPE_16X16;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ /* MT_FRAME */
+ s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
+ mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
+ s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
+ mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);
+ /* full_pel: only for MPEG-1 */
+ if (s->full_pel[i]) {
+ s->mv[i][0][0] <<= 1;
+ s->mv[i][0][1] <<= 1;
+ }
+ }
+ }
+ } else {
+ mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+ s->mv_type = MV_TYPE_16X8;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ /* MT_16X8 */
+ for (j = 0; j < 2; j++) {
+ s->field_select[i][j] = get_bits1(&s->gb);
+ for (k = 0; k < 2; k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][j][k]);
+ s->last_mv[i][j][k] = val;
+ s->mv[i][j][k] = val;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case MT_FIELD:
+ if(s->progressive_sequence){
+ av_log(s->avctx, AV_LOG_ERROR, "MT_FIELD in progressive_sequence\n");
+ return -1;
+ }
+ s->mv_type = MV_TYPE_FIELD;
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ for (j = 0; j < 2; j++) {
+ s->field_select[i][j] = get_bits1(&s->gb);
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][j][0]);
+ s->last_mv[i][j][0] = val;
+ s->mv[i][j][0] = val;
+ av_dlog(s->avctx, "fmx=%d\n", val);
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][j][1] >> 1);
+ s->last_mv[i][j][1] = val << 1;
+ s->mv[i][j][1] = val;
+ av_dlog(s->avctx, "fmy=%d\n", val);
+ }
+ }
+ }
+ } else {
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ s->field_select[i][0] = get_bits1(&s->gb);
+ for (k = 0; k < 2; k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][0][k]);
+ s->last_mv[i][0][k] = val;
+ s->last_mv[i][1][k] = val;
+ s->mv[i][0][k] = val;
+ }
+ }
+ }
+ }
+ break;
+ case MT_DMV:
+ if(s->progressive_sequence){
+ av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");
+ return -1;
+ }
+ s->mv_type = MV_TYPE_DMV;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ int dmx, dmy, mx, my, m;
+ const int my_shift = s->picture_structure == PICT_FRAME;
+
+ mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][0][0]);
+ s->last_mv[i][0][0] = mx;
+ s->last_mv[i][1][0] = mx;
+ dmx = get_dmv(s);
+ my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][0][1] >> my_shift);
+ dmy = get_dmv(s);
+
+
+ s->last_mv[i][0][1] = my << my_shift;
+ s->last_mv[i][1][1] = my << my_shift;
+
+ s->mv[i][0][0] = mx;
+ s->mv[i][0][1] = my;
+ s->mv[i][1][0] = mx; // not used
+ s->mv[i][1][1] = my; // not used
+
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
+
+ // m = 1 + 2 * s->top_field_first;
+ m = s->top_field_first ? 1 : 3;
+
+ /* top -> top pred */
+ s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
+ m = 4 - m;
+ s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
+ } else {
+ mb_type |= MB_TYPE_16x16;
+
+ s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
+ s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
+ if (s->picture_structure == PICT_TOP_FIELD)
+ s->mv[i][2][1]--;
+ else
+ s->mv[i][2][1]++;
+ }
+ }
+ }
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ }
+
+ s->mb_intra = 0;
+ if (HAS_CBP(mb_type)) {
+ s->dsp.clear_blocks(s->block[0]);
+
+ cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
+ if (mb_block_count > 6) {
+ cbp <<= mb_block_count - 6;
+ cbp |= get_bits(&s->gb, mb_block_count - 6);
+ s->dsp.clear_blocks(s->block[6]);
+ }
+ if (cbp <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ //if 1, we memcpy blocks in xvmcvideo
+ if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
+ ff_xvmc_pack_pblocks(s, cbp);
+ if (s->swap_uv) {
+ exchange_uv(s);
+ }
+ }
+
+ if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
+ if (s->flags2 & CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ } else {
+ cbp <<= 12-mb_block_count;
+
+ for (i = 0; i < mb_block_count; i++) {
+ if (cbp & (1 << 11)) {
+ if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
+ return -1;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ }
+ } else {
+ if (s->flags2 & CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
+ return -1;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 12; i++)
+ s->block_last_index[i] = -1;
+ }
+ }
+
+ s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
+
+ return 0;
+}
+
typedef struct Mpeg1Context {
MpegEncContext mpeg_enc_ctx;
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
@@ -1610,15 +1608,6 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
av_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
}
-static void exchange_uv(MpegEncContext *s)
-{
- DCTELEM (*tmp)[64];
-
- tmp = s->pblocks[4];
- s->pblocks[4] = s->pblocks[5];
- s->pblocks[5] = tmp;
-}
-
static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
{
AVCodecContext *avctx = s->avctx;
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 598d1e1423..3e950f1466 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -97,17 +97,21 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
return 0;
}
-static int xan_huffman_decode(unsigned char *dest, const unsigned char *src,
- int dest_len)
+static int xan_huffman_decode(unsigned char *dest, int dest_len,
+ const unsigned char *src, int src_len)
{
unsigned char byte = *src++;
unsigned char ival = byte + 0x16;
const unsigned char * ptr = src + byte*2;
+ int ptr_len = src_len - 1 - byte*2;
unsigned char val = ival;
unsigned char *dest_end = dest + dest_len;
GetBitContext gb;
- init_get_bits(&gb, ptr, 0); // FIXME: no src size available
+ if (ptr_len < 0)
+ return AVERROR_INVALIDDATA;
+
+ init_get_bits(&gb, ptr, ptr_len * 8);
while ( val != 0x16 ) {
val = src[val - 0x17 + get_bits1(&gb) * byte];
@@ -246,7 +250,7 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s,
}
}
-static void xan_wc3_decode_frame(XanContext *s) {
+static int xan_wc3_decode_frame(XanContext *s) {
int width = s->avctx->width;
int height = s->avctx->height;
@@ -266,13 +270,30 @@ static void xan_wc3_decode_frame(XanContext *s) {
const unsigned char *size_segment;
const unsigned char *vector_segment;
const unsigned char *imagedata_segment;
+ int huffman_offset, size_offset, vector_offset, imagedata_offset;
+
+ if (s->size < 8)
+ return AVERROR_INVALIDDATA;
+
+ huffman_offset = AV_RL16(&s->buf[0]);
+ size_offset = AV_RL16(&s->buf[2]);
+ vector_offset = AV_RL16(&s->buf[4]);
+ imagedata_offset = AV_RL16(&s->buf[6]);
- huffman_segment = s->buf + AV_RL16(&s->buf[0]);
- size_segment = s->buf + AV_RL16(&s->buf[2]);
- vector_segment = s->buf + AV_RL16(&s->buf[4]);
- imagedata_segment = s->buf + AV_RL16(&s->buf[6]);
+ if (huffman_offset >= s->size ||
+ size_offset >= s->size ||
+ vector_offset >= s->size ||
+ imagedata_offset >= s->size)
+ return AVERROR_INVALIDDATA;
- xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size);
+ huffman_segment = s->buf + huffman_offset;
+ size_segment = s->buf + size_offset;
+ vector_segment = s->buf + vector_offset;
+ imagedata_segment = s->buf + imagedata_offset;
+
+ if (xan_huffman_decode(opcode_buffer, opcode_buffer_size,
+ huffman_segment, s->size - huffman_offset) < 0)
+ return AVERROR_INVALIDDATA;
if (imagedata_segment[0] == 2)
xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size);
@@ -358,6 +379,7 @@ static void xan_wc3_decode_frame(XanContext *s) {
y += (x + size) / width;
x = (x + size) % width;
}
+ return 0;
}
#if RUNTIME_GAMMA
@@ -519,7 +541,8 @@ static int xan_decode_frame(AVCodecContext *avctx,
s->buf = buf;
s->size = buf_size;
- xan_wc3_decode_frame(s);
+ if (xan_wc3_decode_frame(s) < 0)
+ return AVERROR_INVALIDDATA;
/* release the last frame if it is allocated */
if (s->last_frame.data[0])
@@ -563,4 +586,3 @@ AVCodec ff_xan_wc3_decoder = {
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
};
-