2 Copyright (c) 2005-2015, 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.
41 // used with TLVReader::Read*
43 // these are used below to manufacture arguments
44 #define OBJ_READ_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
45 #define OBJ_WRITE_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
46 #define OBJ_READ_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
47 #define OBJ_WRITE_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
48 #define OBJ_TYPE_ARGS(t) m_Dict->Type(MDD_##t).ul
55 typedef std::pair<ui32_t, ui32_t> ItemInfo;
56 typedef std::map<TagValue, ItemInfo> TagMap;
59 class TLVReader : public Kumu::MemIOReader
63 IPrimerLookup* m_Lookup;
66 ASDCP_NO_COPY_CONSTRUCT(TLVReader);
67 bool FindTL(const MDDEntry&);
70 TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
71 Result_t ReadObject(const MDDEntry&, Kumu::IArchive*);
72 Result_t ReadUi8(const MDDEntry&, ui8_t*);
73 Result_t ReadUi16(const MDDEntry&, ui16_t*);
74 Result_t ReadUi32(const MDDEntry&, ui32_t*);
75 Result_t ReadUi64(const MDDEntry&, ui64_t*);
79 class TLVWriter : public Kumu::MemIOWriter
83 IPrimerLookup* m_Lookup;
86 ASDCP_NO_COPY_CONSTRUCT(TLVWriter);
87 Result_t WriteTag(const MDDEntry&);
90 TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
91 Result_t WriteObject(const MDDEntry&, Kumu::IArchive*);
92 Result_t WriteUi8(const MDDEntry&, ui8_t*);
93 Result_t WriteUi16(const MDDEntry&, ui16_t*);
94 Result_t WriteUi32(const MDDEntry&, ui32_t*);
95 Result_t WriteUi64(const MDDEntry&, ui64_t*);
100 class Batch : public std::vector<T>, public Kumu::IArchive
106 inline virtual bool HasValue() const { return ! this->empty(); }
108 virtual ui32_t ArchiveLength() const {
109 ui32_t arch_size = sizeof(ui32_t) * 2;
110 typename std::vector<T>::const_iterator i;
112 for ( i = this->begin(); i != this->end(); ++i )
114 arch_size += i->ArchiveLength();
121 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
122 if ( ! Writer->WriteUi32BE(this->size()) ) return false;
123 byte_t* p = Writer->CurrentData();
125 if ( ! Writer->WriteUi32BE(0) ) return false;
126 if ( this->empty() ) return true;
128 typename std::vector<T>::const_iterator i = this->begin();
129 assert(i != this->end());
131 ui32_t ItemSize = Writer->Remainder();
132 if ( ! i->Archive(Writer) ) return false;
133 ItemSize -= Writer->Remainder();
134 Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
138 for ( ; i != this->end() && result; ++i )
140 result = i->Archive(Writer);
147 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
148 ui32_t item_count, item_size;
149 if ( ! Reader->ReadUi32BE(&item_count) ) return false;
150 if ( ! Reader->ReadUi32BE(&item_size) ) return false;
152 if ( ( item_count > 65536 ) || ( item_size > 1024 ) )
158 for ( ui32_t i = 0; i < item_count && result; ++i )
161 result = Tmp.Unarchive(Reader);
165 this->push_back(Tmp);
173 void Dump(FILE* stream = 0, ui32_t depth = 0)
175 char identbuf[IdentBufferLen];
180 typename std::vector<T>::iterator i = this->begin();
181 for ( ; i != this->end(); i++ )
182 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
188 class Array : public std::list<T>, public Kumu::IArchive
194 inline virtual bool HasValue() const { return ! this->empty(); }
196 virtual ui32_t ArchiveLength() const {
197 ui32_t arch_size = sizeof(ui32_t) * 2;
198 typename std::list<T>::const_iterator i;
200 for ( i = this->begin(); i != this->end(); ++i )
202 arch_size += i->ArchiveLength();
209 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
210 if ( ! Writer->WriteUi32BE(this->size()) ) return false;
211 byte_t* p = Writer->CurrentData();
213 if ( ! Writer->WriteUi32BE(0) ) return false;
214 if ( this->empty() ) return true;
216 typename std::list<T>::const_iterator i = this->begin();
217 assert(i != this->end());
219 ui32_t ItemSize = Writer->Remainder();
220 if ( ! i->Archive(Writer) ) return false;
221 ItemSize -= Writer->Remainder();
222 Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
226 for ( ; i != this->end() && result; ++i )
228 result = i->Archive(Writer);
235 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
236 ui32_t item_count, item_size;
237 if ( ! Reader->ReadUi32BE(&item_count) ) return false;
238 if ( ! Reader->ReadUi32BE(&item_size) ) return false;
240 if ( ( item_count > 65536 ) || ( item_size > 1024 ) )
246 for ( ui32_t i = 0; i < item_count && result; ++i )
249 result = Tmp.Unarchive(Reader);
253 this->push_back(Tmp);
262 void Dump(FILE* stream = 0, ui32_t depth = 0)
264 char identbuf[IdentBufferLen];
269 typename std::list<T>::iterator i = this->begin();
270 for ( ; i != this->end(); i++ )
271 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
277 class HeadlessArray : public std::list<T>, public Kumu::IArchive
281 virtual ~HeadlessArray() {}
284 virtual bool Unarchive(Kumu::MemIOReader* Reader)
288 while ( Reader->Remainder() > 0 && result )
291 result = Tmp.Unarchive(Reader);
292 this->push_back(Tmp);
298 inline virtual bool HasValue() const { return ! this->empty(); }
300 virtual ui32_t ArchiveLength() const {
301 ui32_t arch_size = 0;
303 typename std::list<T>::const_iterator l_i = this->begin();
305 for ( ; l_i != this->end(); l_i++ )
306 arch_size += l_i->ArchiveLength();
312 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
314 typename std::list<T>::const_iterator l_i = this->begin();
316 for ( ; l_i != this->end() && result; l_i++ )
317 result = (*l_i).Archive(Writer);
323 void Dump(FILE* stream = 0, ui32_t depth = 0)
325 char identbuf[IdentBufferLen];
330 typename std::list<T>::iterator i = this->begin();
331 for ( ; i != this->end(); i++ )
332 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
337 class ISO8String : public std::string, public Kumu::IArchive
341 ISO8String(const char*);
342 ISO8String(const std::string&);
345 const ISO8String& operator=(const char*);
346 const ISO8String& operator=(const std::string&);
348 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
349 inline virtual bool HasValue() const { return ! empty(); }
350 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
351 virtual bool Unarchive(Kumu::MemIOReader* Reader);
352 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
356 class UTF16String : public std::string, public Kumu::IArchive
360 UTF16String(const char*);
361 UTF16String(const std::string&);
364 const UTF16String& operator=(const char*);
365 const UTF16String& operator=(const std::string&);
367 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
368 inline virtual bool HasValue() const { return ! empty(); }
369 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
370 virtual bool Unarchive(Kumu::MemIOReader* Reader);
371 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
375 class Rational : public ASDCP::Rational, public Kumu::IArchive
381 Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
382 Numerator = rhs.Numerator;
383 Denominator = rhs.Denominator;
386 const Rational& operator=(const Rational& rhs) {
387 Numerator = rhs.Numerator;
388 Denominator = rhs.Denominator;
392 Rational(const ASDCP::Rational& rhs) {
393 Numerator = rhs.Numerator;
394 Denominator = rhs.Denominator;
397 const Rational& operator=(const ASDCP::Rational& rhs) {
398 Numerator = rhs.Numerator;
399 Denominator = rhs.Denominator;
404 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
405 snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
409 inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
410 if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
411 if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
415 inline virtual bool HasValue() const { return true; }
416 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
418 inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
419 if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
420 if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
426 class VersionType : public Kumu::IArchive
429 enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
436 VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
437 VersionType(const VersionType& rhs) { Copy(rhs); }
438 virtual ~VersionType() {}
440 const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
441 void Copy(const VersionType& rhs) {
446 Release = rhs.Release;
449 void Dump(FILE* = 0);
451 const char* EncodeString(char* str_buf, ui32_t buf_len) const {
452 snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
456 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
457 if ( ! Reader->ReadUi16BE(&Major) ) return false;
458 if ( ! Reader->ReadUi16BE(&Minor) ) return false;
459 if ( ! Reader->ReadUi16BE(&Patch) ) return false;
460 if ( ! Reader->ReadUi16BE(&Build) ) return false;
462 if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
463 Release = (Release_t)tmp_release;
467 inline virtual bool HasValue() const { return true; }
468 inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
470 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
471 if ( ! Writer->WriteUi16BE(Major) ) return false;
472 if ( ! Writer->WriteUi16BE(Minor) ) return false;
473 if ( ! Writer->WriteUi16BE(Patch) ) return false;
474 if ( ! Writer->WriteUi16BE(Build) ) return false;
475 if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
481 The RGBALayout type shall be a fixed-size 8 element sequence with a total length
482 of 16 bytes, where each element shall consist of the RGBAComponent type with the
485 Code (UInt8): Enumerated value specifying component (i.e., component identifier).
486 "0" is the layout terminator.
488 Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26)
489 1->32 indicates integer depth
490 253 = HALF (floating point 16-bit value)
491 254 = IEEE floating point 32-bit value
492 255 = IEEE floating point 64-bit value
493 0 = RGBALayout terminator
495 A Fill component indicates unused bits. After the components have been specified,
496 the remaining Code and Size fields shall be set to zero (0).
498 For each component in the Pixel, one of the following Codes or the terminator
499 shall be specified (explained below):
504 struct RGBALayoutTableEntry
511 struct RGBALayoutTableEntry const RGBALayoutTable[] = {
512 { 0x52, 'R', "Red component" },
513 { 0x47, 'G', "Green component" },
514 { 0x42, 'B', "Blue component" },
515 { 0x41, 'A', "Alpha component" },
516 { 0x72, 'r', "Red component (LSBs)" },
517 { 0x67, 'g', "Green component (LSBs)" },
518 { 0x62, 'b', "Blue component (LSBs)" },
519 { 0x61, 'a', "Alpha component (LSBs)" },
520 { 0x46, 'F', "Fill component" },
521 { 0x50, 'P', "Palette code" },
522 { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
523 { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
524 { 0x57, 'W', "Composite Video" },
525 { 0x58, 'X', "Non co-sited luma component" },
526 { 0x59, 'Y', "Luma component" },
527 { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
528 { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
529 { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
530 { 0x77, 'w', "Composite Video (LSBs)" },
531 { 0x78, 'x', "Non co-sited luma component (LSBs)" },
532 { 0x79, 'y', "Luma component (LSBs)" },
533 { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
534 { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
535 { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
536 { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
537 { 0x00, '_', "Terminator" }
541 size_t const RGBAValueLength = 16;
543 byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
544 byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 };
545 byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
546 byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 };
547 byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
550 class RGBALayout : public Kumu::IArchive
552 byte_t m_value[RGBAValueLength];
556 RGBALayout(const byte_t* value);
559 RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
560 const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
562 void Set(const byte_t* value) {
563 memcpy(m_value, value, RGBAValueLength);
566 const char* EncodeString(char* buf, ui32_t buf_len) const;
568 bool HasValue() const { return true; }
569 ui32_t ArchiveLength() const { return RGBAValueLength; }
571 bool Archive(Kumu::MemIOWriter* Writer) const {
572 return Writer->WriteRaw(m_value, RGBAValueLength);
575 bool Unarchive(Kumu::MemIOReader* Reader) {
576 if ( Reader->Remainder() < RGBAValueLength )
581 memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
582 Reader->SkipOffset(RGBAValueLength);
589 class Raw : public Kumu::ByteString
593 Raw(const Raw& rhs) { Copy(rhs); }
596 const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
597 void Copy(const Raw& rhs) {
598 if ( KM_SUCCESS(Capacity(rhs.Length())) )
605 virtual bool Unarchive(Kumu::MemIOReader* Reader);
606 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
607 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
614 #endif //_MXFTYPES_H_