| 5286 | } |
| 5287 | |
| 5288 | avifResult avifDecoderParse(avifDecoder * decoder) |
| 5289 | { |
| 5290 | avifDiagnosticsClearError(&decoder->diag); |
| 5291 | |
| 5292 | // An imageSizeLimit greater than AVIF_DEFAULT_IMAGE_SIZE_LIMIT and the special value of 0 to |
| 5293 | // disable the limit are not yet implemented. |
| 5294 | if ((decoder->imageSizeLimit > AVIF_DEFAULT_IMAGE_SIZE_LIMIT) || (decoder->imageSizeLimit == 0)) { |
| 5295 | return AVIF_RESULT_NOT_IMPLEMENTED; |
| 5296 | } |
| 5297 | // Color only or alpha only is not currently supported. |
| 5298 | if ((decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA) != 0 && |
| 5299 | (decoder->imageContentToDecode & AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA) != AVIF_IMAGE_CONTENT_COLOR_AND_ALPHA) { |
| 5300 | avifDiagnosticsPrintf(&decoder->diag, "imageContentToDecode set to only color or only alpha is not supported"); |
| 5301 | return AVIF_RESULT_NOT_IMPLEMENTED; |
| 5302 | } |
| 5303 | if (!decoder->io || !decoder->io->read) { |
| 5304 | return AVIF_RESULT_IO_NOT_SET; |
| 5305 | } |
| 5306 | |
| 5307 | // Cleanup anything lingering in the decoder |
| 5308 | avifDecoderCleanup(decoder); |
| 5309 | |
| 5310 | // ----------------------------------------------------------------------- |
| 5311 | // Parse BMFF boxes |
| 5312 | |
| 5313 | decoder->data = avifDecoderDataCreate(); |
| 5314 | AVIF_CHECKERR(decoder->data != NULL, AVIF_RESULT_OUT_OF_MEMORY); |
| 5315 | decoder->data->diag = &decoder->diag; |
| 5316 | |
| 5317 | AVIF_CHECKRES(avifParse(decoder)); |
| 5318 | |
| 5319 | // Walk the decoded items (if any) and harvest ispe |
| 5320 | avifDecoderData * data = decoder->data; |
| 5321 | for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) { |
| 5322 | avifDecoderItem * item = data->meta->items.item[itemIndex]; |
| 5323 | if (avifDecoderItemShouldBeSkipped(item)) { |
| 5324 | continue; |
| 5325 | } |
| 5326 | |
| 5327 | const avifProperty * ispeProp = avifPropertyArrayFind(&item->properties, "ispe"); |
| 5328 | if (ispeProp) { |
| 5329 | item->width = ispeProp->u.ispe.width; |
| 5330 | item->height = ispeProp->u.ispe.height; |
| 5331 | |
| 5332 | if ((item->width == 0) || (item->height == 0)) { |
| 5333 | avifDiagnosticsPrintf(data->diag, "Item ID [%u] has an invalid size [%ux%u]", item->id, item->width, item->height); |
| 5334 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 5335 | } |
| 5336 | if (avifDimensionsTooLarge(item->width, item->height, decoder->imageSizeLimit, decoder->imageDimensionLimit)) { |
| 5337 | avifDiagnosticsPrintf(data->diag, "Item ID [%u] dimensions are too large [%ux%u]", item->id, item->width, item->height); |
| 5338 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 5339 | } |
| 5340 | } else { |
| 5341 | const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC"); |
| 5342 | if (auxCProp && isAlphaURN(auxCProp->u.auxC.auxType)) { |
| 5343 | if (decoder->strictFlags & AVIF_STRICT_ALPHA_ISPE_REQUIRED) { |
| 5344 | avifDiagnosticsPrintf(data->diag, |
| 5345 | "[Strict] Alpha auxiliary image item ID [%u] is missing a mandatory ispe property", |