2 Copyright (c) 2005-2016, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 // used with TLVReader::Read*
44 // these are used below to manufacture arguments
45 #define OBJ_READ_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
46 #define OBJ_WRITE_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
47 #define OBJ_READ_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
48 #define OBJ_WRITE_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
49 #define OBJ_TYPE_ARGS(t) m_Dict->Type(MDD_##t).ul
56 typedef std::pair<ui32_t, ui32_t> ItemInfo;
57 typedef std::map<TagValue, ItemInfo> TagMap;
60 class TLVReader : public Kumu::MemIOReader
64 IPrimerLookup* m_Lookup;
67 ASDCP_NO_COPY_CONSTRUCT(TLVReader);
70 TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
71 bool FindTL(const MDDEntry&);
72 Result_t ReadObject(const MDDEntry&, Kumu::IArchive*);
73 Result_t ReadUi8(const MDDEntry&, ui8_t*);
74 Result_t ReadUi16(const MDDEntry&, ui16_t*);
75 Result_t ReadUi32(const MDDEntry&, ui32_t*);
76 Result_t ReadUi64(const MDDEntry&, ui64_t*);
80 class TLVWriter : public Kumu::MemIOWriter
84 IPrimerLookup* m_Lookup;
87 ASDCP_NO_COPY_CONSTRUCT(TLVWriter);
88 Result_t WriteTag(const MDDEntry&);
91 TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
92 Result_t WriteObject(const MDDEntry&, Kumu::IArchive*);
93 Result_t WriteUi8(const MDDEntry&, ui8_t*);
94 Result_t WriteUi16(const MDDEntry&, ui16_t*);
95 Result_t WriteUi32(const MDDEntry&, ui32_t*);
96 Result_t WriteUi64(const MDDEntry&, ui64_t*);
100 template <class ContainerType>
101 class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive
104 FixedSizeItemCollection() {}
105 virtual ~FixedSizeItemCollection() {}
107 ui32_t ItemSize() const {
108 typename ContainerType::value_type tmp_item;
109 return tmp_item.ArchiveLength();
112 bool HasValue() const { return ! this->empty(); }
114 ui32_t ArchiveLength() const {
115 return ( sizeof(ui32_t) * 2 ) + ( this->size() * this->ItemSize() );
118 bool Archive(Kumu::MemIOWriter* Writer) const {
119 if ( ! Writer->WriteUi32BE(this->size()) ) return false;
120 if ( ! Writer->WriteUi32BE(this->ItemSize()) ) return false;
121 if ( this->empty() ) return true;
123 typename ContainerType::const_iterator i;
125 for ( i = this->begin(); i != this->end() && result; ++i )
127 result = i->Archive(Writer);
134 bool Unarchive(Kumu::MemIOReader* Reader) {
135 ui32_t item_count, item_size;
136 if ( ! Reader->ReadUi32BE(&item_count) ) return false;
137 if ( ! Reader->ReadUi32BE(&item_size) ) return false;
139 if ( item_count > 0 )
141 if ( this->ItemSize() != item_size ) return false;
145 for ( ui32_t i = 0; i < item_count && result; ++i )
147 typename ContainerType::value_type tmp_item;
148 result = tmp_item.Unarchive(Reader);
152 this->push_back(tmp_item);
159 void Dump(FILE* stream = 0, ui32_t depth = 0) {
160 char identbuf[IdentBufferLen];
167 typename ContainerType::const_iterator i;
168 for ( i = this->begin(); i != this->end(); ++i )
170 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
176 template <class item_type>
177 class PushSet : public std::set<item_type>
181 virtual ~PushSet() {}
182 void push_back(const item_type& item) { this->insert(item); }
185 template <class ItemType>
186 class Batch : public FixedSizeItemCollection<PushSet<ItemType> >
193 template <class ItemType>
194 class Array : public FixedSizeItemCollection<std::vector<ItemType> >
203 class SimpleArray : public std::list<T>, public Kumu::IArchive
207 virtual ~SimpleArray() {}
210 bool Unarchive(Kumu::MemIOReader* Reader)
214 while ( Reader->Remainder() > 0 && result )
217 result = Tmp.Unarchive(Reader);
221 this->push_back(Tmp);
228 inline bool HasValue() const { return ! this->empty(); }
230 ui32_t ArchiveLength() const {
231 ui32_t arch_size = 0;
233 typename std::list<T>::const_iterator l_i = this->begin();
235 for ( ; l_i != this->end(); l_i++ )
236 arch_size += l_i->ArchiveLength();
242 bool Archive(Kumu::MemIOWriter* Writer) const {
244 typename std::list<T>::const_iterator l_i = this->begin();
246 for ( ; l_i != this->end() && result; l_i++ )
247 result = (*l_i).Archive(Writer);
253 void Dump(FILE* stream = 0, ui32_t depth = 0)
255 char identbuf[IdentBufferLen];
260 typename std::list<T>::iterator i = this->begin();
261 for ( ; i != this->end(); i++ )
262 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
267 class ISO8String : public std::string, public Kumu::IArchive
271 ISO8String(const char*);
272 ISO8String(const std::string&);
275 const ISO8String& operator=(const char*);
276 const ISO8String& operator=(const std::string&);
278 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
279 inline virtual bool HasValue() const { return ! empty(); }
280 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
281 virtual bool Unarchive(Kumu::MemIOReader* Reader);
282 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
286 class UTF16String : public std::string, public Kumu::IArchive
290 UTF16String(const char*);
291 UTF16String(const std::string&);
294 const UTF16String& operator=(const char*);
295 const UTF16String& operator=(const std::string&);
297 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
298 inline virtual bool HasValue() const { return ! empty(); }
299 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
300 virtual bool Unarchive(Kumu::MemIOReader* Reader);
301 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
305 class Rational : public ASDCP::Rational, public Kumu::IArchive
311 Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
312 Numerator = rhs.Numerator;
313 Denominator = rhs.Denominator;
316 const Rational& operator=(const Rational& rhs) {
317 Numerator = rhs.Numerator;
318 Denominator = rhs.Denominator;
322 Rational(const ASDCP::Rational& rhs) {
323 Numerator = rhs.Numerator;
324 Denominator = rhs.Denominator;
327 const Rational& operator=(const ASDCP::Rational& rhs) {
328 Numerator = rhs.Numerator;
329 Denominator = rhs.Denominator;
334 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
335 snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
339 inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
340 if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
341 if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
345 inline virtual bool HasValue() const { return true; }
346 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
348 inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
349 if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
350 if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
356 class LineMapPair : public Kumu::IArchive
365 LineMapPair(const ui32_t& first, const ui32_t& second) : IArchive() {
370 LineMapPair(const LineMapPair& rhs) : IArchive() {
375 const LineMapPair& operator=(const LineMapPair& rhs) {
382 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
383 snprintf(str_buf, buf_len, "%d,%d", First, Second);
387 inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
389 if ( ! Reader->ReadUi32BE(&n) ) return false;
390 if ( n != 4 ) return false;
391 if ( ! Reader->ReadUi32BE(&n) ) return false;
392 if ( n != 2 ) return false;
393 if ( ! Reader->ReadUi32BE((ui32_t*)&First) ) return false;
394 if ( ! Reader->ReadUi32BE((ui32_t*)&Second) ) return false;
398 inline virtual bool HasValue() const { return true; }
399 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*4; }
401 inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
402 if ( ! Writer->WriteUi32BE(4UL) ) return false;
403 if ( ! Writer->WriteUi32BE(2UL) ) return false;
404 if ( ! Writer->WriteUi32BE((ui32_t)First) ) return false;
405 if ( ! Writer->WriteUi32BE((ui32_t)Second) ) return false;
411 class VersionType : public Kumu::IArchive
414 enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
421 VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
422 VersionType(const VersionType& rhs) { Copy(rhs); }
423 virtual ~VersionType() {}
425 const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
426 void Copy(const VersionType& rhs) {
431 Release = rhs.Release;
434 void Dump(FILE* = 0);
436 const char* EncodeString(char* str_buf, ui32_t buf_len) const {
437 snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
441 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
442 if ( ! Reader->ReadUi16BE(&Major) ) return false;
443 if ( ! Reader->ReadUi16BE(&Minor) ) return false;
444 if ( ! Reader->ReadUi16BE(&Patch) ) return false;
445 if ( ! Reader->ReadUi16BE(&Build) ) return false;
447 if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
448 Release = (Release_t)tmp_release;
452 inline virtual bool HasValue() const { return true; }
453 inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
455 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
456 if ( ! Writer->WriteUi16BE(Major) ) return false;
457 if ( ! Writer->WriteUi16BE(Minor) ) return false;
458 if ( ! Writer->WriteUi16BE(Patch) ) return false;
459 if ( ! Writer->WriteUi16BE(Build) ) return false;
460 if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
466 The RGBALayout type shall be a fixed-size 8 element sequence with a total length
467 of 16 bytes, where each element shall consist of the RGBAComponent type with the
470 Code (UInt8): Enumerated value specifying component (i.e., component identifier).
471 "0" is the layout terminator.
473 Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26)
474 1->32 indicates integer depth
475 253 = HALF (floating point 16-bit value)
476 254 = IEEE floating point 32-bit value
477 255 = IEEE floating point 64-bit value
478 0 = RGBALayout terminator
480 A Fill component indicates unused bits. After the components have been specified,
481 the remaining Code and Size fields shall be set to zero (0).
483 For each component in the Pixel, one of the following Codes or the terminator
484 shall be specified (explained below):
489 struct RGBALayoutTableEntry
496 struct RGBALayoutTableEntry const RGBALayoutTable[] = {
497 { 0x52, 'R', "Red component" },
498 { 0x47, 'G', "Green component" },
499 { 0x42, 'B', "Blue component" },
500 { 0x41, 'A', "Alpha component" },
501 { 0x72, 'r', "Red component (LSBs)" },
502 { 0x67, 'g', "Green component (LSBs)" },
503 { 0x62, 'b', "Blue component (LSBs)" },
504 { 0x61, 'a', "Alpha component (LSBs)" },
505 { 0x46, 'F', "Fill component" },
506 { 0x50, 'P', "Palette code" },
507 { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
508 { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
509 { 0x57, 'W', "Composite Video" },
510 { 0x58, 'X', "Non co-sited luma component" },
511 { 0x59, 'Y', "Luma component" },
512 { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
513 { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
514 { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
515 { 0x77, 'w', "Composite Video (LSBs)" },
516 { 0x78, 'x', "Non co-sited luma component (LSBs)" },
517 { 0x79, 'y', "Luma component (LSBs)" },
518 { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
519 { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
520 { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
521 { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
522 { 0x00, '_', "Terminator" }
526 size_t const RGBAValueLength = 16;
528 byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
529 byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 };
530 byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
531 byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 };
532 byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
535 class RGBALayout : public Kumu::IArchive
537 byte_t m_value[RGBAValueLength];
541 RGBALayout(const byte_t* value);
544 RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
545 const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
547 void Set(const byte_t* value) {
548 memcpy(m_value, value, RGBAValueLength);
551 const char* EncodeString(char* buf, ui32_t buf_len) const;
553 bool HasValue() const { return true; }
554 ui32_t ArchiveLength() const { return RGBAValueLength; }
556 bool Archive(Kumu::MemIOWriter* Writer) const {
557 return Writer->WriteRaw(m_value, RGBAValueLength);
560 bool Unarchive(Kumu::MemIOReader* Reader) {
561 if ( Reader->Remainder() < RGBAValueLength )
566 memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
567 Reader->SkipOffset(RGBAValueLength);
574 class Raw : public Kumu::ByteString
578 Raw(const Raw& rhs) { Copy(rhs); }
581 const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
582 void Copy(const Raw& rhs) {
583 if ( KM_SUCCESS(Capacity(rhs.Length())) )
590 virtual bool Unarchive(Kumu::MemIOReader* Reader);
591 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
592 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
599 #endif //_MXFTYPES_H_