Merge remote-tracking branch 'qatar/release/9' into release/1.1
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 14 Mar 2013 03:27:35 +0000 (04:27 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 14 Mar 2013 03:27:35 +0000 (04:27 +0100)
* qatar/release/9:
  eamad: allocate a dummy reference frame when the real one is missing
  libmp3lame: use the correct remaining buffer size when flushing
  png: use av_mallocz_array() for the zlib zalloc function
  wmaprodec: require block_align to be set.
  ffv1: fix calculating slice dimensions for version 2
  xxan: fix invalid memory access in xan_decode_frame_type0()
  wmadec: require block_align to be set.
  ivi_common: do not call MC for intra frames when dc_transform is unset

Conflicts:
libavcodec/ffv1dec.c
libavcodec/ivi_common.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/eamad.c
libavcodec/libmp3lame.c
libavcodec/png.c
libavcodec/wmadec.c
libavcodec/wmaprodec.c
libavcodec/xxan.c

diff --combined libavcodec/eamad.c
@@@ -2,20 -2,20 +2,20 @@@
   * Electronic Arts Madcow Video Decoder
   * Copyright (c) 2007-2009 Peter Ross
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * 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 Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
  
@@@ -83,21 -83,15 +83,21 @@@ static inline void comp_block(MadContex
                                int j, int mv_x, int mv_y, int add)
  {
      if (j < 4) {
 +        unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
 +        if (offset >= (t->avctx->height - 7) * t->last_frame.linesize[0] - 7)
 +            return;
          comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
               t->frame.linesize[0],
 -             t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x,
 +             t->last_frame.data[0] + offset,
               t->last_frame.linesize[0], add);
      } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
          int index = j - 3;
 +        unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2);
 +        if (offset >= (t->avctx->height/2 - 7) * t->last_frame.linesize[index] - 7)
 +            return;
          comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8,
               t->frame.linesize[index],
 -             t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2),
 +             t->last_frame.data[index] + offset,
               t->last_frame.linesize[index], add);
      }
  }
@@@ -116,7 -110,7 +116,7 @@@ static inline void idct_put(MadContext 
      }
  }
  
 -static inline void decode_block_intra(MadContext *s, DCTELEM * block)
 +static inline int decode_block_intra(MadContext *s, DCTELEM * block)
  {
      int level, i, j, run;
      RLTable *rl = &ff_rl_mpeg1;
              }
              if (i > 63) {
                  av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
 -                return;
 +                return -1;
              }
  
              block[j] = level;
          }
          CLOSE_READER(re, &s->gb);
      }
 +    return 0;
  }
  
  static int decode_motion(GetBitContext *gb)
      return value;
  }
  
 -static void decode_mb(MadContext *s, int inter)
 +static int decode_mb(MadContext *s, int inter)
  {
      int mv_map = 0;
      int mv_x, mv_y;
              mv_map = v ? get_bits(&s->gb, 6) : 63;
              mv_x = decode_motion(&s->gb);
              mv_y = decode_motion(&s->gb);
 -        } else {
 -            mv_map = 0;
          }
      }
  
      for (j=0; j<6; j++) {
          if (mv_map & (1<<j)) {  // mv_x and mv_y are guarded by mv_map
              int add = 2*decode_motion(&s->gb);
 -            comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
 +            if (s->last_frame.data[0])
 +                comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
          } else {
              s->dsp.clear_block(s->block);
 -            decode_block_intra(s, s->block);
 +            if(decode_block_intra(s, s->block) < 0)
 +                return -1;
              idct_put(s, s->block, s->mb_x, s->mb_y, j);
          }
      }
 +    return 0;
  }
  
  static void calc_quant_matrix(MadContext *s, int qscale)
