Merge commit '9dbbda235d93d628777b986e502213f1ed390973'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 7 Jan 2013 00:24:32 +0000 (01:24 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 7 Jan 2013 00:24:32 +0000 (01:24 +0100)
* commit '9dbbda235d93d628777b986e502213f1ed390973':
  vb: return meaningful error codes.
  ptx: return meaningful error codes.
  tiff: return meaningful error codes.
  vqavideo: return meaningful error codes.
  mss2: return meaningful error codes.
  v210dec: return meaningful error codes
  indeo2: cosmetics, reformat

Conflicts:
libavcodec/indeo2.c
libavcodec/tiff.c
libavcodec/v210dec.c
libavcodec/vb.c
libavcodec/vqavideo.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/indeo2.c
libavcodec/mss2.c
libavcodec/ptx.c
libavcodec/tiff.c
libavcodec/v210dec.c
libavcodec/vb.c
libavcodec/vqavideo.c

@@@ -141,14 -141,17 +141,14 @@@ static int ir2_decode_frame(AVCodecCont
                          void *data, int *got_frame,
                          AVPacket *avpkt)
  {
-     const uint8_t *buf = avpkt->data;
-     int buf_size = avpkt->size;
      Ir2Context * const s = avctx->priv_data;
-     AVFrame *picture = data;
-     AVFrame * const p = &s->picture;
+     const uint8_t *buf   = avpkt->data;
+     int buf_size         = avpkt->size;
+     AVFrame *picture     = data;
+     AVFrame * const p    = &s->picture;
      int start, ret;
  
 -    if (p->data[0])
 -        avctx->release_buffer(avctx, p);
 -
 -    p->reference = 1;
 +    p->reference = 3;
      p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
      if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
          av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
Simple merge
Simple merge
@@@ -432,9 -133,8 +432,9 @@@ static int tiff_unpack_strip(TiffContex
              av_log(s->avctx, AV_LOG_ERROR,
                     "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
                     (unsigned long)width * lines, ret);
 +            av_free(src2);
              av_free(zbuf);
-             return -1;
+             return AVERROR_UNKNOWN;
          }
          src = zbuf;
          for (line = 0; line < lines; line++) {
      }
  #endif
      if (s->compr == TIFF_LZW) {
-         if (ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0) {
 +        if (s->fill_order) {
 +            int i;
 +            av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size);
 +            if (!s->deinvert_buf)
 +                return AVERROR(ENOMEM);
 +            for (i = 0; i < size; i++)
 +                s->deinvert_buf[i] = ff_reverse[src[i]];
 +            src = s->deinvert_buf;
 +            ssrc = src;
 +        }
 +        if (size > 1 && !src[0] && (src[1]&1)) {
 +            av_log(s->avctx, AV_LOG_ERROR, "Old style LZW is unsupported\n");
 +        }
+         if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {
              av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
-             return -1;
+             return ret;
          }
      }
      if (s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3
                      if (pixels + code > width) {
                          av_log(s->avctx, AV_LOG_ERROR,
                                 "Copy went out of bounds\n");
-                         return -1;
+                         return AVERROR_INVALIDDATA;
                      }
 -                    memcpy(dst + pixels, src, code);
 +                    if (ssrc + size - src < code) {
 +                        av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
 +                        return AVERROR_INVALIDDATA;
 +                    }
 +                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
 +                                    dst, 1, src, 0, code, pixels);
                      src += code;
                      pixels += code;
                  } else if (code != -128) { // -127..-1
                      if (pixels + code > width) {
                          av_log(s->avctx, AV_LOG_ERROR,
                                 "Run went out of bounds\n");
-                         return -1;
+                         return AVERROR_INVALIDDATA;
                      }
                      c = *src++;
 -                    memset(dst + pixels, c, code);
 +                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
 +                                    dst, 0, NULL, c, code, pixels);
                      pixels += code;
                  }
              }
              if (pixels < width) {
                  av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
                         pixels, width);
-                 return -1;
+                 return AVERROR_INVALIDDATA;
              }
 +            if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
 +                horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
              break;
          }
          dst += stride;
