o Added support for SMPTE RDD 47 "ISXD Track File"
[asdcplib.git] / src / MXFTypes.h
index 02efbb1e54e2dc7fb63088040c1dd9fe4f429402..c49fed9b6f07b267e1f5de0621865dc7c65a4db2 100755 (executable)
@@ -1,29 +1,52 @@
-//
-// MXFTypes.h
-//
+/*
+Copyright (c) 2005-2016, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file    MXFTypes.h
+    \version $Id$
+    \brief   MXF objects
+*/
 
 #ifndef _MXFTYPES_H_
 #define _MXFTYPES_H_
 
-
-
-#endif //_MXFTYPES_H_
-
 #include "KLV.h"
 #include <list>
 #include <vector>
+#include <set>
 #include <map>
 #include <wchar.h>
 
 // used with TLVReader::Read*
 //
 // these are used below to manufacture arguments
-#define OBJ_READ_ARGS(s,l) s_MDD_Table[MDDindex_##s##_##l], &l
-#define OBJ_READ_ARGS_R(s,l,r) s_MDD_Table[MDDindex_##s##_##l], &r
-
-#define OBJ_WRITE_ARGS(s,l) s_MDD_Table[MDDindex_##s##_##l], &l
-
-#define OBJ_TYPE_ARGS(t) s_MDD_Table[MDDindex_##t].ul
+#define OBJ_READ_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
+#define OBJ_WRITE_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
+#define OBJ_READ_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
+#define OBJ_WRITE_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
+#define OBJ_TYPE_ARGS(t) m_Dict->Type(MDD_##t).ul
 
 
 namespace ASDCP
@@ -34,7 +57,7 @@ namespace ASDCP
       typedef std::map<TagValue, ItemInfo> TagMap;
 
       //      
-      class TLVReader : public ASDCP::MemIOReader
+      class TLVReader : public Kumu::MemIOReader
        {
 
          TagMap         m_ElementMap;
@@ -42,11 +65,11 @@ namespace ASDCP
 
          TLVReader();
          ASDCP_NO_COPY_CONSTRUCT(TLVReader);
-         bool FindTL(const MDDEntry&);
 
        public:
          TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
-         Result_t ReadObject(const MDDEntry&, IArchive*);
+         bool FindTL(const MDDEntry&);
+         Result_t ReadObject(const MDDEntry&, Kumu::IArchive*);
          Result_t ReadUi8(const MDDEntry&, ui8_t*);
          Result_t ReadUi16(const MDDEntry&, ui16_t*);
          Result_t ReadUi32(const MDDEntry&, ui32_t*);
@@ -54,7 +77,7 @@ namespace ASDCP
        };
 
       //      
-      class TLVWriter : public ASDCP::MemIOWriter
+      class TLVWriter : public Kumu::MemIOWriter
        {
 
          TagMap         m_ElementMap;
@@ -66,7 +89,7 @@ namespace ASDCP
 
        public:
          TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
-         Result_t WriteObject(const MDDEntry&, IArchive*);
+         Result_t WriteObject(const MDDEntry&, Kumu::IArchive*);
          Result_t WriteUi8(const MDDEntry&, ui8_t*);
          Result_t WriteUi16(const MDDEntry&, ui16_t*);
          Result_t WriteUi32(const MDDEntry&, ui32_t*);
@@ -74,94 +97,154 @@ namespace ASDCP
        };
 
       //
-      template <class T>
-       class Batch : public std::vector<T>, public IArchive
+      template <class ContainerType>
+       class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive
        {
        public:
-         ui32_t ItemCount;
-         ui32_t ItemSize;
-
-         Batch() : ItemCount(0), ItemSize(0) { ItemSize = sizeof(T); }
-         ~Batch() {}
+         FixedSizeItemCollection() {}
+         virtual ~FixedSizeItemCollection() {}
 
-         //
-         Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
-           Result_t result = Reader.ReadUi32BE(&ItemCount);
+         ui32_t ItemSize() const {
+           typename ContainerType::value_type tmp_item;
+           return tmp_item.ArchiveLength();
+         }
 
-           if ( ASDCP_SUCCESS(result) )
-             result = Reader.ReadUi32BE(&ItemSize);
+         bool HasValue() const { return ! this->empty(); }
 
-           if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) )
-             return RESULT_FAIL;
+         ui32_t ArchiveLength() const {
+           return ( sizeof(ui32_t) * 2 ) +  ( (ui32_t)this->size() * this->ItemSize() );
+         }
 
