[FFmpeg-devel] [PATCH 1/3] avcodec/pngdec: Use internal AVBPrint string when parsing chunks
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Wed Mar 17 18:32:00 EET 2021
One saves an allocation in case the string fits into the buffer.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
5663301560d77486c7f7c03c1aa5f542fab23c24 caused a regression that makes
some png files lose their metadata, because decode_idat_chunk() unrefs
the frame that the metadata has been attached to. I therefore tested
these commits with the aforementioned commit reverted.
libavcodec/pngdec.c | 27 ++++++++++-----------------
1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index a5a71ef161..6b9fdf5a22 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -517,7 +517,7 @@ static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
const uint8_t *data_end = data + length;
const uint8_t *keyword = data;
const uint8_t *keyword_end = memchr(keyword, 0, data_end - keyword);
- uint8_t *kw_utf8 = NULL, *text, *txt_utf8 = NULL;
+ uint8_t *kw_utf8 = NULL, *txt_utf8 = NULL;
unsigned text_len;
AVBPrint bp;
@@ -533,19 +533,16 @@ static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
return AVERROR_INVALIDDATA;
if ((ret = decode_zbuf(&bp, data, data_end)) < 0)
return ret;
+ data = bp.str;
text_len = bp.len;
- ret = av_bprint_finalize(&bp, (char **)&text);
- if (ret < 0)
- return ret;
} else {
- text = (uint8_t *)data;
- text_len = data_end - text;
+ text_len = data_end - data;
}
kw_utf8 = iso88591_to_utf8(keyword, keyword_end - keyword);
- txt_utf8 = iso88591_to_utf8(text, text_len);
- if (text != data)
- av_free(text);
+ txt_utf8 = iso88591_to_utf8(data, text_len);
+ if (compressed)
+ av_bprint_finalize(&bp, NULL);
if (!(kw_utf8 && txt_utf8)) {
av_free(kw_utf8);
av_free(txt_utf8);
@@ -851,7 +848,7 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f)
{
int ret, cnt = 0;
- uint8_t *data, profile_name[82];
+ uint8_t profile_name[82];
AVBPrint bp;
AVFrameSideData *sd;
@@ -873,19 +870,15 @@ static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f)
if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length)) < 0)
return ret;
- ret = av_bprint_finalize(&bp, (char **)&data);
- if (ret < 0)
- return ret;
-
sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len);
if (!sd) {
- av_free(data);
+ av_bprint_finalize(&bp, NULL);
return AVERROR(ENOMEM);
}
+ memcpy(sd->data, bp.str, bp.len);
+ av_bprint_finalize(&bp, NULL);
av_dict_set(&sd->metadata, "name", profile_name, 0);
- memcpy(sd->data, data, bp.len);
- av_free(data);
/* ICC compressed data and CRC */
bytestream2_skip(&s->gb, length + 4);
--
2.27.0
More information about the ffmpeg-devel
mailing list