@@@ -718,10 -381,8 +718,10 @@@ static int tiff_decode_tag(TiffContext 
              case TIFF_SHORT:
              case TIFF_LONG:
                  s->bpp = 0;
 -                for (i = 0; i < count && buf < end_buf; i++)
 -                    s->bpp += tget(&buf, type, s->le);
 +                if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
-                     return -1;
++                    return AVERROR_INVALIDDATA;
 +                for (i = 0; i < count; i++)
 +                    s->bpp += tget(&s->gb, type, s->le);
                  break;
              default:
                  s->bpp = -1;
          if (s->strips == 1)
              s->rps = s->height;
          s->sot = type;
 -        if (s->stripdata > end_buf) {
 +        if (s->strippos > bytestream2_size(&s->gb)) {
              av_log(s->avctx, AV_LOG_ERROR,
                     "Tag referencing position outside the image\n");
-             return -1;
+             return AVERROR_INVALIDDATA;
          }
          break;
      case TIFF_STRIP_SIZE:
          }
          s->strips = count;
          s->sstype = type;
 -        if (s->stripsizes > end_buf) {
 +        if (s->stripsizesoff > bytestream2_size(&s->gb)) {
              av_log(s->avctx, AV_LOG_ERROR,
                     "Tag referencing position outside the image\n");
-             return -1;
+             return AVERROR_INVALIDDATA;
          }
          break;
 +    case TIFF_TILE_BYTE_COUNTS:
 +    case TIFF_TILE_LENGTH:
 +    case TIFF_TILE_OFFSETS:
 +    case TIFF_TILE_WIDTH:
 +        av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");
 +        return AVERROR_PATCHWELCOME;
 +        break;
      case TIFF_PREDICTOR:
          s->predictor = value;
          break;
      case TIFF_PAL:
          pal = (uint32_t *) s->palette;
          off = type_sizes[type];
 -        if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
 +        if (count / 3 > 256 || bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
-             return -1;
+             return AVERROR_INVALIDDATA;
 -        rp = buf;
 -        gp = buf + count / 3 * off;
 -        bp = buf + count / 3 * off * 2;
          off = (type_sizes[type] - 1) << 3;
 -        for (i = 0; i < count / 3; i++) {
 -            j  = (tget(&rp, type, s->le) >> off) << 16;
 -            j |= (tget(&gp, type, s->le) >> off) << 8;
 -            j |=  tget(&bp, type, s->le) >> off;
 -            pal[i] = j;
 +        for (k = 2; k >= 0; k--) {
 +            for (i = 0; i < count / 3; i++) {
 +                if (k == 2)
 +                    pal[i] = 0xFFU << 24;
 +                j =  (tget(&s->gb, type, s->le) >> off) << (k * 8);
 +                pal[i] |= j;
 +            }
          }
          s->palette_is_set = 1;
          break;
          if (s->compr == TIFF_G4)
              s->fax_opts = value;
          break;
-                         return -1;
 +#define ADD_METADATA(count, name, sep)\
 +    if (ret = add_metadata(count, type, name, sep, s) < 0) {\
 +        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\
 +        return ret;\
 +    }
 +    case TIFF_MODEL_PIXEL_SCALE:
 +        ADD_METADATA(count, "ModelPixelScaleTag", NULL);
 +        break;
 +    case TIFF_MODEL_TRANSFORMATION:
 +        ADD_METADATA(count, "ModelTransformationTag", NULL);
 +        break;
 +    case TIFF_MODEL_TIEPOINT:
 +        ADD_METADATA(count, "ModelTiepointTag", NULL);
 +        break;
 +    case TIFF_GEO_KEY_DIRECTORY:
 +        ADD_METADATA(1, "GeoTIFF_Version", NULL);
 +        ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");
 +        s->geotag_count   = tget_short(&s->gb, s->le);
 +        if (s->geotag_count > count / 4 - 1) {
 +            s->geotag_count = count / 4 - 1;
 +            av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
 +        }
 +        if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4)
 +            return -1;
 +        s->geotags = av_mallocz(sizeof(TiffGeoTag) * s->geotag_count);
 +        if (!s->geotags) {
 +            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
 +            return AVERROR(ENOMEM);
 +        }
 +        for (i = 0; i < s->geotag_count; i++) {
 +            s->geotags[i].key    = tget_short(&s->gb, s->le);
 +            s->geotags[i].type   = tget_short(&s->gb, s->le);
 +            s->geotags[i].count  = tget_short(&s->gb, s->le);
 +
 +            if (!s->geotags[i].type)
 +                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, tget_short(&s->gb, s->le));
 +            else
 +                s->geotags[i].offset = tget_short(&s->gb, s->le);
 +        }
 +        break;
 +    case TIFF_GEO_DOUBLE_PARAMS:
 +        if (count >= INT_MAX / sizeof(int64_t))
 +            return AVERROR_INVALIDDATA;
 +        if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
 +            return AVERROR_INVALIDDATA;
 +        dp = av_malloc(count * sizeof(double));
 +        if (!dp) {
 +            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
 +            return AVERROR(ENOMEM);
 +        }
 +        for (i = 0; i < count; i++)
 +            dp[i] = tget_double(&s->gb, s->le);
 +        for (i = 0; i < s->geotag_count; i++) {
 +            if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {
 +                if (s->geotags[i].count == 0
 +                    || s->geotags[i].offset + s->geotags[i].count > count) {
 +                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
 +                } else {
 +                    char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", ");
 +                    if (!ap) {
 +                        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
 +                        av_freep(&dp);
 +                        return AVERROR(ENOMEM);
 +                    }
 +                    s->geotags[i].val = ap;
 +                }
 +            }
 +        }
 +        av_freep(&dp);
 +        break;
 +    case TIFF_GEO_ASCII_PARAMS:
 +        pos = bytestream2_tell(&s->gb);
 +        for (i = 0; i < s->geotag_count; i++) {
 +            if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) {
 +                if (s->geotags[i].count == 0
 +                    || s->geotags[i].offset +  s->geotags[i].count > count) {
 +                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
 +                } else {
 +                    char *ap;
 +
 +                    bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET);
 +                    if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count)
++                        return AVERROR_INVALIDDATA;
 +                    ap = av_malloc(s->geotags[i].count);
 +                    if (!ap) {
 +                        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
 +                        return AVERROR(ENOMEM);
 +                    }
 +                    bytestream2_get_bufferu(&s->gb, ap, s->geotags[i].count);
 +                    ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte
 +                    s->geotags[i].val = ap;
 +                }
 +            }
 +        }
 +        break;
 +    case TIFF_ARTIST:
 +        ADD_METADATA(count, "artist", NULL);
 +        break;
 +    case TIFF_COPYRIGHT:
 +        ADD_METADATA(count, "copyright", NULL);
 +        break;
 +    case TIFF_DATE:
 +        ADD_METADATA(count, "date", NULL);
 +        break;
 +    case TIFF_DOCUMENT_NAME:
 +        ADD_METADATA(count, "document_name", NULL);
 +        break;
 +    case TIFF_HOST_COMPUTER:
 +        ADD_METADATA(count, "computer", NULL);
 +        break;
 +    case TIFF_IMAGE_DESCRIPTION:
 +        ADD_METADATA(count, "description", NULL);
 +        break;
 +    case TIFF_MAKE:
 +        ADD_METADATA(count, "make", NULL);
 +        break;
 +    case TIFF_MODEL:
 +        ADD_METADATA(count, "model", NULL);
 +        break;
 +    case TIFF_PAGE_NAME:
 +        ADD_METADATA(count, "page_name", NULL);
 +        break;
 +    case TIFF_PAGE_NUMBER:
 +        ADD_METADATA(count, "page_number", " / ");
 +        break;
 +    case TIFF_SOFTWARE_NAME:
 +        ADD_METADATA(count, "software", NULL);
 +        break;
      default:
          av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n",
                 tag, tag);