-           for ( ui32_t i = 0; i < ItemCount && ASDCP_SUCCESS(result); i++ )
+         bool Archive(Kumu::MemIOWriter* Writer) const {
+           if ( ! Writer->WriteUi32BE((ui32_t)this->size()) ) return false;
+           if ( ! Writer->WriteUi32BE((ui32_t)this->ItemSize()) ) return false;
+           if ( this->empty() ) return true;
+           
+           typename ContainerType::const_iterator i;
+           bool result = true;
+           for ( i = this->begin(); i != this->end() && result; ++i )
              {
-               T Tmp;
-               result = Tmp.ReadFrom(Reader);
-
-               if ( ASDCP_SUCCESS(result) )
-                 push_back(Tmp);
+               result = i->Archive(Writer);
              }
 
            return result;
          }
 
          //
-         Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
-           Result_t result = Writer.WriteUi32BE(size());
+         bool Unarchive(Kumu::MemIOReader* Reader) {
+           ui32_t item_count, item_size;
+           if ( ! Reader->ReadUi32BE(&item_count) ) return false;
+           if ( ! Reader->ReadUi32BE(&item_size) ) return false;
+
+           if ( item_count > 0 )
+             {
+               if ( this->ItemSize() != item_size ) return false;
+             }
 
-           if ( ASDCP_SUCCESS(result) )
-             result = Writer.WriteUi32BE(ItemSize);
+           bool result = true;
+           for ( ui32_t i = 0; i < item_count && result; ++i )
+             {
+               typename ContainerType::value_type tmp_item;
+               result = tmp_item.Unarchive(Reader);
 
-           typename std::vector<T>::iterator l_i = begin();
-           for ( ; l_i != end() && ASDCP_SUCCESS(result); l_i++ )
-             result = (*l_i).WriteTo(Writer);
+               if ( result )
+                 {
+                   this->push_back(tmp_item);
+                 }
+             }
 
            return result;
          }
 
-         //
-         void Dump(FILE* stream = 0, ui32_t depth = 0)
-           {
-             char identbuf[IdentBufferLen];
+         void Dump(FILE* stream = 0, ui32_t depth = 0) {
+           char identbuf[IdentBufferLen];
 
-             if ( stream == 0 )
+           if ( stream == 0 )
+             {
                stream = stderr;
-
-             typename std::vector<T>::iterator i = this->begin();
-             for ( ; i != this->end(); i++ )
-               fprintf(stream, "  %s\n", (*i).ToString(identbuf));
-           }
+             }
+           
+           typename ContainerType::const_iterator i;
+           for ( i = this->begin(); i != this->end(); ++i )
+             {
+               fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
+             }
+         }
        };
 
+
+      template <class item_type>
+       class PushSet : public std::set<item_type>
+      {
+      public:
+       PushSet() {}
+       virtual ~PushSet() {}
+       void push_back(const item_type& item) { this->insert(item); }
+      };
+
+      template <class ItemType>
+       class Batch : public FixedSizeItemCollection<PushSet<ItemType> >
+      {
+      public:
+       Batch() {}
+       virtual ~Batch() {}
+      };
+
+      template <class ItemType>
+       class Array : public FixedSizeItemCollection<std::vector<ItemType> >
+      {
+      public:
+       Array() {}
+       virtual ~Array() {}
+      };
+
       //
       template <class T>
