OSDN Git Service

Merge commit 'c453723ad7d14abc5e82677eebaa6025fa598f08'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 22 Nov 2013 09:56:42 +0000 (10:56 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 22 Nov 2013 09:57:41 +0000 (10:57 +0100)
* commit 'c453723ad7d14abc5e82677eebaa6025fa598f08':
  gifdec: check that the image dimensions are non-zero

Conflicts:
libavcodec/gifdec.c

See: 286930d302fd34cfc2541bfdd760a8bbf9f2d2e5
Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/gifdec.c

@@@ -181,55 -87,33 +181,57 @@@ static int gif_read_image(GifState *s, 
  
      /* verify that all the image is inside the screen dimensions */
      if (left + width > s->screen_width ||
 -        top + height > s->screen_height ||
 -        !width || !height) {
 +        top + height > s->screen_height)
 +        return AVERROR_INVALIDDATA;
-     if (width <= 0 || height <= 0)
++    if (width <= 0 || height <= 0) {
+         av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n");
          return AVERROR_INVALIDDATA;
+     }
  
 -    /* build the palette */
 -    n = (1 << bits_per_pixel);
 -    spal = palette;
 -    for(i = 0; i < n; i++) {
 -        s->image_palette[i] = (0xffu << 24) | AV_RB24(spal);
 -        spal += 3;
 +    /* process disposal method */
 +    if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) {
 +        gif_fill_rect(frame, s->stored_bg_color, s->gce_l, s->gce_t, s->gce_w, s->gce_h);
 +    } else if (s->gce_prev_disposal == GCE_DISPOSAL_RESTORE) {
 +        gif_copy_img_rect(s->stored_img, (uint32_t *)frame->data[0],
 +            frame->linesize[0] / sizeof(uint32_t), s->gce_l, s->gce_t, s->gce_w, s->gce_h);
      }
 -    for(; i < 256; i++)
 -        s->image_palette[i] = (0xffu << 24);
 -    /* handle transparency */
 -    if (s->transparent_color_index >= 0)
 -        s->image_palette[s->transparent_color_index] = 0;
 +
 +    s->gce_prev_disposal = s->gce_disposal;
 +
 +    if (s->gce_disposal != GCE_DISPOSAL_NONE) {
 +        s->gce_l = left;  s->gce_t = top;
 +        s->gce_w = width; s->gce_h = height;
 +
 +        if (s->gce_disposal == GCE_DISPOSAL_BACKGROUND) {
 +            if (s->transparent_color_index >= 0)
 +                s->stored_bg_color = s->trans_color;
 +            else
 +                s->stored_bg_color = s->bg_color;
 +        } else if (s->gce_disposal == GCE_DISPOSAL_RESTORE) {
 +            av_fast_malloc(&s->stored_img, &s->stored_img_size, frame->linesize[0] * frame->height);
 +            if (!s->stored_img)
 +                return AVERROR(ENOMEM);
 +
 +            gif_copy_img_rect((uint32_t *)frame->data[0], s->stored_img,
 +                frame->linesize[0] / sizeof(uint32_t), left, top, width, height);
 +        }
 +    }
 +
 +    /* Expect at least 2 bytes: 1 for lzw code size and 1 for block size. */
 +    if (bytestream2_get_bytes_left(&s->gb) < 2)
 +        return AVERROR_INVALIDDATA;
  
      /* now get the image data */
 -    code_size = bytestream_get_byte(&s->bytestream);
 -    ff_lzw_decode_init(s->lzw, code_size, s->bytestream,
 -                       s->bytestream_end - s->bytestream, FF_LZW_GIF);
 +    code_size = bytestream2_get_byteu(&s->gb);
 +    if ((ret = ff_lzw_decode_init(s->lzw, code_size, s->gb.buffer,
 +                                  bytestream2_get_bytes_left(&s->gb), FF_LZW_GIF)) < 0) {
 +        av_log(s->avctx, AV_LOG_ERROR, "LZW init failed\n");
 +        return ret;
 +    }
  
      /* read all the image */
 -    linesize = frame->linesize[0];
 -    ptr1 = frame->data[0] + top * linesize + left;
 +    linesize = frame->linesize[0] / sizeof(uint32_t);
 +    ptr1 = (uint32_t *)frame->data[0] + top * linesize + left;
      ptr = ptr1;
      pass = 0;
      y1 = 0;