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
107 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
108 ui32_t ItemCount, ItemSize;
109 if ( ! Reader->ReadUi32BE(&ItemCount) ) return false;
110 if ( ! Reader->ReadUi32BE(&ItemSize) ) return false;
112 if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) )
116 for ( ui32_t i = 0; i < ItemCount && result; i++ )
119 result = Tmp.Unarchive(Reader);
122 this->push_back(Tmp);
128 inline virtual bool HasValue() const { return ! this->empty(); }
130 virtual ui32_t ArchiveLength() const {
131 ui32_t arch_size = sizeof(ui32_t)*2;
133 typename std::vector<T>::const_iterator l_i = this->begin();
134 assert(l_i != this->end());
136 for ( ; l_i != this->end(); l_i++ )
137 arch_size += l_i->ArchiveLength();
143 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
144 if ( ! Writer->WriteUi32BE(this->size()) ) return false;
145 byte_t* p = Writer->CurrentData();
147 if ( ! Writer->WriteUi32BE(0) ) return false;
148 if ( this->empty() ) return true;
150 typename std::vector<T>::const_iterator l_i = this->begin();
151 assert(l_i != this->end());
153 ui32_t ItemSize = Writer->Remainder();
154 if ( ! (*l_i).Archive(Writer) ) return false;
155 ItemSize -= Writer->Remainder();
156 Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
160 for ( ; l_i != this->end() && result; l_i++ )
161 result = (*l_i).Archive(Writer);
167 void Dump(FILE* stream = 0, ui32_t depth = 0)
169 char identbuf[IdentBufferLen];
174 typename std::vector<T>::iterator i = this->begin();
175 for ( ; i != this->end(); i++ )
176 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
182 class Array : public std::list<T>, public Kumu::IArchive
189 virtual bool Unarchive(Kumu::MemIOReader* Reader)
193 while ( Reader->Remainder() > 0 && result )
196 result = Tmp.Unarchive(Reader);
197 this->push_back(Tmp);
203 inline virtual bool HasValue() const { return ! this->empty(); }
205 virtual ui32_t ArchiveLength() const {
206 ui32_t arch_size = 0;
208 typename std::list<T>::const_iterator l_i = this->begin();
210 for ( ; l_i != this->end(); l_i++ )
211 arch_size += l_i->ArchiveLength();
217 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
219 typename std::list<T>::const_iterator l_i = this->begin();
221 for ( ; l_i != this->end() && result; l_i++ )
222 result = (*l_i).Archive(Writer);
228 void Dump(FILE* stream = 0, ui32_t depth = 0)
230 char identbuf[IdentBufferLen];
235 typename std::list<T>::iterator i = this->begin();
236 for ( ; i != this->end(); i++ )
237 fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
242 class ISO8String : public std::string, public Kumu::IArchive
246 ISO8String(const char*);
247 ISO8String(const std::string&);
250 const ISO8String& operator=(const char*);
251 const ISO8String& operator=(const std::string&);
253 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
254 inline virtual bool HasValue() const { return ! empty(); }
255 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
256 virtual bool Unarchive(Kumu::MemIOReader* Reader);
257 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
261 class UTF16String : public std::string, public Kumu::IArchive
265 UTF16String(const char*);
266 UTF16String(const std::string&);
269 const UTF16String& operator=(const char*);
270 const UTF16String& operator=(const std::string&);
272 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
273 inline virtual bool HasValue() const { return ! empty(); }
274 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
275 virtual bool Unarchive(Kumu::MemIOReader* Reader);
276 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
280 class Rational : public ASDCP::Rational, public Kumu::IArchive
286 Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
287 Numerator = rhs.Numerator;
288 Denominator = rhs.Denominator;
291 const Rational& operator=(const Rational& rhs) {
292 Numerator = rhs.Numerator;
293 Denominator = rhs.Denominator;
297 Rational(const ASDCP::Rational& rhs) {
298 Numerator = rhs.Numerator;
299 Denominator = rhs.Denominator;
302 const Rational& operator=(const ASDCP::Rational& rhs) {
303 Numerator = rhs.Numerator;
304 Denominator = rhs.Denominator;
309 inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
310 snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
314 inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
315 if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
316 if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
320 inline virtual bool HasValue() const { return true; }
321 inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
323 inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
324 if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
325 if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
331 class VersionType : public Kumu::IArchive
334 enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
341 VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
342 VersionType(const VersionType& rhs) { Copy(rhs); }
343 virtual ~VersionType() {}
345 const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
346 void Copy(const VersionType& rhs) {
351 Release = rhs.Release;
354 void Dump(FILE* = 0);
356 const char* EncodeString(char* str_buf, ui32_t buf_len) const {
357 snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
361 virtual bool Unarchive(Kumu::MemIOReader* Reader) {
362 if ( ! Reader->ReadUi16BE(&Major) ) return false;
363 if ( ! Reader->ReadUi16BE(&Minor) ) return false;
364 if ( ! Reader->ReadUi16BE(&Patch) ) return false;
365 if ( ! Reader->ReadUi16BE(&Build) ) return false;
367 if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
368 Release = (Release_t)tmp_release;
372 inline virtual bool HasValue() const { return true; }
373 inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
375 virtual bool Archive(Kumu::MemIOWriter* Writer) const {
376 if ( ! Writer->WriteUi16BE(Major) ) return false;
377 if ( ! Writer->WriteUi16BE(Minor) ) return false;
378 if ( ! Writer->WriteUi16BE(Patch) ) return false;
379 if ( ! Writer->WriteUi16BE(Build) ) return false;
380 if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
386 The RGBALayout type shall be a fixed-size 8 element sequence with a total length
387 of 16 bytes, where each element shall consist of the RGBAComponent type with the
390 Code (UInt8): Enumerated value specifying component (i.e., component identifier).
391 "0" is the layout terminator.
393 Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26)
394 1->32 indicates integer depth
395 253 = HALF (floating point 16-bit value)
396 254 = IEEE floating point 32-bit value
397 255 = IEEE floating point 64-bit value
398 0 = RGBALayout terminator
400 A Fill component indicates unused bits. After the components have been specified,
401 the remaining Code and Size fields shall be set to zero (0).
403 For each component in the Pixel, one of the following Codes or the terminator
404 shall be specified (explained below):
409 struct RGBALayoutTableEntry
416 struct RGBALayoutTableEntry const RGBALayoutTable[] = {
417 { 0x52, 'R', "Red component" },
418 { 0x47, 'G', "Green component" },
419 { 0x42, 'B', "Blue component" },
420 { 0x41, 'A', "Alpha component" },
421 { 0x72, 'r', "Red component (LSBs)" },
422 { 0x67, 'g', "Green component (LSBs)" },
423 { 0x62, 'b', "Blue component (LSBs)" },
424 { 0x61, 'a', "Alpha component (LSBs)" },
425 { 0x46, 'F', "Fill component" },
426 { 0x50, 'P', "Palette code" },
427 { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
428 { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
429 { 0x57, 'W', "Composite Video" },
430 { 0x58, 'X', "Non co-sited luma component" },
431 { 0x59, 'Y', "Luma component" },
432 { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
433 { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
434 { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
435 { 0x77, 'w', "Composite Video (LSBs)" },
436 { 0x78, 'x', "Non co-sited luma component (LSBs)" },
437 { 0x79, 'y', "Luma component (LSBs)" },
438 { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
439 { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
440 { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
441 { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
442 { 0x00, '_', "Terminator" }
446 size_t const RGBAValueLength = 16;
448 byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
449 byte_t const RGBAValue_RGB_8[RGBAValueLength] = { 'R', 8, 'G', 8, 'B', 8, 0, 0 };
450 byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
451 byte_t const RGBAValue_YUV_8[RGBAValueLength] = { 'Y', 8, 'U', 8, 'V', 8, 0, 0 };
452 byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
455 class RGBALayout : public Kumu::IArchive
457 byte_t m_value[RGBAValueLength];
461 RGBALayout(const byte_t* value);
464 RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
465 const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
467 void Set(const byte_t* value) {
468 memcpy(m_value, value, RGBAValueLength);
471 const char* EncodeString(char* buf, ui32_t buf_len) const;
473 bool HasValue() const { return true; }
474 ui32_t ArchiveLength() const { return RGBAValueLength; }
476 bool Archive(Kumu::MemIOWriter* Writer) const {
477 return Writer->WriteRaw(m_value, RGBAValueLength);
480 bool Unarchive(Kumu::MemIOReader* Reader) {
481 if ( Reader->Remainder() < RGBAValueLength )
486 memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
487 Reader->SkipOffset(RGBAValueLength);
494 class Raw : public Kumu::ByteString
498 Raw(const Raw& rhs) { Copy(rhs); }
501 const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
502 void Copy(const Raw& rhs) {
503 if ( KM_SUCCESS(Capacity(rhs.Length())) )
510 virtual bool Unarchive(Kumu::MemIOReader* Reader);
511 virtual bool Archive(Kumu::MemIOWriter* Writer) const;
512 const char* EncodeString(char* str_buf, ui32_t buf_len) const;
519 #endif //_MXFTYPES_H_