X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fpngdec.c;h=0d6612cccafb897e1518848e6d6755b564e5998c;hb=1985071e41f4df8fc693a564e25758676bba164a;hp=083f61f4f802f240b3694fca2f12d134925e6b96;hpb=091c9860559e4d33179747c5d651bc9e31bd76eb;p=ffmpeg diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 083f61f4f80..0d6612cccaf 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -836,6 +836,49 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s, return 0; } +static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) +{ + int ret, cnt = 0; + uint8_t *data, profile_name[82]; + AVBPrint bp; + AVFrameSideData *sd; + + while ((profile_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81); + if (cnt > 80) { + av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid name!\n"); + return AVERROR_INVALIDDATA; + } + + length = FFMAX(length - cnt, 0); + + if (bytestream2_get_byte(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid compression!\n"); + return AVERROR_INVALIDDATA; + } + + length = FFMAX(length - 1, 0); + + if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length)) < 0) + return ret; + + av_bprint_finalize(&bp, (char **)&data); + + sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len); + if (!sd) { + av_free(data); + return AVERROR(ENOMEM); + } + + 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); + + return 0; +} + static void handle_small_bpp(PNGDecContext *s, AVFrame *p) { if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) { @@ -1239,6 +1282,11 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, bytestream2_skip(&s->gb, 4); /* crc */ break; } + case MKTAG('i', 'C', 'C', 'P'): { + if (decode_iccp_chunk(s, length, p) < 0) + goto fail; + break; + } case MKTAG('I', 'E', 'N', 'D'): if (!(s->pic_state & PNG_ALLIMAGE)) av_log(avctx, AV_LOG_ERROR, "IEND without all image\n"); @@ -1366,7 +1414,7 @@ static int decode_frame_png(AVCodecContext *avctx, } if ((ret = av_frame_ref(data, s->picture.f)) < 0) - return ret; + goto the_end; *got_frame = 1;