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