@@@ -234,14 -226,14 +234,14 @@@ static int decode_frame(AVCodecContext 
      int buf_size       = avpkt->size;
      const uint8_t *buf_end = buf+buf_size;
      MadContext *s     = avctx->priv_data;
 -    int width, height;
 +    int width, height, ret;
      int chunk_type;
      int inter;
  
 -    if (buf_size < 17) {
 +    if (buf_size < 26) {
          av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
          *got_frame = 0;
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
  
      chunk_type = AV_RL32(&buf[0]);
      buf += 16;
  
      if (avctx->width != width || avctx->height != height) {
 -        if (av_image_check_size(width, height, 0, avctx) < 0)
 -            return -1;
 +        if((width * height)/2048*7 > buf_end-buf)
 +            return AVERROR_INVALIDDATA;
 +        if ((ret = av_image_check_size(width, height, 0, avctx)) < 0)
 +            return ret;
          avcodec_set_dimensions(avctx, width, height);
          if (s->frame.data[0])
              avctx->release_buffer(avctx, &s->frame);
 +        if (s->last_frame.data[0])
 +            avctx->release_buffer(avctx, &s->last_frame);
      }
  
 -    s->frame.reference = 1;
 +    s->frame.reference = 3;
      if (!s->frame.data[0]) {
 -        if (ff_get_buffer(avctx, &s->frame) < 0) {
 +        if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
              av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 -            return -1;
 +            return ret;
          }
      }
  
+     if (inter && !s->last_frame.data[0]) {
+         int ret;
+         av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n");
+         s->last_frame.reference = 1;
+         ret = ff_get_buffer(avctx, &s->last_frame);
+         if (ret < 0)
+             return ret;
+         memset(s->last_frame.data[0], 0, s->last_frame.height *
+                s->last_frame.linesize[0]);
+         memset(s->last_frame.data[1], 0x80, s->last_frame.height / 2 *
+                s->last_frame.linesize[1]);
+         memset(s->last_frame.data[2], 0x80, s->last_frame.height / 2 *
+                s->last_frame.linesize[2]);
+     }
      av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
                            buf_end - buf);
      if (!s->bitstream_buf)
          return AVERROR(ENOMEM);
      s->dsp.bswap16_buf(s->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2);
 +    memset((uint8_t*)s->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE);
      init_get_bits(&s->gb, s->bitstream_buf, 8*(buf_end-buf));
  
      for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
          for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
 -            decode_mb(s, inter);
 +            if(decode_mb(s, inter) < 0)
 +                return AVERROR_INVALIDDATA;
  
      *got_frame = 1;
      *(AVFrame*)data = s->frame;
diff --combined libavcodec/libmp3lame.c
@@@ -2,20 -2,20 +2,20 @@@
   * Interface to libmp3lame for mp3 encoding
   * Copyright (c) 2002 Lennert Buytenhek <buytenh@gnu.org>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * 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 Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -38,7 -38,7 +38,7 @@@
  #include "mpegaudio.h"
  #include "mpegaudiodecheader.h"
  
 -#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4)
 +#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4+1000) // FIXME: Buffer size to small? Adding 1000 to make up for it.
  
  typedef struct LAMEContext {
      AVClass *class;
@@@ -102,7 -102,6 +102,7 @@@ static av_cold int mp3lame_encode_init(
      if ((s->gfp = lame_init()) == NULL)
          return AVERROR(ENOMEM);
  
 +
      lame_set_num_channels(s->gfp, avctx->channels);
      lame_set_mode(s->gfp, avctx->channels > 1 ? JOINT_STEREO : MONO);
  
@@@ -218,7 -217,7 +218,7 @@@ static int mp3lame_encode_frame(AVCodec
          }
      } else {
          lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index,
-                                         BUFFER_SIZE - s->buffer_index);
+                                         s->buffer_size - s->buffer_index);
      }
      if (lame_result < 0) {
          if (lame_result == -1) {
  
      /* add current frame to the queue */
      if (frame) {
 -        if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
 +        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
              return ret;
      }
  
      av_dlog(avctx, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len,
              s->buffer_index);
      if (len <= s->buffer_index) {
 -        if ((ret = ff_alloc_packet(avpkt, len))) {
 -            av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
 +        if ((ret = ff_alloc_packet2(avctx, avpkt, len)))
              return ret;
 -        }
          memcpy(avpkt->data, s->buffer, len);
          s->buffer_index -= len;
          memmove(s->buffer, s->buffer + len, s->buffer_index);
diff --combined libavcodec/png.c
@@@ -2,25 -2,29 +2,25 @@@
   * PNG image format
   * Copyright (c) 2003 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * 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 Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  #include "avcodec.h"
 -#include "bytestream.h"
  #include "png.h"
  
 -const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
 -const uint8_t ff_mngsig[8] = {138, 77, 78, 71, 13, 10, 26, 10};
 -
  /* Mask to determine which y pixels are valid in a pass */
  const uint8_t ff_png_pass_ymask[NB_PASSES] = {
      0x80, 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55,
@@@ -36,11 -40,14 +36,9 @@@ static const uint8_t ff_png_pass_xshift
      3, 3, 2, 2, 1, 1, 0
  };
  
 -/* Mask to determine which pixels are valid in a pass */
 -const uint8_t ff_png_pass_mask[NB_PASSES] = {
 -    0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff
 -};
 -
  void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size)
  {
-     if(items >= UINT_MAX / size)
-         return NULL;
-     return av_malloc(items * size);
+     return av_mallocz_array(items, size);
  }
  
  void ff_png_zfree(void *opaque, void *ptr)
diff --combined libavcodec/wmadec.c
@@@ -1,21 -1,21 +1,21 @@@
  /*
   * WMA compatible decoder
 - * Copyright (c) 2002 The Libav Project
 + * Copyright (c) 2002 The FFmpeg Project
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * 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 Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -72,6 -72,11 +72,11 @@@ static int wma_decode_init(AVCodecConte
      int i, flags2;
      uint8_t *extradata;
  
+     if (!avctx->block_align) {
+         av_log(avctx, AV_LOG_ERROR, "block_align is not set\n");
+         return AVERROR(EINVAL);
+     }
      s->avctx = avctx;
  
      /* extract flag infos */
      s->use_bit_reservoir = flags2 & 0x0002;
      s->use_variable_block_len = flags2 & 0x0004;
  
 +    if(avctx->codec->id == AV_CODEC_ID_WMAV2 && avctx->extradata_size >= 8){
 +        if(AV_RL16(extradata+4)==0xd && s->use_variable_block_len){
 +            av_log(avctx, AV_LOG_WARNING, "Disabling use_variable_block_len, if this fails contact the ffmpeg developers and send us the file\n");
 +            s->use_variable_block_len= 0; // this fixes issue1503
 +        }
 +    }
 +
      if(ff_wma_init(avctx, flags2)<0)
          return -1;
  
@@@ -476,11 -474,6 +481,11 @@@ static int wma_decode_block(WMACodecCon
          s->block_len_bits = s->frame_len_bits;
      }
  
 +    if (s->frame_len_bits - s->block_len_bits >= s->nb_block_sizes){
 +        av_log(s->avctx, AV_LOG_ERROR, "block_len_bits not initialized to a valid value\n");
 +        return -1;
 +    }
 +
      /* now check if the block length is coherent with the frame length */
      s->block_len = 1 << s->block_len_bits;
      if ((s->block_pos + s->block_len) > s->frame_len){
@@@ -820,8 -813,7 +825,8 @@@ static int wma_decode_superframe(AVCode
                 buf_size, avctx->block_align);
          return AVERROR_INVALIDDATA;
      }
 -    buf_size = avctx->block_align;
 +    if(avctx->block_align)
 +        buf_size = avctx->block_align;
  
      init_get_bits(&s->gb, buf, buf_size*8);
  
      *got_frame_ptr   = 1;
      *(AVFrame *)data = s->frame;
  
 -    return avctx->block_align;
 +    return buf_size;
   fail:
      /* when error, we reset the bit reservoir */
      s->last_superframe_len = 0;
@@@ -936,7 -928,6 +941,7 @@@ static av_cold void flush(AVCodecContex
      s->last_superframe_len= 0;
  }
  
 +#if CONFIG_WMAV1_DECODER
  AVCodec ff_wmav1_decoder = {
      .name           = "wmav1",
      .type           = AVMEDIA_TYPE_AUDIO,
      .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                        AV_SAMPLE_FMT_NONE },
  };
 -
 +#endif
 +#if CONFIG_WMAV2_DECODER
  AVCodec ff_wmav2_decoder = {
      .name           = "wmav2",
      .type           = AVMEDIA_TYPE_AUDIO,
      .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                        AV_SAMPLE_FMT_NONE },
  };
 +#endif
diff --combined libavcodec/wmaprodec.c
@@@ -3,20 -3,20 +3,20 @@@
   * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
   * Copyright (c) 2008 - 2011 Sascha Sommer, Benjamin Larsson
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * 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 Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -280,6 -280,11 +280,11 @@@ static av_cold int decode_init(AVCodecC
      int log2_max_num_subframes;
      int num_possible_block_sizes;
  
+     if (!avctx->block_align) {
+         av_log(avctx, AV_LOG_ERROR, "block_align is not set\n");
+         return AVERROR(EINVAL);
+     }
      s->avctx = avctx;
      ff_dsputil_init(&s->dsp, avctx);
      avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
          return AVERROR_INVALIDDATA;
      }
  
 +    if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) {
 +        av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n",
 +               s->min_samples_per_subframe);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
      if (s->avctx->sample_rate <= 0) {
          av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
          return AVERROR_INVALIDDATA;
          }
          s->sfb_offsets[i][band - 1] = subframe_len;
          s->num_sfb[i]               = band - 1;
 +        if (s->num_sfb[i] <= 0) {
 +            av_log(avctx, AV_LOG_ERROR, "num_sfb invalid\n");
 +            return AVERROR_INVALIDDATA;
 +        }
      }
  
  
