Merge commit '1a31dff9370b4732c91df5cb1ca4b39f2cb3050e'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 14 Jan 2013 14:36:35 +0000 (15:36 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 14 Jan 2013 14:36:35 +0000 (15:36 +0100)
* commit '1a31dff9370b4732c91df5cb1ca4b39f2cb3050e':
  loco: return meaningful error codes.
  flicvideo: return meaningful error codes.
  vcr1: remove disabled encoder stub

Conflicts:
libavcodec/flicvideo.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/flicvideo.c
libavcodec/loco.c
libavcodec/vcr1.c

diff --combined libavcodec/flicvideo.c
@@@ -2,20 -2,20 +2,20 @@@
   * FLI/FLC Animation Video Decoder
   * Copyright (C) 2003, 2004 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
   */
  
@@@ -63,7 -63,7 +63,7 @@@
  
  #define CHECK_PIXEL_PTR(n) \
      if (pixel_ptr + n > pixel_limit) { \
 -        av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
 +        av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
          pixel_ptr + n, pixel_limit); \
          return AVERROR_INVALIDDATA; \
      } \
@@@ -83,40 -83,22 +83,40 @@@ static av_cold int flic_decode_init(AVC
      unsigned char *fli_header = (unsigned char *)avctx->extradata;
      int depth;
  
 -    if (avctx->extradata_size != 12 &&
 -        avctx->extradata_size != 128) {
 -        av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
 +    if (avctx->extradata_size != 0 &&
 +        avctx->extradata_size != 12 &&
 +        avctx->extradata_size != 128 &&
 +        avctx->extradata_size != 256 &&
 +        avctx->extradata_size != 904 &&
 +        avctx->extradata_size != 1024) {
 +        av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
          return AVERROR_INVALIDDATA;
      }
  
      s->avctx = avctx;
  
 -    s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
 -
 -    depth = 0;
      if (s->avctx->extradata_size == 12) {
          /* special case for magic carpet FLIs */
          s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
          depth = 8;
 +    } else if (avctx->extradata_size == 1024) {
 +        uint8_t *ptr = avctx->extradata;
 +        int i;
 +
 +        for (i = 0; i < 256; i++) {
 +            s->palette[i] = AV_RL32(ptr);
 +            ptr += 4;
 +        }
 +        depth = 8;
 +        /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
 +    } else if (avctx->extradata_size == 0 ||
 +               avctx->extradata_size == 256 ||
 +        /* see FFmpeg ticket #1234 */
 +               avctx->extradata_size == 904) {
 +        s->fli_type = FLI_TYPE_CODE;
 +        depth = 8;
      } else {
 +        s->fli_type = AV_RL16(&fli_header[4]);
          depth = AV_RL16(&fli_header[12]);
      }
  
                    return AVERROR_INVALIDDATA;
      }
  
 +    avcodec_get_frame_defaults(&s->frame);
      s->frame.data[0] = NULL;
      s->new_palette = 0;
  
@@@ -154,6 -135,7 +154,6 @@@ static int flic_decode_frame_8BPP(AVCod
      FlicDecodeContext *s = avctx->priv_data;
  
      GetByteContext g2;
 -    int stream_ptr_after_color_chunk;
      int pixel_ptr;
      int palette_ptr;
      unsigned char palette_idx1;
  
      bytestream2_init(&g2, buf, buf_size);
  
 -    s->frame.reference = 1;
 +    s->frame.reference = 3;
      s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
      if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
  
      pixels = s->frame.data[0];
      pixel_limit = s->avctx->height * s->frame.linesize[0];
 +    if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE))
 +        return AVERROR_INVALIDDATA;
      frame_size = bytestream2_get_le32(&g2);
 +    if (frame_size > buf_size)
 +        frame_size = buf_size;
      bytestream2_skip(&g2, 2); /* skip the magic number */
      num_chunks = bytestream2_get_le16(&g2);
      bytestream2_skip(&g2, 8);  /* skip padding */
      frame_size -= 16;
  
      /* iterate through the chunks */
 -    while ((frame_size > 0) && (num_chunks > 0)) {
 +    while ((frame_size >= 6) && (num_chunks > 0)) {
 +        int stream_ptr_after_chunk;
          chunk_size = bytestream2_get_le32(&g2);
 +        if (chunk_size > frame_size) {
 +            av_log(avctx, AV_LOG_WARNING,
 +                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
 +            chunk_size = frame_size;
 +        }
 +        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
 +
          chunk_type = bytestream2_get_le16(&g2);
  
          switch (chunk_type) {
          case FLI_256_COLOR:
          case FLI_COLOR:
 -            stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6;
 -
              /* check special case: If this file is from the Magic Carpet
               * game and uses 6-bit colors even though it reports 256-color
               * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
                  if (color_changes == 0)
                      color_changes = 256;
  
 +                if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
 +                    break;
 +
                  for (j = 0; j < color_changes; j++) {
                      unsigned int entry;
  
                      r = bytestream2_get_byte(&g2) << color_shift;
                      g = bytestream2_get_byte(&g2) << color_shift;
                      b = bytestream2_get_byte(&g2) << color_shift;
 -                    entry = (r << 16) | (g << 8) | b;
 +                    entry = 0xFFU << 24 | r << 16 | g << 8 | b;
 +                    if (color_shift == 2)
 +                        entry |= entry >> 6 & 0x30303;
                      if (s->palette[palette_ptr] != entry)
                          s->new_palette = 1;
                      s->palette[palette_ptr++] = entry;
                  }
              }
 -
 -            /* color chunks sometimes have weird 16-bit alignment issues;
 -             * therefore, take the hardline approach and skip
 -             * to the value calculated w.r.t. the size specified by the color
 -             * chunk header */
 -            if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0)
 -                bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2));
 -
              break;
  
          case FLI_DELTA:
              y_ptr = 0;
              compressed_lines = bytestream2_get_le16(&g2);
              while (compressed_lines > 0) {
 +                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
 +                    break;
                  line_packets = bytestream2_get_le16(&g2);
                  if ((line_packets & 0xC000) == 0xC000) {
                      // line skip opcode
                      CHECK_PIXEL_PTR(0);
                      pixel_countdown = s->avctx->width;
                      for (i = 0; i < line_packets; i++) {
 +                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
 +                            break;
                          /* account for the skip bytes */
                          pixel_skip = bytestream2_get_byte(&g2);
                          pixel_ptr += pixel_skip;
                              }
                          } else {
                              CHECK_PIXEL_PTR(byte_run * 2);
 +                            if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
 +                                break;
                              for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
                                  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
                              }
                  pixel_ptr = y_ptr;
                  CHECK_PIXEL_PTR(0);
                  pixel_countdown = s->avctx->width;
 +                if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
 +                    break;
                  line_packets = bytestream2_get_byte(&g2);
                  if (line_packets > 0) {
                      for (i = 0; i < line_packets; i++) {
                          /* account for the skip bytes */
 +                        if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
 +                            break;
                          pixel_skip = bytestream2_get_byte(&g2);
                          pixel_ptr += pixel_skip;
                          pixel_countdown -= pixel_skip;
                          byte_run = sign_extend(bytestream2_get_byte(&g2),8);
                          if (byte_run > 0) {
                              CHECK_PIXEL_PTR(byte_run);
 +                            if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
 +                                break;
                              for (j = 0; j < byte_run; j++, pixel_countdown--) {
                                  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
                              }
                   bytestream2_skip(&g2, 1);
                  pixel_countdown = s->avctx->width;
                  while (pixel_countdown > 0) {
 +                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
 +                        break;
                      byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
                      if (byte_run > 0) {
                          palette_idx1 = bytestream2_get_byte(&g2);
                      } else {  /* copy bytes if byte_run < 0 */
                          byte_run = -byte_run;
                          CHECK_PIXEL_PTR(byte_run);
 +                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
 +                            break;
                          for (j = 0; j < byte_run; j++) {
                              pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
                              pixel_countdown--;
  
          case FLI_COPY:
              /* copy the chunk (uncompressed frame) */
 -            if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
 +            if (chunk_size - 6 != s->avctx->width * s->avctx->height) {
                  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
 -                       "bigger than image, skipping chunk\n", chunk_size - 6);
 +                       "has incorrect size, skipping chunk\n", chunk_size - 6);
                  bytestream2_skip(&g2, chunk_size - 6);
              } else {
                  for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
  
          case FLI_MINI:
              /* some sort of a thumbnail? disregard this chunk... */
 -            bytestream2_skip(&g2, chunk_size - 6);
              break;
  
          default:
              break;
          }
  
 +        if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0)
 +            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
 +
          frame_size -= chunk_size;
          num_chunks--;
      }
  
      /* by the end of the chunk, the stream ptr should equal the frame
 -     * size (minus 1, possibly); if it doesn't, issue a warning */
 -    if ((bytestream2_get_bytes_left(&g2) != 0) &&
 -        (bytestream2_get_bytes_left(&g2) != 1))
 +     * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
 +    if (bytestream2_get_bytes_left(&g2) > 2)
          av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
                 "and final chunk ptr = %d\n", buf_size,
                 buf_size - bytestream2_get_bytes_left(&g2));
@@@ -500,7 -458,7 +500,7 @@@ static int flic_decode_frame_15_16BPP(A
  
      bytestream2_init(&g2, buf, buf_size);
  
 -    s->frame.reference = 1;
 +    s->frame.reference = 3;
      s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
      if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
      bytestream2_skip(&g2, 2);  /* skip the magic number */
      num_chunks = bytestream2_get_le16(&g2);
      bytestream2_skip(&g2, 8);  /* skip padding */
 +    if (frame_size > buf_size)
 +        frame_size = buf_size;
  
      frame_size -= 16;
  
      /* iterate through the chunks */
      while ((frame_size > 0) && (num_chunks > 0)) {
 +        int stream_ptr_after_chunk;
          chunk_size = bytestream2_get_le32(&g2);
 +        if (chunk_size > frame_size) {
 +            av_log(avctx, AV_LOG_WARNING,
 +                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
 +            chunk_size = frame_size;
 +        }
 +        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
 +
          chunk_type = bytestream2_get_le16(&g2);
  
 +
          switch (chunk_type) {
          case FLI_256_COLOR:
          case FLI_COLOR:
              y_ptr = 0;
              compressed_lines = bytestream2_get_le16(&g2);
              while (compressed_lines > 0) {
 +                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
 +                    break;
                  line_packets = bytestream2_get_le16(&g2);
                  if (line_packets < 0) {
                      line_packets = -line_packets;
                      pixel_countdown = s->avctx->width;
                      for (i = 0; i < line_packets; i++) {
                          /* account for the skip bytes */
 +                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
 +                            break;
                          pixel_skip = bytestream2_get_byte(&g2);
                          pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
                          pixel_countdown -= pixel_skip;
                                  pixel_ptr += 2;
                              }
                          } else {
 +                            if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
 +                                break;
                              CHECK_PIXEL_PTR(2 * byte_run);
                              for (j = 0; j < byte_run; j++, pixel_countdown--) {
                                  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
                  pixel_countdown = (s->avctx->width * 2);
  
                  while (pixel_countdown > 0) {
 +                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
 +                        break;
                      byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
                      if (byte_run > 0) {
                          palette_idx1 = bytestream2_get_byte(&g2);
                          }
                      } else {  /* copy bytes if byte_run < 0 */
                          byte_run = -byte_run;
 +                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
 +                            break;
                          CHECK_PIXEL_PTR(byte_run);
                          for (j = 0; j < byte_run; j++) {
                              palette_idx1 = bytestream2_get_byte(&g2);
                  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
  
                  while (pixel_countdown > 0) {
 +                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
 +                        break;
                      byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
                      if (byte_run > 0) {
                          pixel    = bytestream2_get_le16(&g2);
                          }
                      } else {  /* copy pixels if byte_run < 0 */
                          byte_run = -byte_run;
 +                        if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
 +                            break;
                          CHECK_PIXEL_PTR(2 * byte_run);
                          for (j = 0; j < byte_run; j++) {
                              *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
@@@ -787,7 -720,7 +787,7 @@@ static int flic_decode_frame(AVCodecCon
      /* the finite set of possibilites allowable by here. */
      /* But in case we do, just error out. */
      av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
-     return AVERROR_INVALIDDATA;
+     return AVERROR_BUG;
  }
  
  
diff --combined libavcodec/loco.c
@@@ -2,20 -2,20 +2,20 @@@
   * LOCO codec
   * Copyright (c) 2005 Konstantin Shishkov
   *
 - * 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
   */
  
@@@ -124,9 -124,6 +124,9 @@@ static int loco_decode_plane(LOCOContex
      int val;
      int i, j;
  
 +    if(buf_size<=0)
 +        return -1;
 +
      init_get_bits(&rc.gb, buf, buf_size*8);
      rc.save = 0;
      rc.run = 0;
@@@ -168,73 -165,68 +168,73 @@@ static int decode_frame(AVCodecContext 
      int buf_size = avpkt->size;
      LOCOContext * const l = avctx->priv_data;
      AVFrame * const p = &l->pic;
-     int decoded;
+     int decoded, ret;
  
      if(p->data[0])
          avctx->release_buffer(avctx, p);
  
      p->reference = 0;
-     if(ff_get_buffer(avctx, p) < 0){
+     if ((ret = ff_get_buffer(avctx, p)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-         return -1;
+         return ret;
      }
      p->key_frame = 1;
  
 +#define ADVANCE_BY_DECODED do { \
 +    if (decoded < 0) goto stop; \
 +    buf += decoded; buf_size -= decoded; \
 +} while(0)
      switch(l->mode) {
      case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY:
          decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
                                      p->linesize[0], buf, buf_size, 1);
 -        buf += decoded; buf_size -= decoded;
 +        ADVANCE_BY_DECODED;
          decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height,
                                      p->linesize[1], buf, buf_size, 1);
 -        buf += decoded; buf_size -= decoded;
 +        ADVANCE_BY_DECODED;
          decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height,
                                      p->linesize[2], buf, buf_size, 1);
          break;
      case LOCO_CYV12: case LOCO_YV12:
          decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
                                      p->linesize[0], buf, buf_size, 1);
 -        buf += decoded; buf_size -= decoded;
 +        ADVANCE_BY_DECODED;
          decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2,
                                      p->linesize[2], buf, buf_size, 1);
 -        buf += decoded; buf_size -= decoded;
 +        ADVANCE_BY_DECODED;
          decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2,
                                      p->linesize[1], buf, buf_size, 1);
          break;
      case LOCO_CRGB: case LOCO_RGB:
          decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
                                      -p->linesize[0], buf, buf_size, 3);
 -        buf += decoded; buf_size -= decoded;
 +        ADVANCE_BY_DECODED;
          decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height,
                                      -p->linesize[0], buf, buf_size, 3);
 -        buf += decoded; buf_size -= decoded;
 +        ADVANCE_BY_DECODED;
          decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height,
                                      -p->linesize[0], buf, buf_size, 3);
          break;
 -    case LOCO_RGBA:
 -        decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
 -                                    p->linesize[0], buf, buf_size, 4);
 -        buf += decoded; buf_size -= decoded;
 -        decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height,
 -                                    p->linesize[0], buf, buf_size, 4);
 -        buf += decoded; buf_size -= decoded;
 -        decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height,
 -                                    p->linesize[0], buf, buf_size, 4);
 -        buf += decoded; buf_size -= decoded;
 -        decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height,
 -                                    p->linesize[0], buf, buf_size, 4);
 +    case LOCO_CRGBA: case LOCO_RGBA:
 +        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
 +                                    -p->linesize[0], buf, buf_size, 4);
 +        ADVANCE_BY_DECODED;
 +        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height,
 +                                    -p->linesize[0], buf, buf_size, 4);
 +        ADVANCE_BY_DECODED;
 +        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height,
 +                                    -p->linesize[0], buf, buf_size, 4);
 +        ADVANCE_BY_DECODED;
 +        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 3, avctx->width, avctx->height,
 +                                    -p->linesize[0], buf, buf_size, 4);
          break;
      }
 +stop:
  
      *got_frame      = 1;
      *(AVFrame*)data = l->pic;
  
 -    return buf_size;
 +    return buf_size < 0 ? -1 : avpkt->size - buf_size;
  }
  
  static av_cold int decode_init(AVCodecContext *avctx){
      if (avctx->extradata_size < 12) {
          av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n",
                 avctx->extradata_size);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      version = AV_RL32(avctx->extradata);
      switch(version) {
          break;
      default:
          av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      if(avctx->debug & FF_DEBUG_PICT_INFO)
          av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode);
  
 +    avcodec_get_frame_defaults(&l->pic);
 +
      return 0;
  }
  
