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.
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 VersionType : public Kumu::IArchive
359 enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
366 VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
367 VersionType(const VersionType& rhs) { Copy(rhs); }
368 virtual ~VersionType() {}
370 const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
371 void Copy(const VersionType& rhs) {
376 Release = rhs.Release;
379 void Dump(FILE* = 0);
381 const char* EncodeString(char* str_buf, ui32_t buf_len) const {
382 snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
386 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
387 if ( ! Reader->ReadUi16BE(&Major) ) return false;
388 if ( ! Reader->ReadUi16BE(&Minor) ) return false;
389 if ( ! Reader->ReadUi16BE(&Patch) ) return false;
390 if ( ! Reader->ReadUi16BE(&Build) ) return false;
392 if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
393 Release = (Release_t)tmp_release;
397 inline virtual bool HasValue() const { return true; }
398 inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
400 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
401 if ( ! Writer->WriteUi16BE(Major) ) return false;
402 if ( ! Writer->WriteUi16BE(Minor) ) return false;
403 if ( ! Writer->WriteUi16BE(Patch) ) return false;
404 if ( ! Writer->WriteUi16BE(Build) ) return false;
405 if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
411 The RGBALayout type shall be a fixed-size 8 element sequence with a total length
412 of 16 bytes, where each element shall consist of the RGBAComponent type with the
415 Code (UInt8): Enumerated value specifying component (i.e., component identifier).
416 "0" is the layout terminator.
418 Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26)
419 1->32 indicates integer depth
420 253 = HALF (floating point 16-bit value)
421 254 = IEEE floating point 32-bit value
422 255 = IEEE floating point 64-bit value
423 0 = RGBALayout terminator
425 A Fill component indicates unused bits. After the components have been specified,
426 the remaining Code and Size fields shall be set to zero (0).
428 For each component in the Pixel, one of the following Codes or the terminator
429 shall be specified (explained below):
434 struct RGBALayoutTableEntry
441 struct RGBALayoutTableEntry const RGBALayoutTable[] = {
442 { 0x52, 'R', "Red component" },
443 { 0x47, 'G', "Green component" },
444 { 0x42, 'B', "Blue component" },
445 { 0x41, 'A', "Alpha component" },
446 { 0x72, 'r', "Red component (LSBs)" },
447 { 0x67, 'g', "Green component (LSBs)" },
448 { 0x62, 'b', "Blue component (LSBs)" },
449 { 0x61, 'a', "Alpha component (LSBs)" },
450 { 0x46, 'F', "Fill component" },
451 { 0x50, 'P', "Palette code" },
452 { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
453 { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
454 { 0x57, 'W', "Composite Video" },
455 { 0x58, 'X', "Non co-sited luma component" },
456 { 0x59, 'Y', "Luma component" },
457 { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
458 { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
459 { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
460 { 0x77, 'w', "Composite Video (LSBs)" },
461 { 0x78, 'x', "Non co-sited luma component (LSBs)" },
462 { 0x79, 'y', "Luma component (LSBs)" },
463 { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
464 { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
465 { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
466 { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
467 { 0x00, '_', "Terminator" }
471 size_t const RGBAValueLength = 16;
473 byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
474 byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 };
475 byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
476 byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 };
477 byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
480 class RGBALayout : public Kumu::IArchive
482 byte_t m_value[RGBAValueLength];
486 RGBALayout(const byte_t* value);
489 RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
490 const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
492 void Set(const byte_t* value) {
493 memcpy(m_value, value, RGBAValueLength);
496 const char* EncodeString(char* buf, ui32_t buf_len) const;
498 bool HasValue() const { return true; }
499 ui32_t ArchiveLength() const { return RGBAValueLength; }
501 bool Archive(Kumu::MemIOWriter* Writer) const {
502 return Writer->WriteRaw(m_value, RGBAValueLength);
505 bool Unarchive(Kumu::MemIOReader* Reader) {
506 if ( Reader->Remainder() < RGBAValueLength )
511 memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
512 Reader->SkipOffset(RGBAValueLength);
519 class Raw : public Kumu::ByteString
523 Raw(const Raw& rhs) { Copy(rhs); }
526 const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
527 void Copy(const Raw& rhs) {
528 if ( KM_SUCCESS(Capacity(rhs.Length())) )
535 virtual bool Unarchive(Kumu::MemIOReader* Reader);
536 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
537 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
544 #endif //_MXFTYPES_H_