int fill_order;
uint32_t res[4];
int is_thumbnail;
+ unsigned last_tag;
int is_bayer;
uint8_t pattern[4];
if (is_dng) {
int is_u16, pixel_size_bytes, pixel_size_bits, elements;
- is_u16 = (s->bpp > 8);
+ is_u16 = (s->bpp / s->bppcount > 8);
pixel_size_bits = (is_u16 ? 16 : 8);
pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t));
int is_single_comp, is_u16, pixel_size;
int ret;
+ if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb))
+ return AVERROR_INVALIDDATA;
+
/* Prepare a packet and send to the MJPEG decoder */
av_init_packet(&jpkt);
jpkt.data = (uint8_t*)s->gb.buffer;
/* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */
+ if (s->jpgframe->width != s->avctx_mjpeg->width ||
+ s->jpgframe->height != s->avctx_mjpeg->height ||
+ s->jpgframe->format != s->avctx_mjpeg->pix_fmt)
+ return AVERROR_INVALIDDATA;
+
/* See dng_blit for explanation */
if (s->avctx_mjpeg->width == w * 2 &&
s->avctx_mjpeg->height == h / 2 &&
s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) {
is_single_comp = 1;
- } else if (s->avctx_mjpeg->width == w &&
- s->avctx_mjpeg->height == h &&
+ } else if (s->avctx_mjpeg->width >= w &&
+ s->avctx_mjpeg->height >= h &&
s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8)
) {
is_single_comp = 0;
if (ret < 0) {
goto end;
}
+ if (tag <= s->last_tag)
+ return AVERROR_INVALIDDATA;
+
+ // We ignore TIFF_STRIP_SIZE as it is sometimes in the logic but wrong order around TIFF_STRIP_OFFS
+ if (tag != TIFF_STRIP_SIZE)
+ s->last_tag = tag;
off = bytestream2_tell(&s->gb);
if (count == 1) {
s->height = value;
break;
case TIFF_BPP:
- if (count > 5U) {
+ if (count > 5 || count <= 0) {
av_log(s->avctx, AV_LOG_ERROR,
"This format is not supported (bpp=%d, %d components)\n",
value, count);
"Samples per pixel requires a single value, many provided\n");
return AVERROR_INVALIDDATA;
}
- if (value > 5U) {
+ if (value > 5 || value <= 0) {
av_log(s->avctx, AV_LOG_ERROR,
- "Samples per pixel %d is too large\n", value);
+ "Invalid samples per pixel %d\n", value);
return AVERROR_INVALIDDATA;
}
if (s->bppcount == 1)
s->sub_ifd = ff_tget(&s->gb, TIFF_LONG, s->le); /** Only get the first SubIFD */
break;
case DNG_LINEARIZATION_TABLE:
- for (int i = 0; i < FFMIN(count, 1 << s->bpp); i++)
+ if (count > FF_ARRAY_ELEMS(s->dng_lut))
+ return AVERROR_INVALIDDATA;
+ for (int i = 0; i < count; i++)
s->dng_lut[i] = ff_tget(&s->gb, type, s->le);
break;
case DNG_BLACK_LEVEL:
break;
case TIFF_GEO_KEY_DIRECTORY:
if (s->geotag_count) {
- avpriv_request_sample(s->avctx, "Multiple geo key directories\n");
+ avpriv_request_sample(s->avctx, "Multiple geo key directories");
return AVERROR_INVALIDDATA;
}
ADD_METADATA(1, "GeoTIFF_Version", NULL);
}
break;
case TIFF_ICC_PROFILE:
- if (type != TIFF_UNDEFINED)
- return AVERROR_INVALIDDATA;
-
gb_temp = s->gb;
bytestream2_seek(&gb_temp, SEEK_SET, off);
s->is_tiled = 0;
s->is_jpeg = 0;
s->cur_page = 0;
+ s->last_tag = 0;
for (i = 0; i < 65536; i++)
s->dng_lut[i] = i;
return AVERROR_INVALIDDATA;
}
if (off <= last_off) {
- avpriv_request_sample(s->avctx, "non increasing IFD offset\n");
+ avpriv_request_sample(s->avctx, "non increasing IFD offset");
return AVERROR_INVALIDDATA;
}
if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
if (is_dng) {
int bps;
+ if (s->bpp % s->bppcount)
+ return AVERROR_INVALIDDATA;
+ bps = s->bpp / s->bppcount;
+ if (bps < 8 || bps > 32)
+ return AVERROR_INVALIDDATA;
+
if (s->white_level == 0)
- s->white_level = (1 << s->bpp) - 1; /* Default value as per the spec */
+ s->white_level = (1LL << bps) - 1; /* Default value as per the spec */
if (s->white_level <= s->black_level) {
av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less than WhiteLevel (%"PRId32")\n",
return AVERROR_INVALIDDATA;
}
- if (s->bpp % s->bppcount)
- return AVERROR_INVALIDDATA;
- bps = s->bpp / s->bppcount;
- if (bps < 8 || bps > 32)
- return AVERROR_INVALIDDATA;
if (s->planar)
return AVERROR_PATCHWELCOME;
}
has_strip_bits = s->strippos || s->strips || s->stripoff || s->rps || s->sot || s->sstype || s->stripsize || s->stripsizesoff;
if (has_tile_bits && has_strip_bits) {
- av_log(avctx, AV_LOG_ERROR, "Tiled TIFF is not allowed to strip\n");
- return AVERROR_INVALIDDATA;
+ av_log(avctx, AV_LOG_WARNING, "Tiled TIFF is not allowed to strip\n");
}
/* now we have the data and may start decoding */
s->avctx_mjpeg->flags2 = avctx->flags2;
s->avctx_mjpeg->dct_algo = avctx->dct_algo;
s->avctx_mjpeg->idct_algo = avctx->idct_algo;
- ret = ff_codec_open2_recursive(s->avctx_mjpeg, codec, NULL);
+ ret = avcodec_open2(s->avctx_mjpeg, codec, NULL);
if (ret < 0) {
return ret;
}
.close = tiff_end,
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
.priv_class = &tiff_decoder_class,
};