diff --combined libavcodec/vcr1.c
@@@ -2,20 -2,20 +2,20 @@@
   * ATI VCR1 codec
   * Copyright (c) 2003 Michael Niedermayer
   *
 - * 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
   */
  
@@@ -40,7 -40,6 +40,7 @@@ static av_cold int vcr1_common_init(AVC
      VCR1Context *const a = avctx->priv_data;
  
      avctx->coded_frame = &a->picture;
 +    avcodec_get_frame_defaults(&a->picture);
  
      return 0;
  }
@@@ -51,10 -50,6 +51,10 @@@ static av_cold int vcr1_decode_init(AVC
  
      avctx->pix_fmt = AV_PIX_FMT_YUV410P;
  
 +    if (avctx->width % 8 || avctx->height%4) {
 +        av_log_ask_for_sample(avctx, "odd dimensions are not supported\n");
 +        return AVERROR_PATCHWELCOME;
 +    }
      return 0;
  }
  
@@@ -82,11 -77,6 +82,11 @@@ static int vcr1_decode_frame(AVCodecCon
      if (p->data[0])
          avctx->release_buffer(avctx, p);
  
 +    if(buf_size < 16 + avctx->height + avctx->width*avctx->height*5/8){
 +        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
 +        return AVERROR(EINVAL);
 +    }
 +
      p->reference = 0;
      if ((ret = ff_get_buffer(avctx, p)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@@ -159,42 -149,3 +159,3 @@@ AVCodec ff_vcr1_decoder = 
      .capabilities   = CODEC_CAP_DR1,
      .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
  };
- /* Disable the encoder. */
- #undef CONFIG_VCR1_ENCODER
- #define CONFIG_VCR1_ENCODER 0
- #if CONFIG_VCR1_ENCODER
- #include "put_bits.h"
- static int vcr1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
-                              int buf_size, void *data)
- {
-     VCR1Context *const a = avctx->priv_data;
-     AVFrame *pict        = data;
-     AVFrame *const p     = &a->picture;
-     int size;
-     *p           = *pict;
-     p->pict_type = AV_PICTURE_TYPE_I;
-     p->key_frame = 1;
-     avpriv_align_put_bits(&a->pb);
-     flush_put_bits(&a->pb);
-     size = put_bits_count(&a->pb) / 32;
-     return size * 4;
- }
- AVCodec ff_vcr1_encoder = {
-     .name           = "vcr1",
-     .type           = AVMEDIA_TYPE_VIDEO,
-     .id             = AV_CODEC_ID_VCR1,
-     .priv_data_size = sizeof(VCR1Context),
-     .init           = vcr1_common_init,
-     .encode         = vcr1_encode_frame,
-     .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
- };
- #endif /* CONFIG_VCR1_ENCODER */