X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FMXFTypes.h;h=c49fed9b6f07b267e1f5de0621865dc7c65a4db2;hb=f4061a21fffad4fdf8dbb2f193f0f0960b25421c;hp=e98a2e9d7946284b312ef35a64ee92261a3a7650;hpb=0cc43cc3765c003d60196ff45213c2835281a0c3;p=asdcplib.git diff --git a/src/MXFTypes.h b/src/MXFTypes.h index e98a2e9..c49fed9 100755 --- a/src/MXFTypes.h +++ b/src/MXFTypes.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2012, John Hurst +Copyright (c) 2005-2016, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -35,6 +35,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "KLV.h" #include #include +#include #include #include @@ -64,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*); @@ -96,97 +97,117 @@ namespace ASDCP }; // - template - class Batch : public std::vector, public Kumu::IArchive + template + class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive { public: - Batch() {} - virtual ~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(); + } + + bool HasValue() const { return ! this->empty(); } - if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) ) - return false; + 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 ) - this->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() {} - virtual ~Array() {} + SimpleArray() {} + virtual ~SimpleArray() {} // - virtual bool Unarchive(Kumu::MemIOReader* Reader) + bool Unarchive(Kumu::MemIOReader* Reader) { bool result = true; @@ -194,15 +215,19 @@ namespace ASDCP { T Tmp; result = Tmp.Unarchive(Reader); - this->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(); @@ -214,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(); @@ -252,7 +277,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; }; @@ -271,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; }; @@ -327,6 +352,157 @@ namespace ASDCP } }; + // + 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 + { + 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: + 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 { @@ -354,7 +530,7 @@ namespace ASDCP 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; } @@ -382,6 +558,114 @@ 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 {