Store all alpha payloads before color payloads in mdat

Fixes: #287
diff --git a/src/write.c b/src/write.c
index 412d35c..ac7f234 100644
--- a/src/write.c
+++ b/src/write.c
@@ -962,28 +962,40 @@
     // Write mdat
 
     avifBoxMarker mdat = avifRWStreamWriteBox(&s, "mdat", AVIF_BOX_SIZE_TBD);
-    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
-        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
-        if ((item->metadataPayload.size == 0) && (item->encodeOutput->samples.count == 0)) {
-            continue;
-        }
+    for (uint32_t itemPasses = 0; itemPasses < 2; ++itemPasses) {
+        // Use multiple passes to pack all alpha mdat payloads before color payloads.
+        // See here for the discussion:
+        //
+        // https://github.com/AOMediaCodec/libavif/issues/287
+        //
+        const avifBool alphaPass = (itemPasses == 0);
 
-        uint32_t chunkOffset = (uint32_t)avifRWStreamOffset(&s);
-        if (item->encodeOutput->samples.count > 0) {
-            for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
-                avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
-                avifRWStreamWrite(&s, sample->data.data, sample->data.size);
+        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
+            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
+            if ((item->metadataPayload.size == 0) && (item->encodeOutput->samples.count == 0)) {
+                continue;
             }
-        } else {
-            avifRWStreamWrite(&s, item->metadataPayload.data, item->metadataPayload.size);
-        }
+            if (!alphaPass != !item->alpha) {
+                continue;
+            }
 
-        for (uint32_t fixupIndex = 0; fixupIndex < item->mdatFixups.count; ++fixupIndex) {
-            avifOffsetFixup * fixup = &item->mdatFixups.fixup[fixupIndex];
-            size_t prevOffset = avifRWStreamOffset(&s);
-            avifRWStreamSetOffset(&s, fixup->offset);
-            avifRWStreamWriteU32(&s, chunkOffset);
-            avifRWStreamSetOffset(&s, prevOffset);
+            uint32_t chunkOffset = (uint32_t)avifRWStreamOffset(&s);
+            if (item->encodeOutput->samples.count > 0) {
+                for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
+                    avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
+                    avifRWStreamWrite(&s, sample->data.data, sample->data.size);
+                }
+            } else {
+                avifRWStreamWrite(&s, item->metadataPayload.data, item->metadataPayload.size);
+            }
+
+            for (uint32_t fixupIndex = 0; fixupIndex < item->mdatFixups.count; ++fixupIndex) {
+                avifOffsetFixup * fixup = &item->mdatFixups.fixup[fixupIndex];
+                size_t prevOffset = avifRWStreamOffset(&s);
+                avifRWStreamSetOffset(&s, fixup->offset);
+                avifRWStreamWriteU32(&s, chunkOffset);
+                avifRWStreamSetOffset(&s, prevOffset);
+            }
         }
     }
     avifRWStreamFinishBox(&s, mdat);