@@@ -1040,63 -566,37 +1040,63 @@@ static int decode_frame(AVCodecContext 
          le = 0;
      else {
          av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      s->le = le;
 +    // TIFF_BPP is not a required tag and defaults to 1
 +    s->bppcount = s->bpp = 1;
      s->invert = 0;
      s->compr = TIFF_RAW;
      s->fill_order = 0;
 +    free_geotags(s);
 +    /* metadata has been destroyed from lavc internals, that pointer is not
 +     * valid anymore */
 +    s->picture.metadata = NULL;
 +
      // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
      // that further identifies the file as a TIFF file"
 -    if (tget_short(&buf, le) != 42) {
 +    if (tget_short(&s->gb, le) != 42) {
          av_log(avctx, AV_LOG_ERROR,
                 "The answer to life, universe and everything is not correct!\n");
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
 -    // Reset these pointers so we can tell if they were set this frame
 -    s->stripsizes = s->stripdata = NULL;
 +    // Reset these offsets so we can tell if they were set this frame
 +    s->stripsizesoff = s->strippos = 0;
      /* parse image file directory */
 -    off = tget_long(&buf, le);
 -    if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
 +    off = tget_long(&s->gb, le);
 +    if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
          av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
          return AVERROR_INVALIDDATA;
      }
 -    buf = orig_buf + off;
 -    entries = tget_short(&buf, le);
 +    bytestream2_seek(&s->gb, off, SEEK_SET);
 +    entries = tget_short(&s->gb, le);
 +    if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
 +        return AVERROR_INVALIDDATA;
      for (i = 0; i < entries; i++) {
-         if (tiff_decode_tag(s) < 0)
-             return -1;
 -        if ((ret = tiff_decode_tag(s, orig_buf, buf, end_buf)) < 0)
++        if ((ret = tiff_decode_tag(s)) < 0)
++            return ret;
 +    }
 +
 +    for (i = 0; i<s->geotag_count; i++) {
 +        const char *keyname = get_geokey_name(s->geotags[i].key);
 +        if (!keyname) {
 +            av_log(avctx, AV_LOG_WARNING, "Unknown or unsupported GeoTIFF key %d\n", s->geotags[i].key);
 +            continue;
 +        }
 +        if (get_geokey_type(s->geotags[i].key) != s->geotags[i].type) {
 +            av_log(avctx, AV_LOG_WARNING, "Type of GeoTIFF key %d is wrong\n", s->geotags[i].key);
 +            continue;
 +        }
 +        ret = av_dict_set(&s->picture.metadata, keyname, s->geotags[i].val, 0);
 +        if (ret<0) {
 +            av_log(avctx, AV_LOG_ERROR, "Writing metadata with key '%s' failed\n", keyname);
              return ret;
 -        buf += 12;
 +        }
      }
 -    if (!s->stripdata && !s->stripoff) {
 +
 +    if (!s->strippos && !s->stripoff) {
          av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      /* now we have the data and may start decoding */
      if ((ret = init_image(s)) < 0)
      }
      stride = p->linesize[0];
      dst = p->data[0];
 +
 +    if (s->stripsizesoff) {
 +        if (s->stripsizesoff >= (unsigned)avpkt->size)
 +            return AVERROR_INVALIDDATA;
 +        bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, avpkt->size - s->stripsizesoff);
 +    }
 +    if (s->strippos) {
 +        if (s->strippos >= (unsigned)avpkt->size)
 +            return AVERROR_INVALIDDATA;
 +        bytestream2_init(&stripdata, avpkt->data + s->strippos, avpkt->size - s->strippos);
 +    }
 +
 +    if (s->rps <= 0) {
 +        av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
      for (i = 0; i < s->height; i += s->rps) {
 -        if (s->stripsizes) {
 -            if (s->stripsizes >= end_buf)
 -                return AVERROR_INVALIDDATA;
 -            ssize = tget(&s->stripsizes, s->sstype, s->le);
 -        } else
 +        if (s->stripsizesoff)
 +            ssize = tget(&stripsizes, s->sstype, s->le);
 +        else
              ssize = s->stripsize;
  
 -        if (s->stripdata) {
 -            if (s->stripdata >= end_buf)
 -                return AVERROR_INVALIDDATA;
 -            soff = tget(&s->stripdata, s->sot, s->le);
 -        } else
 +        if (s->strippos)
 +            soff = tget(&stripdata, s->sot, s->le);
 +        else
              soff = s->stripoff;
  
 -        if (soff > buf_size || ssize > buf_size - soff) {
 +        if (soff > avpkt->size || ssize > avpkt->size - soff) {
              av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
-             return -1;
+             return AVERROR_INVALIDDATA;
          }
 -        if (tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize,
 +        if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize,
                                FFMIN(s->rps, s->height - i)) < 0)
              break;
          dst += s->rps * stride;
  #include "libavutil/internal.h"
  #include "libavutil/mem.h"
  
 +#define READ_PIXELS(a, b, c)         \
 +    do {                             \
 +        val  = av_le2ne32(*src++);   \
 +        *a++ =  val & 0x3FF;         \
 +        *b++ = (val >> 10) & 0x3FF;  \
 +        *c++ = (val >> 20) & 0x3FF;  \
 +    } while (0)
 +
 +static void v210_planar_unpack_c(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width)
 +{
 +    uint32_t val;
 +    int i;
 +
 +    for( i = 0; i < width-5; i += 6 ){
 +        READ_PIXELS(u, y, v);
 +        READ_PIXELS(y, u, y);
 +        READ_PIXELS(v, y, u);
 +        READ_PIXELS(y, v, y);
 +    }
 +}
 +
  static av_cold int decode_init(AVCodecContext *avctx)
  {
 +    V210DecContext *s = avctx->priv_data;
 +
      if (avctx->width & 1) {
          av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      avctx->pix_fmt             = AV_PIX_FMT_YUV422P10;
      avctx->bits_per_raw_sample = 10;
  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                          AVPacket *avpkt)
  {
 -    int h, w, ret;
 +    V210DecContext *s = avctx->priv_data;
 +
-     int h, w, stride, aligned_input;
++    int h, w, ret, stride, aligned_input;
      AVFrame *pic = avctx->coded_frame;
      const uint8_t *psrc = avpkt->data;
      uint16_t *y, *u, *v;
 -    int aligned_width = ((avctx->width + 47) / 48) * 48;
 -    int stride = aligned_width * 8 / 3;
  
 -    if (pic->data[0])
 -        avctx->release_buffer(avctx, pic);
 +    if (s->custom_stride )
 +        stride = s->custom_stride;
 +    else {
 +        int aligned_width = ((avctx->width + 47) / 48) * 48;
 +        stride = aligned_width * 8 / 3;
 +    }
  
      if (avpkt->size < stride * avctx->height) {
 -        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
 -        return AVERROR_INVALIDDATA;
 +        if ((((avctx->width + 23) / 24) * 24 * 8) / 3 * avctx->height == avpkt->size) {
 +            stride = avpkt->size / avctx->height;
 +            if (!s->stride_warning_shown)
 +                av_log(avctx, AV_LOG_WARNING, "Broken v210 with too small padding (64 byte) detected\n");
 +            s->stride_warning_shown = 1;
 +        } else {
 +            av_log(avctx, AV_LOG_ERROR, "packet too small\n");
-             return -1;
++            return AVERROR_INVALIDDATA;
 +        }
 +    }
 +
 +    aligned_input = !((uintptr_t)psrc & 0xf) && !(stride & 0xf);
 +    if (aligned_input != s->aligned_input) {
 +        s->aligned_input = aligned_input;
 +        if (HAVE_MMX)
 +            v210_x86_init(s);
      }
  
 +    if (pic->data[0])
 +        avctx->release_buffer(avctx, pic);
 +
      pic->reference = 0;
-     if (ff_get_buffer(avctx, pic) < 0)
-         return -1;
+     if ((ret = ff_get_buffer(avctx, pic)) < 0)
+         return ret;
  
      y = (uint16_t*)pic->data[0];
      u = (uint16_t*)pic->data[1];
diff --cc libavcodec/vb.c
@@@ -199,10 -199,10 +199,10 @@@ static int decode_frame(AVCodecContext 
  
      if(c->pic.data[0])
          avctx->release_buffer(avctx, &c->pic);
 -    c->pic.reference = 1;
 +    c->pic.reference = 3;
-     if(ff_get_buffer(avctx, &c->pic) < 0){
+     if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-         return -1;
+         return ret;
      }
  
      flags = bytestream2_get_le16(&c->stream);
@@@ -129,21 -129,17 +129,21 @@@ static av_cold int vqa_decode_init(AVCo
  
      /* make sure the extradata made it */
      if (s->avctx->extradata_size != VQA_HEADER_SIZE) {
 -        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: expected extradata size of %d\n", VQA_HEADER_SIZE);
 +        av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n", VQA_HEADER_SIZE);
-         return AVERROR_INVALIDDATA;
+         return AVERROR(EINVAL);
      }
  
      /* load up the VQA parameters from the header */
      s->vqa_version = s->avctx->extradata[0];
 +    if (s->vqa_version < 1 || s->vqa_version > 3) {
 +        av_log(s->avctx, AV_LOG_ERROR, "unsupported version %d\n", s->vqa_version);
 +        return AVERROR_PATCHWELCOME;
 +    }
      s->width = AV_RL16(&s->avctx->extradata[6]);
      s->height = AV_RL16(&s->avctx->extradata[8]);
-     if(av_image_check_size(s->width, s->height, 0, avctx)){
+     if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0) {
          s->width= s->height= 0;
-         return AVERROR_INVALIDDATA;
+         return ret;
      }
      s->vector_width = s->avctx->extradata[10];
      s->vector_height = s->avctx->extradata[11];
@@@ -592,8 -589,8 +592,8 @@@ static int vqa_decode_frame(AVCodecCont
      if (s->frame.data[0])
          avctx->release_buffer(avctx, &s->frame);
  
-     if ((res = ff_get_buffer(avctx, &s->frame))) {
+     if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
 -        av_log(s->avctx, AV_LOG_ERROR, "  VQA Video: get_buffer() failed\n");
 +        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
          return res;
      }