-       class Array : public std::list<T>, public IArchive
+       class SimpleArray : public std::list<T>, public Kumu::IArchive
        {
        public:
-         Array() {}
-         ~Array() {}
+         SimpleArray() {}
+         virtual ~SimpleArray() {}
 
          //
-         Result_t ReadFrom(ASDCP::MemIOReader& Reader)
+         bool Unarchive(Kumu::MemIOReader* Reader)
            {
-             while ( Reader.Remainder() > 0 )
+             bool result = true;
+
+             while ( Reader->Remainder() > 0 && result )
                {
                  T Tmp;
-                 Tmp.ReadFrom(Reader);
-                 push_back(Tmp);
+                 result = Tmp.Unarchive(Reader);
+
+                 if ( result )
+                   {
+                     this->push_back(Tmp);
+                   }
                }
 
-             return RESULT_OK;
+             return result;
            }
 
+         inline bool HasValue() const { return ! this->empty(); }
+
+         ui32_t ArchiveLength() const {
+           ui32_t arch_size = 0;
+
+           typename std::list<T>::const_iterator l_i = this->begin();
+
+           for ( ; l_i != this->end(); l_i++ )
+             arch_size += l_i->ArchiveLength();
+           
+           return arch_size;
+         }
+
          //
-         Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
-           Result_t result = RESULT_OK;
-           typename std::list<T>::iterator l_i = begin();
+         bool Archive(Kumu::MemIOWriter* Writer) const {
+           bool result = true;
+           typename std::list<T>::const_iterator l_i = this->begin();
 
-           for ( ; l_i != end() && ASDCP_SUCCESS(result); l_i++ )
-             result = (*l_i).WriteTo(Writer);
+           for ( ; l_i != this->end() && result; l_i++ )
+             result = (*l_i).Archive(Writer);
 
            return result;
          }
@@ -176,110 +259,441 @@ namespace ASDCP
 
              typename std::list<T>::iterator i = this->begin();
              for ( ; i != this->end(); i++ )
-               fprintf(stream, "  %s\n", (*i).ToString(identbuf));
+               fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
            }
        };
 
       //
-      class Timestamp : public IArchive
+    class ISO8String : public std::string, public Kumu::IArchive
+       {
+       public:
+         ISO8String() {}
+         ISO8String(const char*);
+         ISO8String(const std::string&);
+         ~ISO8String() {}
+
+         const ISO8String& operator=(const char*);
+         const ISO8String& operator=(const std::string&);
+
+         const char* EncodeString(char* str_buf, ui32_t buf_len) const;
+         inline virtual bool HasValue() const { return ! empty(); }
+         inline virtual ui32_t ArchiveLength() const { return (ui32_t)(sizeof(ui32_t) + size()); }
+         virtual bool Unarchive(Kumu::MemIOReader* Reader);
+         virtual bool Archive(Kumu::MemIOWriter* Writer) const;
+       };
+
+      //
+    class UTF16String : public std::string, public Kumu::IArchive
+       {
+       public:
+         UTF16String() {}
+         UTF16String(const char*);
+         UTF16String(const std::string&);
+         ~UTF16String() {}
+
+         const UTF16String& operator=(const char*);
+         const UTF16String& operator=(const std::string&);
+
+         const char* EncodeString(char* str_buf, ui32_t buf_len) const;
+         inline virtual bool HasValue() const { return ! empty(); }
+         inline virtual ui32_t ArchiveLength() const { return (ui32_t)(sizeof(ui32_t) + size()); }
+         virtual bool Unarchive(Kumu::MemIOReader* Reader);
+         virtual bool Archive(Kumu::MemIOWriter* Writer) const;
+       };
+
+      //
+      class Rational : public ASDCP::Rational, public Kumu::IArchive
        {
        public:
-         ui16_t Year;
-         ui8_t  Month;
-         ui8_t  Day;
-         ui8_t  Hour;
-         ui8_t  Minute;
-         ui8_t  Second;
-         ui8_t  mSec_4;
-
-         Timestamp() :
-           Year(0), Month(0),  Day(0),
-           Hour(0), Minute(0), Second(0), mSec_4(0) {}
+         Rational() {}
+         ~Rational() {}
+
+         Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
+           Numerator = rhs.Numerator;
+           Denominator = rhs.Denominator;
+         }
+
+         const Rational& operator=(const Rational& rhs) {
+           Numerator = rhs.Numerator;
+           Denominator = rhs.Denominator;
+           return *this;
+         }
+
+         Rational(const ASDCP::Rational& rhs) {
+           Numerator = rhs.Numerator;
+           Denominator = rhs.Denominator;
+         }
+
+         const Rational& operator=(const ASDCP::Rational& rhs) {
+           Numerator = rhs.Numerator;
+           Denominator = rhs.Denominator;
+           return *this;
+         }
 
          //
