| 5167 | } |
| 5168 | |
| 5169 | avifResult avifDecoderNthImageMaxExtent(const avifDecoder * decoder, uint32_t frameIndex, avifExtent * outExtent) |
| 5170 | { |
| 5171 | if (!decoder->data) { |
| 5172 | // Nothing has been parsed yet |
| 5173 | return AVIF_RESULT_NO_CONTENT; |
| 5174 | } |
| 5175 | |
| 5176 | memset(outExtent, 0, sizeof(avifExtent)); |
| 5177 | |
| 5178 | uint32_t startFrameIndex = avifDecoderNearestKeyframe(decoder, frameIndex); |
| 5179 | uint32_t endFrameIndex = frameIndex; |
| 5180 | for (uint32_t currentFrameIndex = startFrameIndex; currentFrameIndex <= endFrameIndex; ++currentFrameIndex) { |
| 5181 | for (unsigned int tileIndex = 0; tileIndex < decoder->data->tiles.count; ++tileIndex) { |
| 5182 | avifTile * tile = &decoder->data->tiles.tile[tileIndex]; |
| 5183 | if (currentFrameIndex >= tile->input->samples.count) { |
| 5184 | return AVIF_RESULT_NO_IMAGES_REMAINING; |
| 5185 | } |
| 5186 | |
| 5187 | avifDecodeSample * sample = &tile->input->samples.sample[currentFrameIndex]; |
| 5188 | avifExtent sampleExtent; |
| 5189 | if (sample->itemID) { |
| 5190 | // The data comes from an item. Let avifDecoderItemMaxExtent() do the heavy lifting. |
| 5191 | |
| 5192 | avifDecoderItem * item; |
| 5193 | AVIF_CHECKRES(avifMetaFindOrCreateItem(decoder->data->meta, sample->itemID, &item)); |
| 5194 | avifResult maxExtentResult = avifDecoderItemMaxExtent(item, sample, &sampleExtent); |
| 5195 | if (maxExtentResult != AVIF_RESULT_OK) { |
| 5196 | return maxExtentResult; |
| 5197 | } |
| 5198 | } else { |
| 5199 | // The data likely comes from a sample table. Use the sample position directly. |
| 5200 | |
| 5201 | sampleExtent.offset = sample->offset; |
| 5202 | sampleExtent.size = sample->size; |
| 5203 | } |
| 5204 | |
| 5205 | if (sampleExtent.size > UINT64_MAX - sampleExtent.offset) { |
| 5206 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 5207 | } |
| 5208 | |
| 5209 | avifResult extentMergeResult = avifExtentMerge(outExtent, &sampleExtent); |
| 5210 | if (extentMergeResult != AVIF_RESULT_OK) { |
| 5211 | return extentMergeResult; |
| 5212 | } |
| 5213 | } |
| 5214 | } |
| 5215 | return AVIF_RESULT_OK; |
| 5216 | } |
| 5217 | |
| 5218 | static avifResult avifDecoderPrepareSample(avifDecoder * decoder, avifDecodeSample * sample, size_t partialByteCount) |
| 5219 | { |