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)