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);
68 bool FindTL(const MDDEntry&);
71 TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
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;
138 if ( this->ItemSize() != item_size ) return false;
141 for ( ui32_t i = 0; i < item_count && result; ++i )
143 typename ContainerType::value_type tmp_item;
144 result = tmp_item.Unarchive(Reader);
148 this->push_back(tmp_item);
155 void Dump(FILE* stream = 0, ui32_t depth = 0) {
156 char identbuf[IdentBufferLen];
163 typename ContainerType::const_iterator i;
164 for ( i = this->begin(); i != this->end(); ++i )
166 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
172 template <class item_type>
173 class PushSet : public std::set<item_type>
177 virtual ~PushSet() {}
178 void push_back(const item_type& item) { this->insert(item); }
181 template <class ItemType>
182 class Batch : public FixedSizeItemCollection<PushSet<ItemType> >
189 template <class ItemType>
190 class Array : public FixedSizeItemCollection<std::vector<ItemType> >
199 class SimpleArray : public std::list<T>, public Kumu::IArchive
203 virtual ~SimpleArray() {}
206 virtual bool Unarchive(Kumu::MemIOReader* Reader)
210 while ( Reader->Remainder() > 0 && result )
213 result = Tmp.Unarchive(Reader);
214 this->push_back(Tmp);
220 inline virtual bool HasValue() const { return ! this->empty(); }
222 virtual ui32_t ArchiveLength() const {
223 ui32_t arch_size = 0;
225 typename std::list<T>::const_iterator l_i = this->begin();
227 for ( ; l_i != this->end(); l_i++ )
228 arch_size += l_i->ArchiveLength();
234 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
236 typename std::list<T>::const_iterator l_i = this->begin();
238 for ( ; l_i != this->end() && result; l_i++ )
239 result = (*l_i).Archive(Writer);
245 void Dump(FILE* stream = 0, ui32_t depth = 0)
247 char identbuf[IdentBufferLen];
252 typename std::list<T>::iterator i = this->begin();
253 for ( ; i != this->end(); i++ )
254 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
259 class ISO8String : public std::string, public Kumu::IArchive
263 ISO8String(const char*);
264 ISO8String(const std::string&);
267 const ISO8String& operator=(const char*);
268 const ISO8String& operator=(const std::string&);
270 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
271 inline virtual bool HasValue() const { return ! empty(); }
272 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
273 virtual bool Unarchive(Kumu::MemIOReader* Reader);
274 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
278 class UTF16String : public std::string, public Kumu::IArchive
282 UTF16String(const char*);
283 UTF16String(const std::string&);
286 const UTF16String& operator=(const char*);
287 const UTF16String& operator=(const std::string&);
289 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
290 inline virtual bool HasValue() const { return ! empty(); }
291 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
292 virtual bool Unarchive(Kumu::MemIOReader* Reader);
293 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
297 class Rational : public ASDCP::Rational, public Kumu::IArchive
303 Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
304 Numerator = rhs.Numerator;
305 Denominator = rhs.Denominator;
308 const Rational& operator=(const Rational& rhs) {
309 Numerator = rhs.Numerator;
310 Denominator = rhs.Denominator;
314 Rational(const ASDCP::Rational& rhs) {
315 Numerator = rhs.Numerator;
316 Denominator = rhs.Denominator;
319 const Rational& operator=(const ASDCP::Rational& rhs) {
320 Numerator = rhs.Numerator;
321 Denominator = rhs.Denominator;
326 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
327 snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
331 inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
332 if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
333 if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
337 inline virtual bool HasValue() const { return true; }
338 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
340 inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
341 if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
342 if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
348 class VersionType : public Kumu::IArchive
351 enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
358 VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
359 VersionType(const VersionType& rhs) { Copy(rhs); }
360 virtual ~VersionType() {}
362 const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
363 void Copy(const VersionType& rhs) {
368 Release = rhs.Release;
371 void Dump(FILE* = 0);
373 const char* EncodeString(char* str_buf, ui32_t buf_len) const {
374 snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
378 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
379 if ( ! Reader->ReadUi16BE(&Major) ) return false;
380 if ( ! Reader->ReadUi16BE(&Minor) ) return false;
381 if ( ! Reader->ReadUi16BE(&Patch) ) return false;
382 if ( ! Reader->ReadUi16BE(&Build) ) return false;
384 if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
385 Release = (Release_t)tmp_release;
389 inline virtual bool HasValue() const { return true; }
390 inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
392 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
393 if ( ! Writer->WriteUi16BE(Major) ) return false;
394 if ( ! Writer->WriteUi16BE(Minor) ) return false;
395 if ( ! Writer->WriteUi16BE(Patch) ) return false;
396 if ( ! Writer->WriteUi16BE(Build) ) return false;
397 if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
403 The RGBALayout type shall be a fixed-size 8 element sequence with a total length
404 of 16 bytes, where each element shall consist of the RGBAComponent type with the
407 Code (UInt8): Enumerated value specifying component (i.e., component identifier).
408 "0" is the layout terminator.
410 Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26)
411 1->32 indicates integer depth
412 253 = HALF (floating point 16-bit value)
413 254 = IEEE floating point 32-bit value
414 255 = IEEE floating point 64-bit value
415 0 = RGBALayout terminator
417 A Fill component indicates unused bits. After the components have been specified,
418 the remaining Code and Size fields shall be set to zero (0).
420 For each component in the Pixel, one of the following Codes or the terminator
421 shall be specified (explained below):
426 struct RGBALayoutTableEntry
433 struct RGBALayoutTableEntry const RGBALayoutTable[] = {
434 { 0x52, 'R', "Red component" },
435 { 0x47, 'G', "Green component" },
436 { 0x42, 'B', "Blue component" },
437 { 0x41, 'A', "Alpha component" },
438 { 0x72, 'r', "Red component (LSBs)" },
439 { 0x67, 'g', "Green component (LSBs)" },
440 { 0x62, 'b', "Blue component (LSBs)" },
441 { 0x61, 'a', "Alpha component (LSBs)" },
442 { 0x46, 'F', "Fill component" },
443 { 0x50, 'P', "Palette code" },
444 { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
445 { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
446 { 0x57, 'W', "Composite Video" },
447 { 0x58, 'X', "Non co-sited luma component" },
448 { 0x59, 'Y', "Luma component" },
449 { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
450 { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
451 { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
452 { 0x77, 'w', "Composite Video (LSBs)" },
453 { 0x78, 'x', "Non co-sited luma component (LSBs)" },
454 { 0x79, 'y', "Luma component (LSBs)" },
455 { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
456 { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
457 { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
458 { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
459 { 0x00, '_', "Terminator" }
463 size_t const RGBAValueLength = 16;
465 byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
466 byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 };
467 byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
468 byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 };
469 byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
472 class RGBALayout : public Kumu::IArchive
474 byte_t m_value[RGBAValueLength];
478 RGBALayout(const byte_t* value);
481 RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
482 const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
484 void Set(const byte_t* value) {
485 memcpy(m_value, value, RGBAValueLength);
488 const char* EncodeString(char* buf, ui32_t buf_len) const;
490 bool HasValue() const { return true; }
491 ui32_t ArchiveLength() const { return RGBAValueLength; }
493 bool Archive(Kumu::MemIOWriter* Writer) const {
494 return Writer->WriteRaw(m_value, RGBAValueLength);
497 bool Unarchive(Kumu::MemIOReader* Reader) {
498 if ( Reader->Remainder() < RGBAValueLength )
503 memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
504 Reader->SkipOffset(RGBAValueLength);
511 class Raw : public Kumu::ByteString
515 Raw(const Raw& rhs) { Copy(rhs); }
518 const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
519 void Copy(const Raw& rhs) {
520 if ( KM_SUCCESS(Capacity(rhs.Length())) )
527 virtual bool Unarchive(Kumu::MemIOReader* Reader);
528 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
529 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
536 #endif //_MXFTYPES_H_