Only consider a frame index to be a keyframe if all tiles/planes are sync frames
Related: https://crbug.com/1274200
diff --git a/src/read.c b/src/read.c
index 7289f8c..3ca86a5 100644
--- a/src/read.c
+++ b/src/read.c
@@ -3874,17 +3874,22 @@
avifBool avifDecoderIsKeyframe(const avifDecoder * decoder, uint32_t frameIndex)
{
- if (!decoder->data) {
+ if (!decoder->data || (decoder->data->tiles.count == 0)) {
// Nothing has been parsed yet
return AVIF_FALSE;
}
- if ((decoder->data->tiles.count > 0) && decoder->data->tiles.tile[0].input) {
- if (frameIndex < decoder->data->tiles.tile[0].input->samples.count) {
- return decoder->data->tiles.tile[0].input->samples.sample[frameIndex].sync;
+ // *All* tiles for the requested frameIndex must be keyframes in order for
+ // avifDecoderIsKeyframe() to return true, otherwise we may seek to a frame in which the color
+ // planes are a keyframe but the alpha plane isn't a keyframe, which will cause an alpha plane
+ // decode failure.
+ for (unsigned int i = 0; i < decoder->data->tiles.count; ++i) {
+ const avifTile * tile = &decoder->data->tiles.tile[i];
+ if ((frameIndex >= tile->input->samples.count) || !tile->input->samples.sample[frameIndex].sync) {
+ return AVIF_FALSE;
}
}
- return AVIF_FALSE;
+ return AVIF_TRUE;
}
uint32_t avifDecoderNearestKeyframe(const avifDecoder * decoder, uint32_t frameIndex)