X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FMXFTypes.h;h=c49fed9b6f07b267e1f5de0621865dc7c65a4db2;hb=f4061a21fffad4fdf8dbb2f193f0f0960b25421c;hp=20d12da9ec4679b563e85f6fb8c27beab6d75994;hpb=7827a7e7572601440568788cb028ee883498fa15;p=asdcplib.git diff --git a/src/MXFTypes.h b/src/MXFTypes.h index 20d12da..c49fed9 100755 --- a/src/MXFTypes.h +++ b/src/MXFTypes.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2006, John Hurst +Copyright (c) 2005-2016, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,15 +35,18 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "KLV.h" #include #include +#include #include #include // used with TLVReader::Read* // // these are used below to manufacture arguments -#define OBJ_READ_ARGS(s,l) Dict::Type(MDD_##s##_##l), &l -#define OBJ_WRITE_ARGS(s,l) Dict::Type(MDD_##s##_##l), &l -#define OBJ_TYPE_ARGS(t) Dict::Type(MDD_##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 @@ -62,10 +65,10 @@ namespace ASDCP TLVReader(); ASDCP_NO_COPY_CONSTRUCT(TLVReader); - bool FindTL(const MDDEntry&); public: TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0); + 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*); @@ -94,97 +97,117 @@ namespace ASDCP }; // - template - class Batch : public std::vector, public Kumu::IArchive + template + class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive { public: - Batch() {} - ~Batch() {} + FixedSizeItemCollection() {} + virtual ~FixedSizeItemCollection() {} - // - virtual bool Unarchive(Kumu::MemIOReader* Reader) { - ui32_t ItemCount, ItemSize; - if ( ! Reader->ReadUi32BE(&ItemCount) ) return false; - if ( ! Reader->ReadUi32BE(&ItemSize) ) return false; + ui32_t ItemSize() const { + typename ContainerType::value_type tmp_item; + return tmp_item.ArchiveLength(); + } - if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) ) - return false; + bool HasValue() const { return ! this->empty(); } + ui32_t ArchiveLength() const { + return ( sizeof(ui32_t) * 2 ) + ( (ui32_t)this->size() * this->ItemSize() ); + } + + 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 ( ui32_t i = 0; i < ItemCount && result; i++ ) + for ( i = this->begin(); i != this->end() && result; ++i ) { - T Tmp; - result = Tmp.Unarchive(Reader); - - if ( result ) - push_back(Tmp); + result = i->Archive(Writer); } return result; } - inline virtual bool HasValue() const { return ! this->empty(); } - - virtual ui32_t ArchiveLength() const { - ui32_t arch_size = sizeof(ui32_t)*2; - - typename std::vector::const_iterator l_i = this->begin(); - assert(l_i != this->end()); - - for ( ; l_i != this->end(); l_i++ ) - arch_size += l_i->ArchiveLength(); - - return arch_size; - } - // - virtual bool Archive(Kumu::MemIOWriter* Writer) const { - if ( ! Writer->WriteUi32BE(this->size()) ) return false; - byte_t* p = Writer->CurrentData(); + 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 ( ! Writer->WriteUi32BE(0) ) return false; - if ( this->empty() ) return true; - - typename std::vector::const_iterator l_i = this->begin(); - assert(l_i != this->end()); - - ui32_t ItemSize = Writer->Remainder(); - if ( ! (*l_i).Archive(Writer) ) return false; - ItemSize -= Writer->Remainder(); - Kumu::i2p(KM_i32_BE(ItemSize), p); - l_i++; + if ( item_count > 0 ) + { + if ( this->ItemSize() != item_size ) return false; + } bool result = true; - for ( ; l_i != this->end() && result; l_i++ ) - result = (*l_i).Archive(Writer); + for ( ui32_t i = 0; i < item_count && result; ++i ) + { + typename ContainerType::value_type tmp_item; + result = tmp_item.Unarchive(Reader); + + 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::iterator i = this->begin(); - for ( ; i != this->end(); i++ ) + } + + typename ContainerType::const_iterator i; + for ( i = this->begin(); i != this->end(); ++i ) + { fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); - } + } + } }; + + template + class PushSet : public std::set + { + public: + PushSet() {} + virtual ~PushSet() {} + void push_back(const item_type& item) { this->insert(item); } + }; + + template + class Batch : public FixedSizeItemCollection > + { + public: + Batch() {} + virtual ~Batch() {} + }; + + template + class Array : public FixedSizeItemCollection > + { + public: + Array() {} + virtual ~Array() {} + }; + // template - class Array : public std::list, public Kumu::IArchive + class SimpleArray : public std::list, public Kumu::IArchive { public: - Array() {} - ~Array() {} + SimpleArray() {} + virtual ~SimpleArray() {} // - virtual bool Unarchive(Kumu::MemIOReader* Reader) + bool Unarchive(Kumu::MemIOReader* Reader) { bool result = true; @@ -192,15 +215,19 @@ namespace ASDCP { T Tmp; result = Tmp.Unarchive(Reader); - push_back(Tmp); + + if ( result ) + { + this->push_back(Tmp); + } } return result; } - inline virtual bool HasValue() const { return ! this->empty(); } + inline bool HasValue() const { return ! this->empty(); } - virtual ui32_t ArchiveLength() const { + ui32_t ArchiveLength() const { ui32_t arch_size = 0; typename std::list::const_iterator l_i = this->begin(); @@ -212,7 +239,7 @@ namespace ASDCP } // - virtual bool Archive(Kumu::MemIOWriter* Writer) const { + bool Archive(Kumu::MemIOWriter* Writer) const { bool result = true; typename std::list::const_iterator l_i = this->begin(); @@ -237,55 +264,22 @@ namespace ASDCP }; // - class Timestamp : public Kumu::IArchive + class ISO8String : public std::string, public Kumu::IArchive { public: - ui16_t Year; - ui8_t Month; - ui8_t Day; - ui8_t Hour; - ui8_t Minute; - ui8_t Second; - ui8_t Tick; - - Timestamp(); - Timestamp(const Timestamp& rhs); - Timestamp(const char* datestr); - virtual ~Timestamp(); - - const Timestamp& operator=(const Timestamp& rhs); - bool operator<(const Timestamp& rhs) const; - bool operator==(const Timestamp& rhs) const; - bool operator!=(const Timestamp& rhs) const; - - // decode and set value from string formatted by EncodeAsString - Result_t SetFromString(const char* datestr); - - // add the given number of days or hours to the timestamp value. Values less than zero - // will cause the value to decrease - void AddDays(i32_t); - void AddHours(i32_t); - - // Write the timestamp value to the given buffer in the form 2004-05-01 13:20:00.000 - // returns 0 if the buffer is smaller than DateTimeLen - const char* EncodeString(char* str_buf, ui32_t buf_len) const; - - // - inline virtual bool Unarchive(Kumu::MemIOReader* Reader) { - if ( ! Reader->ReadUi16BE(&Year) ) return false; - if ( ! Reader->ReadRaw(&Month, 6) ) return false; - return true; - } + ISO8String() {} + ISO8String(const char*); + ISO8String(const std::string&); + ~ISO8String() {} - inline virtual bool HasValue() const { return true; } - inline virtual ui32_t ArchiveLength() const { return 8L; } + const ISO8String& operator=(const char*); + const ISO8String& operator=(const std::string&); - // - inline virtual bool Archive(Kumu::MemIOWriter* Writer) const { - if ( ! Writer->WriteUi16BE(Year) ) return false; - if ( ! Writer->WriteRaw(&Month, 6) ) return false; - return true; - } + 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; }; // @@ -293,6 +287,8 @@ namespace ASDCP { public: UTF16String() {} + UTF16String(const char*); + UTF16String(const std::string&); ~UTF16String() {} const UTF16String& operator=(const char*); @@ -300,7 +296,7 @@ namespace ASDCP 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 sizeof(ui32_t) + size(); } + 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; }; @@ -357,12 +353,161 @@ namespace ASDCP }; // - class VersionType : public Kumu::IArchive + 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 const char* EncodeString(char* str_buf, ui32_t buf_len) const { + snprintf(str_buf, buf_len, "%d,%d", First, Second); + return str_buf; + } + + 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; + } + + 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 ColorPrimary : public Kumu::IArchive { - ASDCP_NO_COPY_CONSTRUCT(VersionType); + public: + 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; + } + + // + inline const char* EncodeString(char* str_buf, ui32_t buf_len) const { + snprintf(str_buf, buf_len, "%d,%d", X, Y); + return str_buf; + } + + 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 ThreeColorPrimaries : public Kumu::IArchive + { public: - enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE }; + 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; + } + + // + 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; + } + + inline virtual bool Unarchive(Kumu::MemIOReader* Reader) { + First.Unarchive(Reader); + Second.Unarchive(Reader); + Third.Unarchive(Reader); + return true; + } + + inline virtual bool HasValue() const { + return First.HasValue() || Second.HasValue() || Third.HasValue(); + } + + inline virtual ui32_t ArchiveLength() const { + return First.ArchiveLength() + + Second.ArchiveLength() + + Third.ArchiveLength(); + } + + 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; @@ -370,11 +515,22 @@ namespace ASDCP Release_t Release; VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {} - ~VersionType() {} + 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, Release); + snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release)); return str_buf; } @@ -402,14 +558,129 @@ namespace ASDCP } }; + /* + 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 { - ASDCP_NO_COPY_CONSTRUCT(Raw); - public: Raw(); - ~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);