Merge commit '0e8ae6d10c609bb968c141aa2436413a55852590' into release/1.1
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 12 Jan 2014 15:01:50 +0000 (16:01 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 12 Jan 2014 15:08:27 +0000 (16:08 +0100)
* commit '0e8ae6d10c609bb968c141aa2436413a55852590':
  mpegvideo: Drop a faulty assert
  lavr: check that current_buffer is not NULL before using it
  pmpdec: check that there is at least one audio packet.
  lzw: switch to bytestream2
  gifdec: convert to bytestream2

Conflicts:
libavcodec/gifdec.c
libavcodec/lzw.c
libavcodec/lzw.h
libavformat/pmpdec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/gifdec.c
libavcodec/lzw.c
libavformat/pmpdec.c
libavresample/utils.c

@@@ -48,25 -41,15 +48,25 @@@ typedef struct GifState 
      int background_color_index;
      int transparent_color_index;
      int color_resolution;
 -    uint32_t *image_palette;
 +    /* intermediate buffer for storing color indices
 +     * obtained from lzw-encoded data stream */
 +    uint8_t *idx_line;
 +    int idx_line_size;
  
      /* after the frame is displayed, the disposal method is used */
 +    int gce_prev_disposal;
      int gce_disposal;
 -    /* delay during which the frame is shown */
 -    int gce_delay;
 +    /* rectangle describing area that must be disposed */
 +    int gce_l, gce_t, gce_w, gce_h;
 +    /* depending on disposal method we store either part of the image
 +     * drawn on the canvas or background color that
 +     * should be used upon disposal */
 +    uint32_t * stored_img;
 +    int stored_img_size;
 +    int stored_bg_color;
  
-     GetByteContext gb;
      /* LZW compatible decoder */
+     GetByteContext gb;
      LZWState *lzw;
  
      /* aux buffers */
@@@ -135,20 -65,14 +135,20 @@@ static void gif_copy_img_rect(const uin
  static int gif_read_image(GifState *s)
  {
      int left, top, width, height, bits_per_pixel, code_size, flags;
 -    int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i;
 -    uint8_t *ptr, *spal, *palette, *ptr1;
 -
 -    left   = bytestream2_get_le16(&s->gb);
 -    top    = bytestream2_get_le16(&s->gb);
 -    width  = bytestream2_get_le16(&s->gb);
 -    height = bytestream2_get_le16(&s->gb);
 -    flags  = bytestream2_get_byte(&s->gb);
 +    int is_interleaved, has_local_palette, y, pass, y1, linesize, pal_size;
 +    uint32_t *ptr, *pal, *px, *pr, *ptr1;
 +    int ret;
 +    uint8_t *idx;
 +
 +    /* At least 9 bytes of Image Descriptor. */
 +    if (bytestream2_get_bytes_left(&s->gb) < 9)
 +        return AVERROR_INVALIDDATA;
 +
-     left = bytestream2_get_le16u(&s->gb);
-     top = bytestream2_get_le16u(&s->gb);
-     width = bytestream2_get_le16u(&s->gb);
++    left   = bytestream2_get_le16u(&s->gb);
++    top    = bytestream2_get_le16u(&s->gb);
++    width  = bytestream2_get_le16u(&s->gb);
 +    height = bytestream2_get_le16u(&s->gb);
-     flags = bytestream2_get_byteu(&s->gb);
++    flags  = bytestream2_get_byteu(&s->gb);
      is_interleaved = flags & 0x40;
      has_local_palette = flags & 0x80;
      bits_per_pixel = (flags & 0x07) + 1;
  
  static int gif_read_extension(GifState *s)
  {
 -    int ext_code, ext_len, i, gce_flags, gce_transparent_index;
 +    int ext_code, ext_len, gce_flags, gce_transparent_index;
 +
 +    /* There must be at least 2 bytes:
 +     * 1 for extension label and 1 for extension length. */
 +    if (bytestream2_get_bytes_left(&s->gb) < 2)
 +        return AVERROR_INVALIDDATA;
  
 -    /* extension */
 -    ext_code = bytestream2_get_byte(&s->gb);
 -    ext_len  = bytestream2_get_byte(&s->gb);
 +    ext_code = bytestream2_get_byteu(&s->gb);
 +    ext_len = bytestream2_get_byteu(&s->gb);
  
 -    av_dlog(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len);
 +    av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len);
  
      switch(ext_code) {
 -    case 0xf9:
 +    case GIF_GCE_EXT_LABEL:
          if (ext_len != 4)
              goto discard_ext;
 -        s->transparent_color_index = -1;
 -        gce_flags    = bytestream2_get_byte(&s->gb);
 -        s->gce_delay = bytestream2_get_le16(&s->gb);
 -        gce_transparent_index = bytestream2_get_byte(&s->gb);
 +
 +        /* We need at least 5 bytes more: 4 is for extension body
 +         * and 1 for next block size. */
 +        if (bytestream2_get_bytes_left(&s->gb) < 5)
 +            return AVERROR_INVALIDDATA;
 +
-         gce_flags = bytestream2_get_byteu(&s->gb);
++        gce_flags    = bytestream2_get_byteu(&s->gb);
 +        bytestream2_skipu(&s->gb, 2);    // delay during which the frame is shown
 +        gce_transparent_index = bytestream2_get_byteu(&s->gb);
          if (gce_flags & 0x01)
              s->transparent_color_index = gce_transparent_index;
          else
@@@ -371,11 -220,11 +371,11 @@@ static int gif_read_header1(GifState *s
  
      /* read screen header */
      s->transparent_color_index = -1;
-     s->screen_width = bytestream2_get_le16u(&s->gb);
 -    s->screen_width  = bytestream2_get_le16(&s->gb);
 -    s->screen_height = bytestream2_get_le16(&s->gb);
++    s->screen_width  = bytestream2_get_le16u(&s->gb);
 +    s->screen_height = bytestream2_get_le16u(&s->gb);
      if(   (unsigned)s->screen_width  > 32767
         || (unsigned)s->screen_height > 32767){
 -        av_log(NULL, AV_LOG_ERROR, "picture size too large\n");
 +        av_log(s->avctx, AV_LOG_ERROR, "picture size too large\n");
          return AVERROR_INVALIDDATA;
      }
  
      return 0;
  }
  
 -static int gif_parse_next_image(GifState *s)
 +static int gif_parse_next_image(GifState *s, int *got_picture)
  {
-     while (bytestream2_get_bytes_left(&s->gb)) {
 +    *got_picture = 1;
+     while (bytestream2_get_bytes_left(&s->gb) > 0) {
          int code = bytestream2_get_byte(&s->gb);
          int ret;
  
@@@ -460,63 -295,29 +460,63 @@@ static int gif_decode_frame(AVCodecCont
      AVFrame *picture = data;
      int ret;
  
 -    bytestream2_init(&s->gb, buf, buf_size);
 -    if ((ret = gif_read_header1(s)) < 0)
 -        return ret;
 +    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
  
-     s->picture.pts          = avpkt->pts;
-     s->picture.pkt_pts      = avpkt->pts;
-     s->picture.pkt_dts      = avpkt->dts;
 -    avctx->pix_fmt = AV_PIX_FMT_PAL8;
 -    if ((ret = av_image_check_size(s->screen_width, s->screen_height, 0, avctx)) < 0)
 -        return ret;
 -    avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
++    s->picture.pts     = avpkt->pts;
++    s->picture.pkt_pts = avpkt->pts;
++    s->picture.pkt_dts = avpkt->dts;
 +    s->picture.pkt_duration = avpkt->duration;
  
 -    if (s->picture.data[0])
 -        avctx->release_buffer(avctx, &s->picture);
 -    if ((ret = ff_get_buffer(avctx, &s->picture)) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 -        return ret;
 +    if (avpkt->size >= 6) {
 +        s->keyframe = memcmp(avpkt->data, gif87a_sig, 6) == 0 ||
 +                      memcmp(avpkt->data, gif89a_sig, 6) == 0;
 +    } else {
 +        s->keyframe = 0;
 +    }
 +
 +    if (s->keyframe) {
 +        s->keyframe_ok = 0;
 +        s->gce_prev_disposal = GCE_DISPOSAL_NONE;
 +        if ((ret = gif_read_header1(s)) < 0)
 +            return ret;
 +
 +        if ((ret = av_image_check_size(s->screen_width, s->screen_height, 0, avctx)) < 0)
 +            return ret;
 +        avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
 +
 +        if (s->picture.data[0])
 +            avctx->release_buffer(avctx, &s->picture);
 +
 +        if ((ret = ff_get_buffer(avctx, &s->picture)) < 0) {
 +            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +            return ret;
 +        }
 +
 +        s->picture.pict_type = AV_PICTURE_TYPE_I;
 +        s->picture.key_frame = 1;
 +        s->keyframe_ok = 1;
 +    } else {
 +        if (!s->keyframe_ok) {
 +            av_log(avctx, AV_LOG_ERROR, "cannot decode frame without keyframe\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +
 +        if ((ret = avctx->reget_buffer(avctx, &s->picture)) < 0) {
 +            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
 +            return ret;
 +        }
 +
 +        s->picture.pict_type = AV_PICTURE_TYPE_P;
 +        s->picture.key_frame = 0;
      }
 -    s->image_palette = (uint32_t *)s->picture.data[1];
 -    ret = gif_parse_next_image(s);
 +
 +    ret = gif_parse_next_image(s, got_frame);
      if (ret < 0)
          return ret;
 +    else if (*got_frame)
 +        *picture = s->picture;
  
-     return avpkt->size;
 -    *picture = s->picture;
 -    *got_frame = 1;
+     return bytestream2_tell(&s->gb);
  }
  
  static av_cold int gif_decode_close(AVCodecContext *avctx)
Simple merge
Simple merge
Simple merge