static int apng_read_header(AVFormatContext *s)

{

    APNGDemuxContext *ctx = s->priv_data;

    AVIOContext *pb = s->pb;

    uint32_t len, tag;

    AVStream *st;

    int acTL_found = 0;

    int64_t ret = AVERROR_INVALIDDATA;



    /* verify PNGSIG */

    if (avio_rb64(pb) != PNGSIG)

        return ret;



    /* parse IHDR (must be first chunk) */

    len = avio_rb32(pb);

    tag = avio_rl32(pb);

    if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R'))

        return ret;



    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);



    /* set the timebase to something large enough (1/100,000 of second)

     * to hopefully cope with all sane frame durations */

    avpriv_set_pts_info(st, 64, 1, 100000);

    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codecpar->codec_id   = AV_CODEC_ID_APNG;

    st->codecpar->width      = avio_rb32(pb);

    st->codecpar->height     = avio_rb32(pb);

    if ((ret = av_image_check_size(st->codecpar->width, st->codecpar->height, 0, s)) < 0)

        return ret;



    /* extradata will contain every chunk up to the first fcTL (excluded) */

    ctx->extra_data = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!ctx->extra_data)

        return AVERROR(ENOMEM);

    ctx->extra_data_size = len + 12;

    AV_WB32(ctx->extra_data,    len);

    AV_WL32(ctx->extra_data+4,  tag);

    AV_WB32(ctx->extra_data+8,  st->codecpar->width);

    AV_WB32(ctx->extra_data+12, st->codecpar->height);

    if ((ret = avio_read(pb, ctx->extra_data+16, 9)) < 0)

        goto fail;



    while (!avio_feof(pb)) {

        if (acTL_found && ctx->num_play != 1) {

            int64_t size   = avio_size(pb);

            int64_t offset = avio_tell(pb);

            if (size < 0) {

                ret = size;

                goto fail;

            } else if (offset < 0) {

                ret = offset;

                goto fail;

            } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) {

                av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n");

                ctx->num_play = 1;

            }

        }

        if ((ctx->num_play == 1 || !acTL_found) &&

            ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0))

            goto fail;



        len = avio_rb32(pb);

        if (len > 0x7fffffff) {

            ret = AVERROR_INVALIDDATA;

            goto fail;

        }



        tag = avio_rl32(pb);

        switch (tag) {

        case MKTAG('a', 'c', 'T', 'L'):

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||

                (ret = append_extradata(ctx, pb, len + 12)) < 0)

                goto fail;

            acTL_found = 1;

            ctx->num_frames = AV_RB32(ctx->extra_data + ret + 8);

            ctx->num_play   = AV_RB32(ctx->extra_data + ret + 12);

            av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",

                                    ctx->num_frames, ctx->num_play);

            break;

        case MKTAG('f', 'c', 'T', 'L'):

            if (!acTL_found) {

               ret = AVERROR_INVALIDDATA;

               goto fail;

            }

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)

                goto fail;

            return 0;

        default:

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||

                (ret = append_extradata(ctx, pb, len + 12)) < 0)

                goto fail;

        }

    }



fail:

    if (ctx->extra_data_size) {

        av_freep(&ctx->extra_data);

        ctx->extra_data_size = 0;

    }

    return ret;

}

static int apng_read_header(AVFormatContext *s)

