static int decode_zbuf(AVBPrint *bp, const uint8_t *data,

                       const uint8_t *data_end)

{

    z_stream zstream;

    unsigned char *buf;

    unsigned buf_size;

    int ret;



    zstream.zalloc = ff_png_zalloc;

    zstream.zfree  = ff_png_zfree;

    zstream.opaque = NULL;

    if (inflateInit(&zstream) != Z_OK)

        return AVERROR_EXTERNAL;

    zstream.next_in  = (unsigned char *)data;

    zstream.avail_in = data_end - data;

    av_bprint_init(bp, 0, -1);



    while (zstream.avail_in > 0) {

        av_bprint_get_buffer(bp, 1, &buf, &buf_size);

        if (!buf_size) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        zstream.next_out  = buf;

        zstream.avail_out = buf_size;

        ret = inflate(&zstream, Z_PARTIAL_FLUSH);

        if (ret != Z_OK && ret != Z_STREAM_END) {

            ret = AVERROR_EXTERNAL;

            goto fail;

        }

        bp->len += zstream.next_out - buf;

        if (ret == Z_STREAM_END)

            break;

    }

    inflateEnd(&zstream);

    bp->str[bp->len] = 0;

    return 0;



fail:

    inflateEnd(&zstream);

    av_bprint_finalize(bp, NULL);

    return ret;

}