-         inline const char* ToString(char* str_buf) const {
-           sprintf(str_buf, "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.%03hu",
-                   Year, Month, Day, Hour, Minute, Second, mSec_4);
+         inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+           snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
            return str_buf;
          }
 
-         //
-         inline Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
-           Result_t result = Reader.ReadUi16BE(&Year);
+         inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+           if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
+           if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
+           return true;
+         }
 
-           if ( ASDCP_SUCCESS(result) )
-             result = Reader.ReadRaw(&Month, 6);
+         inline virtual bool HasValue() const { return true; }
+         inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
 
-           return result;
+         inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+           if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
+           if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
+           return true;
+         }
+       };
+
+      //
+      class LineMapPair : public Kumu::IArchive
+       {
+       public:
+         ui32_t First;
+         ui32_t Second;
+
+       LineMapPair() : First(0), Second() {}
+         ~LineMapPair() {}
+
+       LineMapPair(const ui32_t& first, const ui32_t& second) : IArchive() {
+           First = first;
+           Second = second;
+         }
+
+         LineMapPair(const LineMapPair& rhs) : IArchive() {
+           First = rhs.First;
+           Second = rhs.Second;
+         }
+
+         const LineMapPair& operator=(const LineMapPair& rhs) {
+           First = rhs.First;
+           Second = rhs.Second;
+           return *this;
          }
 
          //
-         inline Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
-           Result_t result = Writer.WriteUi16BE(Year);
+         inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+           snprintf(str_buf, buf_len, "%d,%d", First, Second);
+           return str_buf;
+         }
 
-           if ( ASDCP_SUCCESS(result) )
-             result = Writer.WriteRaw(&Month, 6);
+         inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+           ui32_t n;
+           if ( ! Reader->ReadUi32BE(&n) ) return false;
+           if ( n != 2 ) return false;
+           if ( ! Reader->ReadUi32BE(&n) ) return false;
+           if ( n != 4 ) return false;
+           if ( ! Reader->ReadUi32BE((ui32_t*)&First) ) return false;
+           if ( ! Reader->ReadUi32BE((ui32_t*)&Second) ) return false;
+           return true;
+         }
 
-           return result;
+         inline virtual bool HasValue() const { return true; }
+         inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*4; }
+
+         inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+           if ( ! Writer->WriteUi32BE(2UL) ) return false;
+           if ( ! Writer->WriteUi32BE(4UL) ) return false;
+           if ( ! Writer->WriteUi32BE((ui32_t)First) ) return false;
+           if ( ! Writer->WriteUi32BE((ui32_t)Second) ) return false;
+           return true;
          }
        };
 
       //
-      class UTF16String : public IArchive
+      class ColorPrimary : public Kumu::IArchive
        {
-         ui16_t m_length;
-         char   m_buffer[IdentBufferLen];
-         
        public:
-         UTF16String() : m_length(0) { *m_buffer = 0; }
-         ~UTF16String() {}
+         ui16_t X;
+         ui16_t Y;
+
+       ColorPrimary() : X(0), Y(0) {}
+         ~ColorPrimary() {}
+
+         ColorPrimary(const ui16_t& x, const ui16_t& y) : X(x), Y(y) {}
+
+         ColorPrimary(const ColorPrimary& rhs) { Copy(rhs); }
+         const ColorPrimary& operator=(const ColorPrimary& rhs) { Copy(rhs); return *this; }
+         
+         void Copy(const ColorPrimary& rhs) {
+           X = rhs.X;
+           Y = rhs.Y;
+         }
 
          //
-         const char* ToString(char* str_buf) const {
-           strncpy(str_buf, m_buffer, m_length+1);
+         inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+           snprintf(str_buf, buf_len, "%d,%d", X, Y);
            return str_buf;
          }
 
-         Result_t ReadFrom(ASDCP::MemIOReader& Reader);
-         Result_t WriteTo(ASDCP::MemIOWriter& Writer);
+         inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+           if ( ! Reader->ReadUi16BE((ui16_t*)&X) ) return false;
+           if ( ! Reader->ReadUi16BE((ui16_t*)&Y) ) return false;
+           return true;
+         }
+
+         inline virtual bool HasValue() const { return X || Y; }
+         inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*2; }
+
+         inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+           if ( ! Writer->WriteUi16BE((ui16_t)X) ) return false;
+           if ( ! Writer->WriteUi16BE((ui16_t)Y) ) return false;
+           return true;
+         }
        };
 
       //