@@@ -1144,7 -1139,7 +1149,7 @@@ static int decode_subframe(WMAProDecode
          int num_fill_bits;
          if (!(num_fill_bits = get_bits(&s->gb, 2))) {
              int len = get_bits(&s->gb, 4);
 -            num_fill_bits = get_bits(&s->gb, len) + 1;
 +            num_fill_bits = (len ? get_bits(&s->gb, len) : 0) + 1;
          }
  
          if (num_fill_bits >= 0) {
              transmit_coeffs = 1;
      }
  
 +    av_assert0(s->subframe_len <= WMAPRO_BLOCK_MAX_SIZE);
      if (transmit_coeffs) {
          int step;
          int quant_step = 90 * s->bits_per_sample >> 4;
              for (i = 0; i < s->channels_for_cur_subframe; i++) {
                  int c = s->channel_indexes_for_cur_subframe[i];
                  int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
 -                if (num_vec_coeffs > WMAPRO_BLOCK_MAX_SIZE) {
 +                if (num_vec_coeffs > s->subframe_len) {
                      av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
                      return AVERROR_INVALIDDATA;
                  }
@@@ -1453,7 -1447,7 +1458,7 @@@ static void save_bits(WMAProDecodeCtx *
      int buflen;
  
      /** when the frame data does not need to be concatenated, the input buffer
 -        is resetted and additional bits from the previous frame are copyed
 +        is reset and additional bits from the previous frame are copied
          and skipped later so that a fast byte copy is possible */
  
      if (!append) {
          init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
      }
  
 -    buflen = (s->num_saved_bits + len + 8) >> 3;
 +    buflen = (put_bits_count(&s->pb) + len + 8) >> 3;
  
      if (len <= 0 || buflen > MAX_FRAMESIZE) {
          av_log_ask_for_sample(s->avctx, "input buffer too small\n");
diff --combined libavcodec/xxan.c
@@@ -3,20 -3,20 +3,20 @@@
   * Copyright (C) 2011 Konstantin Shishkov
   * based on work by Mike Melanson
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * 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.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * 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 Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -138,7 -138,7 +138,7 @@@ static int xan_unpack(XanContext *s
              }
              if (dest + size + size2 > dest_end ||
                  dest - orig_dest + size < back)
 -                return -1;
 +                return AVERROR_INVALIDDATA;
              bytestream2_get_buffer(&s->gb, dest, size);
              dest += size;
              av_memcpy_backptr(dest, back, size2);
  
              size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
              if (dest_end - dest < size)
 -                return -1;
 +                return AVERROR_INVALIDDATA;
              bytestream2_get_buffer(&s->gb, dest, size);
              dest += size;
              if (finish)
@@@ -172,7 -172,7 +172,7 @@@ static int xan_decode_chroma(AVCodecCon
          return 0;
      if (chroma_off + 4 >= bytestream2_get_bytes_left(&s->gb)) {
          av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n");
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
      bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
      mode        = bytestream2_get_le16(&s->gb);
  
      if (offset >= bytestream2_get_bytes_left(&s->gb)) {
          av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
  
      bytestream2_skip(&s->gb, offset);
      dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
      if (dec_size < 0) {
          av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
  
      U = s->pic.data[1];
      if (mode) {
          for (j = 0; j < avctx->height >> 1; j++) {
              for (i = 0; i < avctx->width >> 1; i++) {
 +                if (src_end - src < 1)
 +                    return 0;
                  val = *src++;
 -                if (val && val < table_size) {
 +                if (val) {
 +                    if (val >= table_size)
 +                        return AVERROR_INVALIDDATA;
                      val  = AV_RL16(table + (val << 1));
                      uval = (val >> 3) & 0xF8;
                      vval = (val >> 8) & 0xF8;
                      U[i] = uval | (uval >> 5);
                      V[i] = vval | (vval >> 5);
                  }
 -                if (src == src_end)
 -                    return 0;
              }
              U += s->pic.linesize[1];
              V += s->pic.linesize[2];
  
          for (j = 0; j < avctx->height >> 2; j++) {
              for (i = 0; i < avctx->width >> 1; i += 2) {
 +                if (src_end - src < 1)
 +                    return 0;
                  val = *src++;
 -                if (val && val < table_size) {
 +                if (val) {
 +                    if (val >= table_size)
 +                        return AVERROR_INVALIDDATA;
                      val  = AV_RL16(table + (val << 1));
                      uval = (val >> 3) & 0xF8;
                      vval = (val >> 8) & 0xF8;
@@@ -271,7 -265,7 +271,7 @@@ static int xan_decode_frame_type0(AVCod
      if ((ret = xan_decode_chroma(avctx, chroma_off)) != 0)
          return ret;
  
 -    if (corr_off >= (s->gb.buffer_end - s->gb.buffer_start)) {
 +    if (corr_off >= bytestream2_size(&s->gb)) {
          av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
          corr_off = 0;
      }
          ybuf[j+1] = cur << 1;
          last = cur;
      }
 -    ybuf[j]  = last << 1;
 +    if(j < avctx->width)
 +        ybuf[j]  = last << 1;
      prev_buf = ybuf;
      ybuf += avctx->width;
  
              ybuf[j+1] = cur << 1;
              last = cur;
          }
 -        ybuf[j] = last << 1;
 +        if(j < avctx->width)
 +            ybuf[j] = last << 1;
          prev_buf = ybuf;
          ybuf += avctx->width;
      }
          int dec_size;
  
          bytestream2_seek(&s->gb, 8 + corr_off, SEEK_SET);
-         dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
+         dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size / 2);
          if (dec_size < 0)
              dec_size = 0;
 +        else
 +            dec_size = FFMIN(dec_size, s->buffer_size/2 - 1);
 +
          for (i = 0; i < dec_size; i++)
              s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
      }
@@@ -366,8 -355,7 +366,8 @@@ static int xan_decode_frame_type1(AVCod
              ybuf[j+1] = cur;
              last = cur;
          }
 -        ybuf[j] = last;
 +        if(j < avctx->width)
 +            ybuf[j] = last;
          ybuf += avctx->width;
      }
  
@@@ -391,7 -379,7 +391,7 @@@ static int xan_decode_frame(AVCodecCont
      int ftype;
      int ret;
  
 -    s->pic.reference = 1;
 +    s->pic.reference = 3;
      s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
                            FF_BUFFER_HINTS_PRESERVE |
                            FF_BUFFER_HINTS_REUSABLE;
          break;
      default:
          av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
      if (ret)
          return ret;