| 2860 | #endif // AVIF_ENABLE_EXPERIMENTAL_MINI |
| 2861 | |
| 2862 | static avifResult avifRWStreamWriteProperties(avifItemPropertyDedup * const dedup, |
| 2863 | avifRWStream * const s, |
| 2864 | const avifEncoder * const encoder, |
| 2865 | const avifImage * const imageMetadata, |
| 2866 | const avifImage * const altImageMetadata) |
| 2867 | { |
| 2868 | for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) { |
| 2869 | avifEncoderItem * item = &encoder->data->items.item[itemIndex]; |
| 2870 | const avifBool isGrid = (item->gridCols > 0); |
| 2871 | // Whether there is ipma to write for this item. |
| 2872 | avifBool hasIpmaToWrite = item->codec || isGrid; |
| 2873 | const avifBool isToneMappedImage = !memcmp(item->type, "tmap", 4); |
| 2874 | if (isToneMappedImage) { |
| 2875 | hasIpmaToWrite = AVIF_TRUE; |
| 2876 | } |
| 2877 | const avifBool isSampleTransformImage = !memcmp(item->type, "sato", 4); |
| 2878 | if (isSampleTransformImage) { |
| 2879 | hasIpmaToWrite = AVIF_TRUE; |
| 2880 | } |
| 2881 | item->associations.count = 0; |
| 2882 | if (!hasIpmaToWrite) { |
| 2883 | continue; |
| 2884 | } |
| 2885 | |
| 2886 | if (item->dimgFromID && (item->extraLayerCount == 0)) { |
| 2887 | avifEncoderItem * parentItem = avifEncoderDataFindItemByID(encoder->data, item->dimgFromID); |
| 2888 | if (parentItem && !memcmp(parentItem->type, "grid", 4)) { |
| 2889 | // All image cells from a grid should share the exact same properties unless they are |
| 2890 | // layered image which have different al1x, so see if we've already written properties |
| 2891 | // out for another cell in this grid, and if so, just steal their ipma and move on. |
| 2892 | // This is a sneaky way to provide iprp deduplication. |
| 2893 | |
| 2894 | avifBool foundPreviousCell = AVIF_FALSE; |
| 2895 | for (uint32_t dedupIndex = 0; dedupIndex < itemIndex; ++dedupIndex) { |
| 2896 | avifEncoderItem * dedupItem = &encoder->data->items.item[dedupIndex]; |
| 2897 | if ((item->dimgFromID == dedupItem->dimgFromID) && (dedupItem->extraLayerCount == 0)) { |
| 2898 | // We've already written dedup's items out. Steal their ipma indices and move on! |
| 2899 | item->associations.count = 0; |
| 2900 | for (uint32_t associationIndex = 0; associationIndex < dedupItem->associations.count; ++associationIndex) { |
| 2901 | avifItemPropertyAssociation * association = (avifItemPropertyAssociation *)avifArrayPush(&item->associations); |
| 2902 | AVIF_CHECKERR(association != NULL, AVIF_RESULT_OUT_OF_MEMORY); |
| 2903 | *association = dedupItem->associations.association[associationIndex]; |
| 2904 | } |
| 2905 | foundPreviousCell = AVIF_TRUE; |
| 2906 | break; |
| 2907 | } |
| 2908 | } |
| 2909 | if (foundPreviousCell) { |
| 2910 | continue; |
| 2911 | } |
| 2912 | } |
| 2913 | } |
| 2914 | |
| 2915 | const avifImage * itemMetadata = imageMetadata; |
| 2916 | if (isToneMappedImage) { |
| 2917 | itemMetadata = altImageMetadata; |
| 2918 | } else if (item->itemCategory == AVIF_ITEM_GAIN_MAP) { |
| 2919 | AVIF_ASSERT_OR_RETURN(itemMetadata->gainMap && itemMetadata->gainMap->image); |
no test coverage detected