-      class Rational : public ASDCP::Rational, public IArchive
+      class ThreeColorPrimaries : public Kumu::IArchive
        {
        public:
-         Rational() {}
-         ~Rational() {}
+         ColorPrimary First;
+         ColorPrimary Second;
+         ColorPrimary Third;
+
+         ThreeColorPrimaries() {}
+         ~ThreeColorPrimaries() {}
+
+         ThreeColorPrimaries(const ColorPrimary& first, const ColorPrimary& second, const ColorPrimary& third) :
+           First(first), Second(second), Third(third) {}
+
+         ThreeColorPrimaries(const ThreeColorPrimaries& rhs) { Copy(rhs); }
+         const ThreeColorPrimaries& operator=(const ThreeColorPrimaries& rhs) { Copy(rhs); return *this; }
+         
+         void Copy(const ThreeColorPrimaries& rhs) {
+           First = rhs.First;
+           Second = rhs.Second;
+           Third = rhs.Third;
+         }
 
          //
-         const char* ToString(char* str_buf) const {
-           sprintf(str_buf, "%lu/%lu", Numerator, Denominator);
+         inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+           snprintf(str_buf, buf_len, "%d,%d;%d,%d;%d,%d", First.X, First.Y, Second.X, Second.Y, Third.X, Third.Y);
            return str_buf;
          }
 
-         Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
-           Result_t result = Reader.ReadUi32BE((ui32_t*)&Numerator);
+         inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+           First.Unarchive(Reader);
+           Second.Unarchive(Reader);
+           Third.Unarchive(Reader);
+           return true;
+         }
 
-           if ( ASDCP_SUCCESS(result) )
-             result = Reader.ReadUi32BE((ui32_t*)&Denominator);
-           
-           return result;
+         inline virtual bool HasValue() const {
+           return First.HasValue() || Second.HasValue() || Third.HasValue();
          }
 
-         Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
-           Result_t result = Writer.WriteUi32BE((ui32_t)Numerator);
+         inline virtual ui32_t ArchiveLength() const {
+           return First.ArchiveLength()
+             + Second.ArchiveLength()
+             + Third.ArchiveLength();
+         }
 
-           if ( ASDCP_SUCCESS(result) )
-             result = Writer.WriteUi32BE((ui32_t)Denominator);
-           
-           return result;
+         inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+           First.Archive(Writer);
+           Second.Archive(Writer);
+           Third.Archive(Writer);
+           return true;
          }
        };
 
