}
if (!(s->pic_state & PNG_IDAT)) {
/* init image info */
- avctx->width = s->width;
- avctx->height = s->height;
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
s->channels = ff_png_get_nb_channels(s->color_type);
s->bits_per_pixel = s->bit_depth * s->channels;
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) {
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");