Lots of fixes to ftyp, swapping meta and mdat ordering on write for streaming friendliness
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9baf838..1b1f59f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Changed
+- `ftyp` - Change `major_brand` to `avif`
+- `ftyp` - Reorder `compatible_brands`, add `MA1A` or `MA1B` when appropriate
+- Write `meta` box before `mdat` box for streaming friendliness
 
 ## [0.1.2] - 2019-04-18
 ### Added
diff --git a/include/avif/internal.h b/include/avif/internal.h
index fe45bf4..d2cdd5f 100644
--- a/include/avif/internal.h
+++ b/include/avif/internal.h
@@ -129,6 +129,8 @@
 // Read
 avifBool avifStreamHasBytesLeft(avifStream * stream, size_t byteCount);
 size_t avifStreamRemainingBytes(avifStream * stream);
+size_t avifStreamOffset(avifStream * stream);
+void avifStreamSetOffset(avifStream * stream, size_t offset);
 avifBool avifStreamSkip(avifStream * stream, size_t byteCount);
 avifBool avifStreamRead(avifStream * stream, uint8_t * data, size_t size);
 avifBool avifStreamReadU16(avifStream * stream, uint16_t * v);
diff --git a/src/stream.c b/src/stream.c
index 0908c8f..52a22ae 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -29,6 +29,19 @@
     return stream->raw->size - stream->offset;
 }
 
+size_t avifStreamOffset(avifStream * stream)
+{
+    return stream->offset;
+}
+
+void avifStreamSetOffset(avifStream * stream, size_t offset)
+{
+    stream->offset = offset;
+    if (stream->offset > stream->raw->size) {
+        stream->offset = stream->raw->size;
+    }
+}
+
 avifBool avifStreamSkip(avifStream * stream, size_t byteCount)
 {
     if (!avifStreamHasBytesLeft(stream, byteCount)) {
diff --git a/src/write.c b/src/write.c
index 700867e..0d9eeab 100644
--- a/src/write.c
+++ b/src/write.c
@@ -78,24 +78,21 @@
     // Write ftyp
 
     avifBoxMarker ftyp = avifStreamWriteBox(&s, "ftyp", -1, 0);
-    avifStreamWriteChars(&s, "mif1", 4); // unsigned int(32) major_brand;
+    avifStreamWriteChars(&s, "avif", 4); // unsigned int(32) major_brand;
     avifStreamWriteU32(&s, 0);           // unsigned int(32) minor_version;
-    avifStreamWriteChars(&s, "mif1", 4); // unsigned int(32) compatible_brands[];
-    avifStreamWriteChars(&s, "avif", 4); // ... compatible_brands[]
+    avifStreamWriteChars(&s, "avif", 4); // unsigned int(32) compatible_brands[];
+    avifStreamWriteChars(&s, "mif1", 4); // ... compatible_brands[]
     avifStreamWriteChars(&s, "miaf", 4); // ... compatible_brands[]
+    if ((image->depth == 8) || (image->depth == 10)) {
+        if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420) {
+            avifStreamWriteChars(&s, "MA1B", 4); // ... compatible_brands[]
+        } else if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) {
+            avifStreamWriteChars(&s, "MA1A", 4); // ... compatible_brands[]
+        }
+    }
     avifStreamFinishBox(&s, ftyp);
 
     // -----------------------------------------------------------------------
-    // Write mdat
-
-    avifBoxMarker mdat = avifStreamWriteBox(&s, "mdat", -1, 0);
-    uint32_t colorOBUOffset = (uint32_t)s.offset;
-    avifStreamWrite(&s, colorOBU.data, colorOBU.size);
-    uint32_t alphaOBUOffset = (uint32_t)s.offset;
-    avifStreamWrite(&s, alphaOBU.data, alphaOBU.size);
-    avifStreamFinishBox(&s, mdat);
-
-    // -----------------------------------------------------------------------
     // Start meta
 
     avifBoxMarker meta = avifStreamWriteBox(&s, "meta", 0, 0);
@@ -119,6 +116,10 @@
     // -----------------------------------------------------------------------
     // Write iloc
 
+    // Remember where we want to store the offsets to the mdat OBU offsets to adjust them later.
+    size_t colorOBUOffsetOffset = 0;
+    size_t alphaOBUOffsetOffset = 0;
+
     avifBoxMarker iloc = avifStreamWriteBox(&s, "iloc", 0, 0);
 
     // iloc header
@@ -131,14 +132,16 @@
     avifStreamWriteU16(&s, 1);                       // unsigned int(16) item_ID;
     avifStreamWriteU16(&s, 0);                       // unsigned int(16) data_reference_index;
     avifStreamWriteU16(&s, 1);                       // unsigned int(16) extent_count;
-    avifStreamWriteU32(&s, colorOBUOffset);          // unsigned int(offset_size*8) extent_offset;
+    colorOBUOffsetOffset = avifStreamOffset(&s);     //
+    avifStreamWriteU32(&s, 0 /* set later */);       // unsigned int(offset_size*8) extent_offset;
     avifStreamWriteU32(&s, (uint32_t)colorOBU.size); // unsigned int(length_size*8) extent_length;
 
     if (hasAlpha) {
         avifStreamWriteU16(&s, 2);                       // unsigned int(16) item_ID;
         avifStreamWriteU16(&s, 0);                       // unsigned int(16) data_reference_index;
         avifStreamWriteU16(&s, 1);                       // unsigned int(16) extent_count;
-        avifStreamWriteU32(&s, alphaOBUOffset);          // unsigned int(offset_size*8) extent_offset;
+        alphaOBUOffsetOffset = avifStreamOffset(&s);     //
+        avifStreamWriteU32(&s, 0 /* set later */);       // unsigned int(offset_size*8) extent_offset;
         avifStreamWriteU32(&s, (uint32_t)alphaOBU.size); // unsigned int(length_size*8) extent_length;
     }
 
@@ -281,9 +284,36 @@
     avifStreamFinishBox(&s, iprp);
 
     // -----------------------------------------------------------------------
-    // Finish up stream
+    // Finish meta box
 
     avifStreamFinishBox(&s, meta);
+
+    // -----------------------------------------------------------------------
+    // Write mdat
+
+    avifBoxMarker mdat = avifStreamWriteBox(&s, "mdat", -1, 0);
+    uint32_t colorOBUOffset = (uint32_t)s.offset;
+    avifStreamWrite(&s, colorOBU.data, colorOBU.size);
+    uint32_t alphaOBUOffset = (uint32_t)s.offset;
+    avifStreamWrite(&s, alphaOBU.data, alphaOBU.size);
+    avifStreamFinishBox(&s, mdat);
+
+    // -----------------------------------------------------------------------
+    // Finish up stream
+
+    // Set offsets needed in meta box based on where we eventually wrote mdat
+    size_t prevOffset = avifStreamOffset(&s);
+    if (colorOBUOffsetOffset != 0) {
+        avifStreamSetOffset(&s, colorOBUOffsetOffset);
+        avifStreamWriteU32(&s, colorOBUOffset);
+    }
+    if (alphaOBUOffsetOffset != 0) {
+        avifStreamSetOffset(&s, alphaOBUOffsetOffset);
+        avifStreamWriteU32(&s, alphaOBUOffset);
+    }
+    avifStreamSetOffset(&s, prevOffset);
+
+    // Close write stream
     avifStreamFinishWrite(&s);
 
     // -----------------------------------------------------------------------