Merge commit '4fee11ab05fc8569ef35c0ce86a60375c903eefb'
authorHendrik Leppkes <h.leppkes@gmail.com>
Wed, 5 Aug 2015 10:10:08 +0000 (12:10 +0200)
committerHendrik Leppkes <h.leppkes@gmail.com>
Wed, 5 Aug 2015 10:10:08 +0000 (12:10 +0200)
* commit '4fee11ab05fc8569ef35c0ce86a60375c903eefb':
  png: Be more informative regarding signature errors

Conflicts:
libavcodec/pngdec.c

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
1  2 
libavcodec/pngdec.c

@@@ -1118,80 -621,25 +1118,80 @@@ skip_tag
          }
      }
  exit_loop:
 +
 +    if (s->bits_per_pixel <= 4)
 +        handle_small_bpp(s, p);
 +
      /* handle p-frames only if a predecessor frame is available */
 -    if (s->prev->data[0]) {
 -        if (!(avpkt->flags & AV_PKT_FLAG_KEY)) {
 -            int i, j;
 -            uint8_t *pd      = p->data[0];
 -            uint8_t *pd_last = s->prev->data[0];
 -
 -            for (j = 0; j < s->height; j++) {
 -                for (i = 0; i < s->width * s->bpp; i++)
 -                    pd[i] += pd_last[i];
 -                pd      += s->image_linesize;
 -                pd_last += s->image_linesize;
 -            }
 +    if (s->last_picture.f->data[0]) {
 +        if (   !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG")
 +            && s->last_picture.f->width == p->width
 +            && s->last_picture.f->height== p->height
 +            && s->last_picture.f->format== p->format
 +         ) {
 +            if (CONFIG_PNG_DECODER && avctx->codec_id != AV_CODEC_ID_APNG)
 +                handle_p_frame_png(s, p);
 +            else if (CONFIG_APNG_DECODER &&
 +                     avctx->codec_id == AV_CODEC_ID_APNG &&
 +                     (ret = handle_p_frame_apng(avctx, s, p)) < 0)
 +                goto fail;
          }
      }
 +    ff_thread_report_progress(&s->picture, INT_MAX, 0);
 +
 +    av_frame_set_metadata(p, metadata);
 +    metadata   = NULL;
 +    return 0;
  
 -    av_frame_unref(s->prev);
 -    if ((ret = av_frame_ref(s->prev, p)) < 0)
 -        goto fail;
 +fail:
 +    av_dict_free(&metadata);
 +    ff_thread_report_progress(&s->picture, INT_MAX, 0);
 +    return ret;
 +}
 +
 +#if CONFIG_PNG_DECODER
 +static int decode_frame_png(AVCodecContext *avctx,
 +                        void *data, int *got_frame,
 +                        AVPacket *avpkt)
 +{
 +    PNGDecContext *const s = avctx->priv_data;
 +    const uint8_t *buf     = avpkt->data;
 +    int buf_size           = avpkt->size;
 +    AVFrame *p;
 +    int64_t sig;
 +    int ret;
 +
 +    ff_thread_release_buffer(avctx, &s->last_picture);
 +    FFSWAP(ThreadFrame, s->picture, s->last_picture);
 +    p = s->picture.f;
 +
 +    bytestream2_init(&s->gb, buf, buf_size);
 +
 +    /* check signature */
 +    sig = bytestream2_get_be64(&s->gb);
 +    if (sig != PNGSIG &&
 +        sig != MNGSIG) {
-         av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature (%d).\n", buf_size);
++        av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature 0x%08"PRIX64".\n", sig);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    s->y = s->state = 0;
 +
 +    /* init the zlib */
 +    s->zstream.zalloc = ff_png_zalloc;
 +    s->zstream.zfree  = ff_png_zfree;
 +    s->zstream.opaque = NULL;
 +    ret = inflateInit(&s->zstream);
 +    if (ret != Z_OK) {
 +        av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
 +        return AVERROR_EXTERNAL;
 +    }
 +
 +    if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
 +        goto the_end;
 +
 +    if ((ret = av_frame_ref(data, s->picture.f)) < 0)
 +        return ret;
  
      *got_frame = 1;