{

    APNGDemuxContext *ctx = s->priv_data;

    AVIOContext *pb = s->pb;

    uint32_t len, tag;

    AVStream *st;

    int acTL_found = 0;

    int64_t ret = AVERROR_INVALIDDATA;



    

    if (avio_rb64(pb) != PNGSIG)

        return ret;



    

    len = avio_rb32(pb);

    tag = avio_rl32(pb);

    if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R'))

        return ret;



    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);



    



    avpriv_set_pts_info(st, 64, 1, 100000);

    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codecpar->codec_id   = AV_CODEC_ID_APNG;

    st->codecpar->width      = avio_rb32(pb);

    st->codecpar->height     = avio_rb32(pb);

    if ((ret = av_image_check_size(st->codecpar->width, st->codecpar->height, 0, s)) < 0)

        return ret;



    

    ctx->extra_data = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!ctx->extra_data)

        return AVERROR(ENOMEM);

    ctx->extra_data_size = len + 12;

    AV_WB32(ctx->extra_data,    len);

    AV_WL32(ctx->extra_data+4,  tag);

    AV_WB32(ctx->extra_data+8,  st->codecpar->width);

    AV_WB32(ctx->extra_data+12, st->codecpar->height);

    if ((ret = avio_read(pb, ctx->extra_data+16, 9)) < 0)

        goto fail;



    while (!avio_feof(pb)) {

        if (acTL_found && ctx->num_play != 1) {

            int64_t size   = avio_size(pb);

            int64_t offset = avio_tell(pb);

            if (size < 0) {

                ret = size;

                goto fail;

            } else if (offset < 0) {

                ret = offset;

                goto fail;

            } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) {

                av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n");

                ctx->num_play = 1;

            }

        }

        if ((ctx->num_play == 1 || !acTL_found) &&

            ((ret = ffio_ensure_seekback(pb, 4  + 4 )) < 0))

            goto fail;



        len = avio_rb32(pb);

        if (len > 0x7fffffff) {

            ret = AVERROR_INVALIDDATA;

            goto fail;

        }



        tag = avio_rl32(pb);

        switch (tag) {

        case MKTAG('a', 'c', 'T', 'L'):

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||

                (ret = append_extradata(ctx, pb, len + 12)) < 0)

                goto fail;

            acTL_found = 1;

            ctx->num_frames = AV_RB32(ctx->extra_data + ret + 8);

            ctx->num_play   = AV_RB32(ctx->extra_data + ret + 12);

            av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",

                                    ctx->num_frames, ctx->num_play);

            break;

        case MKTAG('f', 'c', 'T', 'L'):

            if (!acTL_found) {

               ret = AVERROR_INVALIDDATA;

               goto fail;

            }

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)

                goto fail;

            return 0;

        default:

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||

                (ret = append_extradata(ctx, pb, len + 12)) < 0)

                goto fail;

        }

    }



fail:

    if (ctx->extra_data_size) {

        av_freep(&ctx->extra_data);

        ctx->extra_data_size = 0;

    }

    return ret;

}

    ctx->extra_data = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);     if (!ctx->extra_data)     ctx->extra_data_size = len + 12;     AV_WB32(ctx->extra_data,    len);     AV_WL32(ctx->extra_data+4,  tag);     AV_WB32(ctx->extra_data+8,  st->codecpar->width);     AV_WB32(ctx->extra_data+12, st->codecpar->height);     if ((ret = avio_read(pb, ctx->extra_data+16, 9)) < 0)                 (ret = append_extradata(ctx, pb, len + 12)) < 0)             ctx->num_frames = AV_RB32(ctx->extra_data + ret + 8);             ctx->num_play   = AV_RB32(ctx->extra_data + ret + 12);                 (ret = append_extradata(ctx, pb, len + 12)) < 0)     if (ctx->extra_data_size) {         av_freep(&ctx->extra_data);         ctx->extra_data_size = 0;     APNGDemuxContext *ctx = s->priv_data;
static int FUNC_0(AVFormatContext *VAR_0)

{

    APNGDemuxContext *ctx = VAR_0->priv_data;

    AVIOContext *pb = VAR_0->pb;

    uint32_t len, tag;

    AVStream *st;

    int VAR_1 = 0;

    int64_t ret = AVERROR_INVALIDDATA;



    

    if (avio_rb64(pb) != PNGSIG)

        return ret;



    

    len = avio_rb32(pb);

    tag = avio_rl32(pb);

    if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R'))

        return ret;



    st = avformat_new_stream(VAR_0, NULL);

    if (!st)

        return AVERROR(ENOMEM);



    



    avpriv_set_pts_info(st, 64, 1, 100000);

    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codecpar->codec_id   = AV_CODEC_ID_APNG;

    st->codecpar->width      = avio_rb32(pb);

    st->codecpar->height     = avio_rb32(pb);

    if ((ret = av_image_check_size(st->codecpar->width, st->codecpar->height, 0, VAR_0)) < 0)

        return ret;



    

    ctx->extra_data = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!ctx->extra_data)

        return AVERROR(ENOMEM);

    ctx->extra_data_size = len + 12;

    AV_WB32(ctx->extra_data,    len);

    AV_WL32(ctx->extra_data+4,  tag);

    AV_WB32(ctx->extra_data+8,  st->codecpar->width);

    AV_WB32(ctx->extra_data+12, st->codecpar->height);

    if ((ret = avio_read(pb, ctx->extra_data+16, 9)) < 0)

        goto fail;



    while (!avio_feof(pb)) {

        if (VAR_1 && ctx->num_play != 1) {

            int64_t size   = avio_size(pb);

            int64_t offset = avio_tell(pb);

            if (size < 0) {

                ret = size;

                goto fail;

            } else if (offset < 0) {

                ret = offset;

                goto fail;

            } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) {

                av_log(VAR_0, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n");

                ctx->num_play = 1;

            }

        }

        if ((ctx->num_play == 1 || !VAR_1) &&

            ((ret = ffio_ensure_seekback(pb, 4  + 4 )) < 0))

            goto fail;



        len = avio_rb32(pb);

        if (len > 0x7fffffff) {

            ret = AVERROR_INVALIDDATA;

            goto fail;

        }



        tag = avio_rl32(pb);

        switch (tag) {

        case MKTAG('a', 'c', 'T', 'L'):

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||

                (ret = append_extradata(ctx, pb, len + 12)) < 0)

                goto fail;

            VAR_1 = 1;

            ctx->num_frames = AV_RB32(ctx->extra_data + ret + 8);

            ctx->num_play   = AV_RB32(ctx->extra_data + ret + 12);

            av_log(VAR_0, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",

                                    ctx->num_frames, ctx->num_play);

            break;

        case MKTAG('f', 'c', 'T', 'L'):

            if (!VAR_1) {

               ret = AVERROR_INVALIDDATA;

               goto fail;

            }

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)

                goto fail;

            return 0;

        default:

            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||

                (ret = append_extradata(ctx, pb, len + 12)) < 0)

                goto fail;

        }

    }



