0f38e9d4cbbd91f77a5a71ced9432f0433a36e9f
[asdcplib.git] / src / MXFTypes.h
1 /*
2 Copyright (c) 2005-2019, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
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.
15
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.
26 */
27 /*! \file    MXFTypes.h
28     \version $Id$
29     \brief   MXF objects
30 */
31
32 #ifndef _MXFTYPES_H_
33 #define _MXFTYPES_H_
34
35 #include "KLV.h"
36 #include "AS_DCP.h"
37 #include <list>
38 #include <vector>
39 #include <set>
40 #include <map>
41 #include <wchar.h>
42
43 // used with TLVReader::Read*
44 //
45 // these are used below to manufacture arguments
46 #define OBJ_READ_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
47 #define OBJ_WRITE_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
48 #define OBJ_READ_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
49 #define OBJ_WRITE_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
50 #define OBJ_TYPE_ARGS(t) m_Dict->Type(MDD_##t).ul
51
52
53 namespace ASDCP
54 {
55   namespace MXF
56     {
57       typedef std::pair<ui32_t, ui32_t> ItemInfo;
58       typedef std::map<TagValue, ItemInfo> TagMap;
59
60       //      
61       class TLVReader : public Kumu::MemIOReader
62         {
63
64           TagMap         m_ElementMap;
65           IPrimerLookup* m_Lookup;
66
67           TLVReader();
68           ASDCP_NO_COPY_CONSTRUCT(TLVReader);
69
70         public:
71           TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
72           bool FindTL(const MDDEntry&);
73           Result_t ReadObject(const MDDEntry&, Kumu::IArchive*);
74           Result_t ReadUi8(const MDDEntry&, ui8_t*);
75           Result_t ReadUi16(const MDDEntry&, ui16_t*);
76           Result_t ReadUi32(const MDDEntry&, ui32_t*);
77           Result_t ReadUi64(const MDDEntry&, ui64_t*);
78         };
79
80       //      
81       class TLVWriter : public Kumu::MemIOWriter
82         {
83
84           TagMap         m_ElementMap;
85           IPrimerLookup* m_Lookup;
86
87           TLVWriter();
88           ASDCP_NO_COPY_CONSTRUCT(TLVWriter);
89           Result_t WriteTag(const MDDEntry&);
90
91         public:
92           TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
93           Result_t WriteObject(const MDDEntry&, Kumu::IArchive*);
94           Result_t WriteUi8(const MDDEntry&, ui8_t*);
95           Result_t WriteUi16(const MDDEntry&, ui16_t*);
96           Result_t WriteUi32(const MDDEntry&, ui32_t*);
97           Result_t WriteUi64(const MDDEntry&, ui64_t*);
98         };
99
100       //
101       template <class ContainerType>
102         class FixedSizeItemCollection : public ContainerType, public Kumu::IArchive
103         {
104         public:
105           FixedSizeItemCollection() {}
106           virtual ~FixedSizeItemCollection() {}
107
108           ui32_t ItemSize() const {
109             typename ContainerType::value_type tmp_item;
110             return tmp_item.ArchiveLength();
111           }
112
113           bool HasValue() const { return ! this->empty(); }
114
115           ui32_t ArchiveLength() const {
116             return ( sizeof(ui32_t) * 2 ) +  ( (ui32_t)this->size() * this->ItemSize() );
117           }
118
119           bool Archive(Kumu::MemIOWriter* Writer) const {
120             if ( ! Writer->WriteUi32BE((ui32_t)this->size()) ) return false;
121             if ( ! Writer->WriteUi32BE((ui32_t)this->ItemSize()) ) return false;
122             if ( this->empty() ) return true;
123             
124             typename ContainerType::const_iterator i;
125             bool result = true;
126             for ( i = this->begin(); i != this->end() && result; ++i )
127               {
128                 result = i->Archive(Writer);
129               }
130
131             return result;
132           }
133
134           //
135           bool Unarchive(Kumu::MemIOReader* Reader) {
136             ui32_t item_count, item_size;
137             if ( ! Reader->ReadUi32BE(&item_count) ) return false;
138             if ( ! Reader->ReadUi32BE(&item_size) ) return false;
139
140             if ( item_count > 0 )
141               {
142                 if ( this->ItemSize() != item_size ) return false;
143               }
144
145             bool result = true;
146             for ( ui32_t i = 0; i < item_count && result; ++i )
147               {
148                 typename ContainerType::value_type tmp_item;
149                 result = tmp_item.Unarchive(Reader);
150
151                 if ( result )
152                   {
153                     this->push_back(tmp_item);
154                   }
155               }
156
157             return result;
158           }
159
160           void Dump(FILE* stream = 0, ui32_t depth = 0) {
161             (void) depth;
162             char identbuf[IdentBufferLen];
163
164             if ( stream == 0 )
165               {
166                 stream = stderr;
167               }
168             
169             typename ContainerType::const_iterator i;
170             for ( i = this->begin(); i != this->end(); ++i )
171               {
172                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
173               }
174           }
175         };
176
177
178       template <class item_type>
179         class PushSet : public std::set<item_type>
180       {
181       public:
182         PushSet() {}
183         virtual ~PushSet() {}
184         void push_back(const item_type& item) { this->insert(item); }
185       };
186
187       template <class ItemType>
188         class Batch : public FixedSizeItemCollection<PushSet<ItemType> >
189       {
190       public:
191         Batch() {}
192         virtual ~Batch() {}
193       };
194
195       template <class ItemType>
196         class Array : public FixedSizeItemCollection<std::vector<ItemType> >
197       {
198       public:
199         Array() {}
200         virtual ~Array() {}
201       };
202
203       //
204       template <class T>
205         class SimpleArray : public std::list<T>, public Kumu::IArchive
206         {
207         public:
208           SimpleArray() {}
209           virtual ~SimpleArray() {}
210
211           //
212           bool Unarchive(Kumu::MemIOReader* Reader)
213             {
214               bool result = true;
215
216               while ( Reader->Remainder() > 0 && result )
217                 {
218                   T Tmp;
219                   result = Tmp.Unarchive(Reader);
220
221                   if ( result )
222                     {
223                       this->push_back(Tmp);
224                     }
225                 }
226
227               return result;
228             }
229
230           inline bool HasValue() const { return ! this->empty(); }
231
232           ui32_t ArchiveLength() const {
233             ui32_t arch_size = 0;
234
235             typename std::list<T>::const_iterator l_i = this->begin();
236
237             for ( ; l_i != this->end(); l_i++ )
238               arch_size += l_i->ArchiveLength();
239             
240             return arch_size;
241           }
242
243           //
244           bool Archive(Kumu::MemIOWriter* Writer) const {
245             bool result = true;
246             typename std::list<T>::const_iterator l_i = this->begin();
247
248             for ( ; l_i != this->end() && result; l_i++ )
249               result = (*l_i).Archive(Writer);
250
251             return result;
252           }
253
254           //
255           void Dump(FILE* stream = 0, ui32_t depth = 0)
256             {
257               (void) depth;
258               char identbuf[IdentBufferLen];
259
260               if ( stream == 0 )
261                 stream = stderr;
262
263               typename std::list<T>::iterator i = this->begin();
264               for ( ; i != this->end(); i++ )
265                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
266             }
267         };
268
269       //
270     class ISO8String : public std::string, public Kumu::IArchive
271         {
272         public:
273           ISO8String() {}
274           ISO8String(const char*);
275           ISO8String(const std::string&);
276           ~ISO8String() {}
277
278           const ISO8String& operator=(const char*);
279           const ISO8String& operator=(const std::string&);
280
281           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
282           inline virtual bool HasValue() const { return ! empty(); }
283           inline virtual ui32_t ArchiveLength() const { return (ui32_t)(sizeof(ui32_t) + size()); }
284           virtual bool Unarchive(Kumu::MemIOReader* Reader);
285           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
286         };
287
288       //
289     class UTF16String : public std::string, public Kumu::IArchive
290         {
291         public:
292           UTF16String() {}
293           UTF16String(const char*);
294           UTF16String(const std::string&);
295           ~UTF16String() {}
296
297           const UTF16String& operator=(const char*);
298           const UTF16String& operator=(const std::string&);
299
300           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
301           inline virtual bool HasValue() const { return ! empty(); }
302           inline virtual ui32_t ArchiveLength() const { return (ui32_t)(sizeof(ui32_t) + size()); }
303           virtual bool Unarchive(Kumu::MemIOReader* Reader);
304           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
305         };
306
307       //
308       class Rational : public ASDCP::Rational, public Kumu::IArchive
309         {
310         public:
311           Rational() {}
312           ~Rational() {}
313
314           Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
315             Numerator = rhs.Numerator;
316             Denominator = rhs.Denominator;
317           }
318
319           const Rational& operator=(const Rational& rhs) {
320             Numerator = rhs.Numerator;
321             Denominator = rhs.Denominator;
322             return *this;
323           }
324
325           Rational(const ASDCP::Rational& rhs) {
326             Numerator = rhs.Numerator;
327             Denominator = rhs.Denominator;
328           }
329
330           const Rational& operator=(const ASDCP::Rational& rhs) {
331             Numerator = rhs.Numerator;
332             Denominator = rhs.Denominator;
333             return *this;
334           }
335
336           //
337           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
338             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
339             return str_buf;
340           }
341
342           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
343             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
344             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
345             return true;
346           }
347
348           inline virtual bool HasValue() const { return true; }
349           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
350
351           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
352             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
353             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
354             return true;
355           }
356         };
357
358       //
359       class LineMapPair : public Kumu::IArchive
360         {
361         public:
362           ui32_t First;
363           ui32_t Second;
364
365         LineMapPair() : First(0), Second() {}
366           ~LineMapPair() {}
367
368         LineMapPair(const ui32_t& first, const ui32_t& second) : IArchive() {
369             First = first;
370             Second = second;
371           }
372
373           LineMapPair(const LineMapPair& rhs) : IArchive() {
374             First = rhs.First;
375             Second = rhs.Second;
376           }
377
378           const LineMapPair& operator=(const LineMapPair& rhs) {
379             First = rhs.First;
380             Second = rhs.Second;
381             return *this;
382           }
383
384           //
385           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
386             snprintf(str_buf, buf_len, "%d,%d", First, Second);
387             return str_buf;
388           }
389
390           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
391             ui32_t n;
392             if ( ! Reader->ReadUi32BE(&n) ) return false;
393             if ( n != 2 ) return false;
394             if ( ! Reader->ReadUi32BE(&n) ) return false;
395             if ( n != 4 ) return false;
396             if ( ! Reader->ReadUi32BE((ui32_t*)&First) ) return false;
397             if ( ! Reader->ReadUi32BE((ui32_t*)&Second) ) return false;
398             return true;
399           }
400
401           inline virtual bool HasValue() const { return true; }
402           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*4; }
403
404           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
405             if ( ! Writer->WriteUi32BE(2UL) ) return false;
406             if ( ! Writer->WriteUi32BE(4UL) ) return false;
407             if ( ! Writer->WriteUi32BE((ui32_t)First) ) return false;
408             if ( ! Writer->WriteUi32BE((ui32_t)Second) ) return false;
409             return true;
410           }
411         };
412
413       //
414       class ColorPrimary : public Kumu::IArchive
415         {
416         public:
417           ui16_t X;
418           ui16_t Y;
419
420         ColorPrimary() : X(0), Y(0) {}
421           ~ColorPrimary() {}
422
423           ColorPrimary(const ui16_t& x, const ui16_t& y) : X(x), Y(y) {}
424
425           ColorPrimary(const ColorPrimary& rhs) { Copy(rhs); }
426           const ColorPrimary& operator=(const ColorPrimary& rhs) { Copy(rhs); return *this; }
427           
428           void Copy(const ColorPrimary& rhs) {
429             X = rhs.X;
430             Y = rhs.Y;
431           }
432
433           //
434           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
435             snprintf(str_buf, buf_len, "%d,%d", X, Y);
436             return str_buf;
437           }
438
439           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
440             if ( ! Reader->ReadUi16BE((ui16_t*)&X) ) return false;
441             if ( ! Reader->ReadUi16BE((ui16_t*)&Y) ) return false;
442             return true;
443           }
444
445           inline virtual bool HasValue() const { return X || Y; }
446           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*2; }
447
448           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
449             if ( ! Writer->WriteUi16BE((ui16_t)X) ) return false;
450             if ( ! Writer->WriteUi16BE((ui16_t)Y) ) return false;
451             return true;
452           }
453         };
454
455       //
456       class ThreeColorPrimaries : public Kumu::IArchive
457         {
458         public:
459           ColorPrimary First;
460           ColorPrimary Second;
461           ColorPrimary Third;
462
463           ThreeColorPrimaries() {}
464           ~ThreeColorPrimaries() {}
465
466           ThreeColorPrimaries(const ColorPrimary& first, const ColorPrimary& second, const ColorPrimary& third) :
467             First(first), Second(second), Third(third) {}
468
469           ThreeColorPrimaries(const ThreeColorPrimaries& rhs) { Copy(rhs); }
470           const ThreeColorPrimaries& operator=(const ThreeColorPrimaries& rhs) { Copy(rhs); return *this; }
471           
472           void Copy(const ThreeColorPrimaries& rhs) {
473             First = rhs.First;
474             Second = rhs.Second;
475             Third = rhs.Third;
476           }
477
478           //
479           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
480             snprintf(str_buf, buf_len, "%d,%d;%d,%d;%d,%d", First.X, First.Y, Second.X, Second.Y, Third.X, Third.Y);
481             return str_buf;
482           }
483
484           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
485             First.Unarchive(Reader);
486             Second.Unarchive(Reader);
487             Third.Unarchive(Reader);
488             return true;
489           }
490
491           inline virtual bool HasValue() const {
492             return First.HasValue() || Second.HasValue() || Third.HasValue();
493           }
494
495           inline virtual ui32_t ArchiveLength() const {
496             return First.ArchiveLength()
497               + Second.ArchiveLength()
498               + Third.ArchiveLength();
499           }
500
501           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
502             First.Archive(Writer);
503             Second.Archive(Writer);
504             Third.Archive(Writer);
505             return true;
506           }
507         };
508
509       //
510       class VersionType : public Kumu::IArchive
511         {
512         public:
513           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
514           ui16_t Major;
515           ui16_t Minor;
516           ui16_t Patch;
517           ui16_t Build;
518           Release_t Release;
519
520           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
521           VersionType(const VersionType& rhs) { Copy(rhs); }
522           virtual ~VersionType() {}
523
524           const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
525           void Copy(const VersionType& rhs) {
526             Major = rhs.Major;
527             Minor = rhs.Minor;
528             Patch = rhs.Patch;
529             Build = rhs.Build;
530             Release = rhs.Release;
531           }
532
533           void Dump(FILE* = 0);
534
535           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
536             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
537             return str_buf;
538           }
539
540           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
541             if ( ! Reader->ReadUi16BE(&Major) ) return false;
542             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
543             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
544             if ( ! Reader->ReadUi16BE(&Build) ) return false;
545             ui16_t tmp_release;
546             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
547             Release = (Release_t)tmp_release;
548             return true;
549           }
550
551           inline virtual bool HasValue() const { return true; }
552           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
553
554           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
555             if ( ! Writer->WriteUi16BE(Major) ) return false;
556             if ( ! Writer->WriteUi16BE(Minor) ) return false;
557             if ( ! Writer->WriteUi16BE(Patch) ) return false;
558             if ( ! Writer->WriteUi16BE(Build) ) return false;
559             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
560             return true;
561           }
562         };
563
564       /*
565         The RGBALayout type shall be a fixed-size 8 element sequence with a total length
566         of 16 bytes, where each element shall consist of the RGBAComponent type with the
567         following fields:
568
569         Code (UInt8): Enumerated value specifying component (i.e., component identifier).
570         "0" is the layout terminator.
571
572         Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26) 
573           1->32 indicates integer depth
574           253 = HALF (floating point 16-bit value)
575           254 = IEEE floating point 32-bit value
576           255 = IEEE floating point 64-bit value
577           0 = RGBALayout terminator
578
579         A Fill component indicates unused bits. After the components have been specified,
580         the remaining Code and Size fields shall be set to zero (0).
581
582         For each component in the Pixel, one of the following Codes or the terminator
583         shall be specified (explained below):
584
585         Code    ASCII
586
587       */
588       struct RGBALayoutTableEntry
589       {
590         byte_t code;
591         char symbol;
592         const char* label;
593       };
594
595       struct RGBALayoutTableEntry const RGBALayoutTable[] = {
596         { 0x52, 'R', "Red component" },
597         { 0x47, 'G', "Green component" },
598         { 0x42, 'B', "Blue component" },
599         { 0x41, 'A', "Alpha component" },
600         { 0x72, 'r', "Red component (LSBs)" },
601         { 0x67, 'g', "Green component (LSBs)" },
602         { 0x62, 'b', "Blue component (LSBs)" },
603         { 0x61, 'a', "Alpha component (LSBs)" },
604         { 0x46, 'F', "Fill component" },
605         { 0x50, 'P', "Palette code" },
606         { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
607         { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
608         { 0x57, 'W', "Composite Video" },
609         { 0x58, 'X', "Non co-sited luma component" },
610         { 0x59, 'Y', "Luma component" },
611         { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
612         { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
613         { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
614         { 0x77, 'w', "Composite Video (LSBs)" },
615         { 0x78, 'x', "Non co-sited luma component (LSBs)" },
616         { 0x79, 'y', "Luma component (LSBs)" },
617         { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
618         { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
619         { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
620         { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
621         { 0x00, '_', "Terminator" }
622       };
623
624
625       size_t const RGBAValueLength = 16;
626
627       byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
628       byte_t const RGBAValue_RGB_8[RGBAValueLength]  = { 'R', 8,  'G', 8,  'B', 8,  0, 0 };
629       byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
630       byte_t const RGBAValue_YUV_8[RGBAValueLength]  = { 'Y', 8,  'U', 8,  'V', 8,  0, 0 };
631       byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
632
633
634       class RGBALayout : public Kumu::IArchive
635         {
636           byte_t m_value[RGBAValueLength];
637
638         public:
639           RGBALayout();
640           RGBALayout(const byte_t* value);
641           ~RGBALayout();
642
643           RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
644           const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
645           
646           void Set(const byte_t* value) {
647             memcpy(m_value, value, RGBAValueLength);
648           }
649
650           const char* EncodeString(char* buf, ui32_t buf_len) const;
651
652           bool HasValue() const { return true; }
653           ui32_t ArchiveLength() const { return RGBAValueLength; }
654
655           bool Archive(Kumu::MemIOWriter* Writer) const {
656             return Writer->WriteRaw(m_value, RGBAValueLength);
657           }
658
659           bool Unarchive(Kumu::MemIOReader* Reader) {
660             if ( Reader->Remainder() < RGBAValueLength )
661               {
662                 return false;
663               }
664
665             memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
666             Reader->SkipOffset(RGBAValueLength);
667             return true;
668           }
669         };
670
671
672       //
673       class Raw : public Kumu::ByteString
674         {
675         public:
676           Raw();
677           virtual ~Raw();
678
679           //
680           virtual bool Unarchive(Kumu::MemIOReader* Reader);
681           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
682           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
683         };
684
685       //
686       class J2KExtendedCapabilitiesType : public Kumu::IArchive
687         {
688         public:
689           ui32_t Pcap;
690           Array<Kumu::ArchivableUi16> Ccap;
691         
692           bool HasValue() const { return true; }
693           ui32_t ArchiveLength() const { return 0; }
694
695           bool Archive(Kumu::MemIOWriter* Writer) const;
696           bool Unarchive(Kumu::MemIOReader* Reader);
697           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
698       };
699
700     } // namespace MXF
701 } // namespace ASDCP
702
703
704 #endif //_MXFTYPES_H_
705
706 //
707 // end MXFTypes.h
708 //