+      //
+      class VersionType : public Kumu::IArchive
+       {
+       public:
+         enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
+         ui16_t Major;
+         ui16_t Minor;
+         ui16_t Patch;
+         ui16_t Build;
+         Release_t Release;
+
+         VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
+         VersionType(const VersionType& rhs) { Copy(rhs); }
+         virtual ~VersionType() {}
+
+         const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
+         void Copy(const VersionType& rhs) {
+           Major = rhs.Major;
+           Minor = rhs.Minor;
+           Patch = rhs.Patch;
+           Build = rhs.Build;
+           Release = rhs.Release;
+         }
+
+         void Dump(FILE* = 0);
+
+         const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+           snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
+           return str_buf;
+         }
+
+         virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+           if ( ! Reader->ReadUi16BE(&Major) ) return false;
+           if ( ! Reader->ReadUi16BE(&Minor) ) return false;
+           if ( ! Reader->ReadUi16BE(&Patch) ) return false;
+           if ( ! Reader->ReadUi16BE(&Build) ) return false;
+           ui16_t tmp_release;
+           if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
+           Release = (Release_t)tmp_release;
+           return true;
+         }
+
+         inline virtual bool HasValue() const { return true; }
+         inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
+
+         virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+           if ( ! Writer->WriteUi16BE(Major) ) return false;
+           if ( ! Writer->WriteUi16BE(Minor) ) return false;
+           if ( ! Writer->WriteUi16BE(Patch) ) return false;
+           if ( ! Writer->WriteUi16BE(Build) ) return false;
+           if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
+           return true;
+         }
+       };
+
+      /*
+       The RGBALayout type shall be a fixed-size 8 element sequence with a total length
+       of 16 bytes, where each element shall consist of the RGBAComponent type with the
+       following fields:
+
+       Code (UInt8): Enumerated value specifying component (i.e., component identifier).
+       "0" is the layout terminator.
+
+       Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26) 
+         1->32 indicates integer depth
+         253 = HALF (floating point 16-bit value)
+         254 = IEEE floating point 32-bit value
+         255 = IEEE floating point 64-bit value
+         0 = RGBALayout terminator
+
+       A Fill component indicates unused bits. After the components have been specified,
+       the remaining Code and Size fields shall be set to zero (0).
+
+       For each component in the Pixel, one of the following Codes or the terminator
+       shall be specified (explained below):
+
+       Code    ASCII
+
+      */
+      struct RGBALayoutTableEntry
+      {
+       byte_t code;
+       char symbol;
+       const char* label;
+      };
+
+      struct RGBALayoutTableEntry const RGBALayoutTable[] = {
+       { 0x52, 'R', "Red component" },
+       { 0x47, 'G', "Green component" },
+       { 0x42, 'B', "Blue component" },
+       { 0x41, 'A', "Alpha component" },
+       { 0x72, 'r', "Red component (LSBs)" },
+       { 0x67, 'g', "Green component (LSBs)" },
+       { 0x62, 'b', "Blue component (LSBs)" },
+       { 0x61, 'a', "Alpha component (LSBs)" },
+       { 0x46, 'F', "Fill component" },
+       { 0x50, 'P', "Palette code" },
+       { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
+       { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
+       { 0x57, 'W', "Composite Video" },
+       { 0x58, 'X', "Non co-sited luma component" },
+       { 0x59, 'Y', "Luma component" },
+       { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
+       { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
+       { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
+       { 0x77, 'w', "Composite Video (LSBs)" },
+       { 0x78, 'x', "Non co-sited luma component (LSBs)" },
+       { 0x79, 'y', "Luma component (LSBs)" },
+       { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
+       { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
+       { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
+       { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
+       { 0x00, '_', "Terminator" }
+      };
+
+
+      size_t const RGBAValueLength = 16;
+
+      byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
+      byte_t const RGBAValue_RGB_8[RGBAValueLength]  = { 'R', 8,  'G', 8,  'B', 8,  0, 0 };
+      byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
+      byte_t const RGBAValue_YUV_8[RGBAValueLength]  = { 'Y', 8,  'U', 8,  'V', 8,  0, 0 };
+      byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
+
+
+      class RGBALayout : public Kumu::IArchive
+       {
+         byte_t m_value[RGBAValueLength];
+
+       public:
+         RGBALayout();
+         RGBALayout(const byte_t* value);
+         ~RGBALayout();
+
+         RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
+         const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
+         
+         void Set(const byte_t* value) {
+           memcpy(m_value, value, RGBAValueLength);
+         }
+
+         const char* EncodeString(char* buf, ui32_t buf_len) const;
+
+         bool HasValue() const { return true; }
+         ui32_t ArchiveLength() const { return RGBAValueLength; }
+
+         bool Archive(Kumu::MemIOWriter* Writer) const {
+           return Writer->WriteRaw(m_value, RGBAValueLength);
+         }
+
+         bool Unarchive(Kumu::MemIOReader* Reader) {
+           if ( Reader->Remainder() < RGBAValueLength )
+             {
+               return false;
+             }
+
+           memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
+           Reader->SkipOffset(RGBAValueLength);
+           return true;
+         }
+       };
+
+
+      //
+      class Raw : public Kumu::ByteString
+       {
+       public:
+         Raw();
+         Raw(const Raw& rhs) { Copy(rhs); }
+         virtual ~Raw();
+
+         const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
+         void Copy(const Raw& rhs) {
+           if ( KM_SUCCESS(Capacity(rhs.Length())) )
+             {
+               Set(rhs);
+             }
+         }
+
+         //
+          virtual bool Unarchive(Kumu::MemIOReader* Reader);
+         virtual bool Archive(Kumu::MemIOWriter* Writer) const;
+         const char* EncodeString(char* str_buf, ui32_t buf_len) const;
+       };
+
     } // namespace MXF
 } // namespace ASDCP
 
 
+#endif //_MXFTYPES_H_
+
 //
 // end MXFTypes.h
 //