mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-29 22:00:58 +02:00
pngdec: decode and expose iCCP chunks as side data
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
This commit is contained in:
parent
24de4fddca
commit
2e08bbb282
@ -836,6 +836,46 @@ 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);
|
||||
|
||||
if (!(sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len)))
|
||||
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 +1279,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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user