fail:

    if (ctx->extra_data_size) {

        av_freep(&ctx->extra_data);

        ctx->extra_data_size = 0;

    }

    return ret;

}

static int FUNC_0(AVFormatContext *VAR_0)
{ APNGDemuxContext *ctx = VAR_0->priv_data; AVIOContext *pb = VAR_0->pb; uint32_t len, tag; AVStream *st; int VAR_1 = 0; int64_t ret = AVERROR_INVALIDDATA; if (avio_rb64(pb) != PNGSIG)
return ret; len = avio_rb32(pb); tag = avio_rl32(pb); if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R'))
return ret; st = avformat_new_stream(VAR_0, NULL); if (!st)
return AVERROR(ENOMEM); avpriv_set_pts_info(st, 64, 1, 100000); st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id   = AV_CODEC_ID_APNG; st->codecpar->width      = avio_rb32(pb); st->codecpar->height     = avio_rb32(pb); if ((ret = av_image_check_size(st->codecpar->width, st->codecpar->height, 0, VAR_0)) < 0)
return ret; ctx->extra_data = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE); if (!ctx->extra_data)
return AVERROR(ENOMEM); ctx->extra_data_size = len + 12; AV_WB32(ctx->extra_data,    len); AV_WL32(ctx->extra_data+4,  tag); AV_WB32(ctx->extra_data+8,  st->codecpar->width); AV_WB32(ctx->extra_data+12, st->codecpar->height); if ((ret = avio_read(pb, ctx->extra_data+16, 9)) < 0)
goto fail; while (!avio_feof(pb)) { if (VAR_1 && ctx->num_play != 1) { int64_t size   = avio_size(pb); int64_t offset = avio_tell(pb); if (size < 0) { ret = size; goto fail; } else if (offset < 0) { ret = offset; goto fail; } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) { av_log(VAR_0, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n"); ctx->num_play = 1; } } if ((ctx->num_play == 1 || !VAR_1) &&
((ret = ffio_ensure_seekback(pb, 4  + 4 )) < 0))
goto fail; len = avio_rb32(pb); if (len > 0x7fffffff) { ret = AVERROR_INVALIDDATA; goto fail; } tag = avio_rl32(pb); switch (tag) { case MKTAG('a', 'c', 'T', 'L'):
if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
(ret = append_extradata(ctx, pb, len + 12)) < 0)
goto fail; VAR_1 = 1; ctx->num_frames = AV_RB32(ctx->extra_data + ret + 8); ctx->num_play   = AV_RB32(ctx->extra_data + ret + 12); av_log(VAR_0, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",
ctx->num_frames, ctx->num_play); break; case MKTAG('f', 'c', 'T', 'L'):
if (!VAR_1) { ret = AVERROR_INVALIDDATA; goto fail; } if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
goto fail; return 0; default:
if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
(ret = append_extradata(ctx, pb, len + 12)) < 0)
goto fail; } } fail:
if (ctx->extra_data_size) { av_freep(&ctx->extra_data); ctx->extra_data_size = 0; } return ret; }