Write unassociated metadata items (EXIF, XMP) to a small meta box inside of a trak box. These items are implicitly associated with the track they are contained within.
| 854 | // Write unassociated metadata items (EXIF, XMP) to a small meta box inside of a trak box. |
| 855 | // These items are implicitly associated with the track they are contained within. |
| 856 | static avifResult avifEncoderWriteTrackMetaBox(avifEncoder * encoder, avifRWStream * s) |
| 857 | { |
| 858 | // Count how many non-image items (such as EXIF/XMP) are being written |
| 859 | uint32_t metadataItemCount = 0; |
| 860 | for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) { |
| 861 | avifEncoderItem * item = &encoder->data->items.item[itemIndex]; |
| 862 | if (memcmp(item->type, encoder->data->imageItemType, 4) != 0) { |
| 863 | ++metadataItemCount; |
| 864 | } |
| 865 | } |
| 866 | if (metadataItemCount == 0) { |
| 867 | // Don't even bother writing the trak meta box |
| 868 | return AVIF_RESULT_OK; |
| 869 | } |
| 870 | |
| 871 | avifBoxMarker meta; |
| 872 | AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "meta", AVIF_BOX_SIZE_TBD, 0, 0, &meta)); |
| 873 | |
| 874 | AVIF_CHECKRES(avifRWStreamWriteHandlerBox(s, "pict")); |
| 875 | |
| 876 | avifBoxMarker iloc; |
| 877 | AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "iloc", AVIF_BOX_SIZE_TBD, 0, 0, &iloc)); |
| 878 | AVIF_CHECKRES(avifRWStreamWriteBits(s, 4, /*bitCount=*/4)); // unsigned int(4) offset_size; |
| 879 | AVIF_CHECKRES(avifRWStreamWriteBits(s, 4, /*bitCount=*/4)); // unsigned int(4) length_size; |
| 880 | AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/4)); // unsigned int(4) base_offset_size; |
| 881 | AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/4)); // unsigned int(4) reserved; |
| 882 | AVIF_CHECKRES(avifRWStreamWriteU16(s, (uint16_t)metadataItemCount)); // unsigned int(16) item_count; |
| 883 | for (uint32_t trakItemIndex = 0; trakItemIndex < encoder->data->items.count; ++trakItemIndex) { |
| 884 | avifEncoderItem * item = &encoder->data->items.item[trakItemIndex]; |
| 885 | if (memcmp(item->type, encoder->data->imageItemType, 4) == 0) { |
| 886 | // Skip over all non-metadata items |
| 887 | continue; |
| 888 | } |
| 889 | |
| 890 | AVIF_CHECKRES(avifRWStreamWriteU16(s, item->id)); // unsigned int(16) item_ID; |
| 891 | AVIF_CHECKRES(avifRWStreamWriteU16(s, 0)); // unsigned int(16) data_reference_index; |
| 892 | AVIF_CHECKRES(avifRWStreamWriteU16(s, 1)); // unsigned int(16) extent_count; |
| 893 | AVIF_CHECKRES(avifEncoderItemAddMdatFixup(item, s)); // |
| 894 | AVIF_CHECKRES(avifRWStreamWriteU32(s, 0 /* set later */)); // unsigned int(offset_size*8) extent_offset; |
| 895 | AVIF_CHECKRES(avifRWStreamWriteU32(s, (uint32_t)item->metadataPayload.size)); // unsigned int(length_size*8) extent_length; |
| 896 | } |
| 897 | AVIF_CHECKRES(avifRWStreamFinishBox(s, iloc)); |
| 898 | |
| 899 | avifBoxMarker iinf; |
| 900 | AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "iinf", AVIF_BOX_SIZE_TBD, 0, 0, &iinf)); |
| 901 | AVIF_CHECKRES(avifRWStreamWriteU16(s, (uint16_t)metadataItemCount)); // unsigned int(16) entry_count; |
| 902 | for (uint32_t trakItemIndex = 0; trakItemIndex < encoder->data->items.count; ++trakItemIndex) { |
| 903 | avifEncoderItem * item = &encoder->data->items.item[trakItemIndex]; |
| 904 | if (memcmp(item->type, encoder->data->imageItemType, 4) == 0) { |
| 905 | continue; |
| 906 | } |
| 907 | |
| 908 | AVIF_ASSERT_OR_RETURN(!item->hiddenImage); |
| 909 | avifBoxMarker infe; |
| 910 | AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "infe", AVIF_BOX_SIZE_TBD, 2, 0, &infe)); |
| 911 | AVIF_CHECKRES(avifRWStreamWriteU16(s, item->id)); // unsigned int(16) item_ID; |
| 912 | AVIF_CHECKRES(avifRWStreamWriteU16(s, 0)); // unsigned int(16) item_protection_index; |
| 913 | AVIF_CHECKRES(avifRWStreamWrite(s, item->type, 4)); // unsigned int(32) item_type; |
no test coverage detected