Add avifDecoderFindItem() in read.c Refactor read.c.
diff --git a/src/read.c b/src/read.c index 43d26be..1e957f1 100644 --- a/src/read.c +++ b/src/read.c
@@ -3389,6 +3389,42 @@ return AVIF_RESULT_OK; } +// If alpha is AVIF_TRUE, searches for the primary color item (parentItemID is ignored in this case). +// If alpha is AVIF_FALSE, searches for the auxiliary alpha item whose parent item ID is parentItemID. +// Returns the target item if found, or NULL. +static avifDecoderItem * avifDecoderDataFindItem(avifDecoderData * data, avifBool alpha, uint32_t parentItemID) +{ + for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) { + avifDecoderItem * item = &data->meta->items.item[itemIndex]; + if (!item->size) { + continue; + } + if (item->hasUnsupportedEssentialProperty) { + // An essential property isn't supported by libavif; ignore the item. + continue; + } + if (memcmp(item->type, "av01", 4) && memcmp(item->type, "grid", 4)) { + // Probably exif or some other data. + continue; + } + if (item->thumbnailForID != 0) { + // It's a thumbnail, skip it. + continue; + } + if (!alpha && (item->id == data->meta->primaryItemID)) { + return item; + } + if (alpha && (item->auxForID == parentItemID)) { + // Is this an alpha auxiliary item of the parent color item? + const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC"); + if (auxCProp && isAlphaURN(auxCProp->u.auxC.auxType)) { + return item; + } + } + } + return NULL; +} + avifResult avifDecoderReset(avifDecoder * decoder) { avifDiagnosticsClearError(&decoder->diag); @@ -3561,103 +3597,41 @@ } else { // Create from items - avifDecoderItem * colorItem = NULL; - avifDecoderItem * alphaItem = NULL; - if (data->meta->primaryItemID == 0) { // A primary item is required avifDiagnosticsPrintf(&decoder->diag, "Primary item not specified"); return AVIF_RESULT_NO_AV1_ITEMS_FOUND; } - // Find the colorOBU (primary) item - for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) { - avifDecoderItem * item = &data->meta->items.item[itemIndex]; - if (!item->size) { - continue; - } - if (item->hasUnsupportedEssentialProperty) { - // An essential property isn't supported by libavif; ignore the item. - continue; - } - avifBool isGrid = (memcmp(item->type, "grid", 4) == 0); - if (memcmp(item->type, "av01", 4) && !isGrid) { - // probably exif or some other data - continue; - } - if (item->thumbnailForID != 0) { - // It's a thumbnail, skip it - continue; - } - if (item->id != data->meta->primaryItemID) { - // This is not the primary item, skip it - continue; - } - - if (isGrid) { - avifROData readData; - avifResult readResult = avifDecoderItemRead(item, decoder->io, &readData, 0, 0, data->diag); - if (readResult != AVIF_RESULT_OK) { - return readResult; - } - if (!avifParseImageGridBox(&data->colorGrid, - readData.data, - readData.size, - decoder->imageSizeLimit, - decoder->imageDimensionLimit, - data->diag)) { - return AVIF_RESULT_INVALID_IMAGE_GRID; - } - } - - colorItem = item; - break; - } - + avifDecoderItem * colorItem = avifDecoderDataFindItem(data, /*alpha=*/AVIF_FALSE, /*parentItemID=*/0); if (!colorItem) { avifDiagnosticsPrintf(&decoder->diag, "Primary item not found"); return AVIF_RESULT_NO_AV1_ITEMS_FOUND; } colorProperties = &colorItem->properties; + if (!memcmp(colorItem->type, "grid", 4)) { + avifROData readData; + AVIF_CHECKRES(avifDecoderItemRead(colorItem, decoder->io, &readData, 0, 0, data->diag)); + AVIF_CHECKERR(avifParseImageGridBox(&data->colorGrid, + readData.data, + readData.size, + decoder->imageSizeLimit, + decoder->imageDimensionLimit, + data->diag), + AVIF_RESULT_INVALID_IMAGE_GRID); + } - // Find the alphaOBU item, if any - for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) { - avifDecoderItem * item = &data->meta->items.item[itemIndex]; - if (!item->size) { - continue; - } - if (item->hasUnsupportedEssentialProperty) { - // An essential property isn't supported by libavif; ignore the item. - continue; - } - avifBool isGrid = (memcmp(item->type, "grid", 4) == 0); - if (memcmp(item->type, "av01", 4) && !isGrid) { - // probably exif or some other data - continue; - } - - // Is this an alpha auxiliary item of whatever we chose for colorItem? - const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC"); - if (auxCProp && isAlphaURN(auxCProp->u.auxC.auxType) && (item->auxForID == colorItem->id)) { - if (isGrid) { - avifROData readData; - avifResult readResult = avifDecoderItemRead(item, decoder->io, &readData, 0, 0, data->diag); - if (readResult != AVIF_RESULT_OK) { - return readResult; - } - if (!avifParseImageGridBox(&data->alphaGrid, - readData.data, - readData.size, - decoder->imageSizeLimit, - decoder->imageDimensionLimit, - data->diag)) { - return AVIF_RESULT_INVALID_IMAGE_GRID; - } - } - - alphaItem = item; - break; - } + avifDecoderItem * alphaItem = avifDecoderDataFindItem(data, /*alpha=*/AVIF_TRUE, /*parentItemID=*/colorItem->id); + if (alphaItem && !memcmp(alphaItem->type, "grid", 4)) { + avifROData readData; + AVIF_CHECKRES(avifDecoderItemRead(alphaItem, decoder->io, &readData, 0, 0, data->diag)); + AVIF_CHECKERR(avifParseImageGridBox(&data->alphaGrid, + readData.data, + readData.size, + decoder->imageSizeLimit, + decoder->imageDimensionLimit, + data->diag), + AVIF_RESULT_INVALID_IMAGE_GRID); } // Find Exif and/or XMP metadata, if any