a39c96711f7bf4fb2fbae5a565cf1543e1d68c0d
[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             char identbuf[IdentBufferLen];
162
163             if ( stream == 0 )
164               {
165                 stream = stderr;
166               }
167             
168             typename ContainerType::const_iterator i;
169             for ( i = this->begin(); i != this->end(); ++i )
170               {
171                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
172               }
173           }
174         };
175
176
177       template <class item_type>
178         class PushSet : public std::set<item_type>
179       {
180       public:
181         PushSet() {}
182         virtual ~PushSet() {}
183         void push_back(const item_type& item) { this->insert(item); }
184       };
185
186       template <class ItemType>
187         class Batch : public FixedSizeItemCollection<PushSet<ItemType> >
188       {
189       public:
190         Batch() {}
191         virtual ~Batch() {}
192       };
193
194       template <class ItemType>
195         class Array : public FixedSizeItemCollection<std::vector<ItemType> >
196       {
197       public:
198         Array() {}
199         virtual ~Array() {}
200       };
201
202       //
203       template <class T>
204         class SimpleArray : public std::list<T>, public Kumu::IArchive
205         {
206         public:
207           SimpleArray() {}
208           virtual ~SimpleArray() {}
209
210           //
211           bool Unarchive(Kumu::MemIOReader* Reader)
212             {
213               bool result = true;
214
215               while ( Reader->Remainder() > 0 && result )
216                 {
217                   T Tmp;
218                   result = Tmp.Unarchive(Reader);
219
220                   if ( result )
221                     {
222                       this->push_back(Tmp);
223                     }
224                 }
225
226               return result;
227             }
228
229           inline bool HasValue() const { return ! this->empty(); }
230
231           ui32_t ArchiveLength() const {
232             ui32_t arch_size = 0;
233
234             typename std::list<T>::const_iterator l_i = this->begin();
235
236             for ( ; l_i != this->end(); l_i++ )
237               arch_size += l_i->ArchiveLength();
238             
239             return arch_size;
240           }
241
242           //
243           bool Archive(Kumu::MemIOWriter* Writer) const {
244             bool result = true;
245             typename std::list<T>::const_iterator l_i = this->begin();
246
247             for ( ; l_i != this->end() && result; l_i++ )
248               result = (*l_i).Archive(Writer);
249
250             return result;
251           }
252
253           //
254           void Dump(FILE* stream = 0, ui32_t depth = 0)
255             {
256               char identbuf[IdentBufferLen];
257
258               if ( stream == 0 )
259                 stream = stderr;
260
261               typename std::list<T>::iterator i = this->begin();
262               for ( ; i != this->end(); i++ )
263                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
264             }
265         };
266
267       //
268     class ISO8String : public std::string, public Kumu::IArchive
269         {
270         public:
271           ISO8String() {}
272           ISO8String(const char*);
273           ISO8String(const std::string&);
274           ~ISO8String() {}
275
276           const ISO8String& operator=(const char*);
277           const ISO8String& operator=(const std::string&);
278
279           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
280           inline virtual bool HasValue() const { return ! empty(); }
281           inline virtual ui32_t ArchiveLength() const { return (ui32_t)(sizeof(ui32_t) + size()); }
282           virtual bool Unarchive(Kumu::MemIOReader* Reader);
283           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
284         };
285
286       //
287     class UTF16String : public std::string, public Kumu::IArchive
288         {
289         public:
290           UTF16String() {}
291           UTF16String(const char*);
292           UTF16String(const std::string&);
293           ~UTF16String() {}
294
295           const UTF16String& operator=(const char*);
296           const UTF16String& operator=(const std::string&);
297
298           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
299           inline virtual bool HasValue() const { return ! empty(); }
300           inline virtual ui32_t ArchiveLength() const { return (ui32_t)(sizeof(ui32_t) + size()); }
301           virtual bool Unarchive(Kumu::MemIOReader* Reader);
302           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
303         };
304
305       //
306       class Rational : public ASDCP::Rational, public Kumu::IArchive
307         {
308         public:
309           Rational() {}
310           ~Rational() {}
311
312           Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
313             Numerator = rhs.Numerator;
314             Denominator = rhs.Denominator;
315           }
316
317           const Rational& operator=(const Rational& rhs) {
318             Numerator = rhs.Numerator;
319             Denominator = rhs.Denominator;
320             return *this;
321           }
322
323           Rational(const ASDCP::Rational& rhs) {
324             Numerator = rhs.Numerator;
325             Denominator = rhs.Denominator;
326           }
327
328           const Rational& operator=(const ASDCP::Rational& rhs) {
329             Numerator = rhs.Numerator;
330             Denominator = rhs.Denominator;
331             return *this;
332           }
333
334           //
335           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
336             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
337             return str_buf;
338           }
339
340           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
341             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
342             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
343             return true;
344           }
345
346           inline virtual bool HasValue() const { return true; }
347           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
348
349           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
350             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
351             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
352             return true;
353           }
354         };
355
356       //
357       class LineMapPair : public Kumu::IArchive
358         {
359         public:
360           ui32_t First;
361           ui32_t Second;
362
363         LineMapPair() : First(0), Second() {}
364           ~LineMapPair() {}
365
366         LineMapPair(const ui32_t& first, const ui32_t& second) : IArchive() {
367             First = first;
368             Second = second;
369           }
370
371           LineMapPair(const LineMapPair& rhs) : IArchive() {
372             First = rhs.First;
373             Second = rhs.Second;
374           }
375
376           const LineMapPair& operator=(const LineMapPair& rhs) {
377             First = rhs.First;
378             Second = rhs.Second;
379             return *this;
380           }
381
382           //
383           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
384             snprintf(str_buf, buf_len, "%d,%d", First, Second);
385             return str_buf;
386           }
387
388           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
389             ui32_t n;
390             if ( ! Reader->ReadUi32BE(&n) ) return false;
391             if ( n != 2 ) return false;
392             if ( ! Reader->ReadUi32BE(&n) ) return false;
393             if ( n != 4 ) return false;
394             if ( ! Reader->ReadUi32BE((ui32_t*)&First) ) return false;
395             if ( ! Reader->ReadUi32BE((ui32_t*)&Second) ) return false;
396             return true;
397           }
398
399           inline virtual bool HasValue() const { return true; }
400           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*4; }
401
402           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
403             if ( ! Writer->WriteUi32BE(2UL) ) return false;
404             if ( ! Writer->WriteUi32BE(4UL) ) return false;
405             if ( ! Writer->WriteUi32BE((ui32_t)First) ) return false;
406             if ( ! Writer->WriteUi32BE((ui32_t)Second) ) return false;
407             return true;
408           }
409         };
410
411       //
412       class ColorPrimary : public Kumu::IArchive
413         {
414         public:
415           ui16_t X;
416           ui16_t Y;
417
418         ColorPrimary() : X(0), Y(0) {}
419           ~ColorPrimary() {}
420
421           ColorPrimary(const ui16_t& x, const ui16_t& y) : X(x), Y(y) {}
422
423           ColorPrimary(const ColorPrimary& rhs) { Copy(rhs); }
424           const ColorPrimary& operator=(const ColorPrimary& rhs) { Copy(rhs); return *this; }
425           
426           void Copy(const ColorPrimary& rhs) {
427             X = rhs.X;
428             Y = rhs.Y;
429           }
430
431           //
432           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
433             snprintf(str_buf, buf_len, "%d,%d", X, Y);
434             return str_buf;
435           }
436
437           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
438             if ( ! Reader->ReadUi16BE((ui16_t*)&X) ) return false;
439             if ( ! Reader->ReadUi16BE((ui16_t*)&Y) ) return false;
440             return true;
441           }
442
443           inline virtual bool HasValue() const { return X || Y; }
444           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*2; }
445
446           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
447             if ( ! Writer->WriteUi16BE((ui16_t)X) ) return false;
448             if ( ! Writer->WriteUi16BE((ui16_t)Y) ) return false;
449             return true;
450           }
451         };
452
453       //
454       class ThreeColorPrimaries : public Kumu::IArchive
455         {
456         public:
457           ColorPrimary First;
458           ColorPrimary Second;
459           ColorPrimary Third;
460
461           ThreeColorPrimaries() {}
462           ~ThreeColorPrimaries() {}
463
464           ThreeColorPrimaries(const ColorPrimary& first, const ColorPrimary& second, const ColorPrimary& third) :
465             First(first), Second(second), Third(third) {}
466
467           ThreeColorPrimaries(const ThreeColorPrimaries& rhs) { Copy(rhs); }
468           const ThreeColorPrimaries& operator=(const ThreeColorPrimaries& rhs) { Copy(rhs); return *this; }
469           
470           void Copy(const ThreeColorPrimaries& rhs) {
471             First = rhs.First;
472             Second = rhs.Second;
473             Third = rhs.Third;
474           }
475
476           //
477           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
478             snprintf(str_buf, buf_len, "%d,%d;%d,%d;%d,%d", First.X, First.Y, Second.X, Second.Y, Third.X, Third.Y);
479             return str_buf;
480           }
481
482           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
483             First.Unarchive(Reader);
484             Second.Unarchive(Reader);
485             Third.Unarchive(Reader);
486             return true;
487           }
488
489           inline virtual bool HasValue() const {
490             return First.HasValue() || Second.HasValue() || Third.HasValue();
491           }
492
493           inline virtual ui32_t ArchiveLength() const {
494             return First.ArchiveLength()
495               + Second.ArchiveLength()
496               + Third.ArchiveLength();
497           }
498
499           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
500             First.Archive(Writer);
501             Second.Archive(Writer);
502             Third.Archive(Writer);
503             return true;
504           }
505         };
506
507       //
508       class VersionType : public Kumu::IArchive
509         {
510         public:
511           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
512           ui16_t Major;
513           ui16_t Minor;
514           ui16_t Patch;
515           ui16_t Build;
516           Release_t Release;
517
518           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
519           VersionType(const VersionType& rhs) { Copy(rhs); }
520           virtual ~VersionType() {}
521
522           const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
523           void Copy(const VersionType& rhs) {
524             Major = rhs.Major;
525             Minor = rhs.Minor;
526             Patch = rhs.Patch;
527             Build = rhs.Build;
528             Release = rhs.Release;
529           }
530
531           void Dump(FILE* = 0);
532
533           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
534             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, ui16_t(Release));
535             return str_buf;
536           }
537
538           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
539             if ( ! Reader->ReadUi16BE(&Major) ) return false;
540             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
541             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
542             if ( ! Reader->ReadUi16BE(&Build) ) return false;
543             ui16_t tmp_release;
544             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
545             Release = (Release_t)tmp_release;
546             return true;
547           }
548
549           inline virtual bool HasValue() const { return true; }
550           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
551
552           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
553             if ( ! Writer->WriteUi16BE(Major) ) return false;
554             if ( ! Writer->WriteUi16BE(Minor) ) return false;
555             if ( ! Writer->WriteUi16BE(Patch) ) return false;
556             if ( ! Writer->WriteUi16BE(Build) ) return false;
557             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
558             return true;
559           }
560         };
561
562       /*
563         The RGBALayout type shall be a fixed-size 8 element sequence with a total length
564         of 16 bytes, where each element shall consist of the RGBAComponent type with the
565         following fields:
566
567         Code (UInt8): Enumerated value specifying component (i.e., component identifier).
568         "0" is the layout terminator.
569
570         Depth (UInt8): Integer specifying the number of bits occupied (see also G.2.26) 
571           1->32 indicates integer depth
572           253 = HALF (floating point 16-bit value)
573           254 = IEEE floating point 32-bit value
574           255 = IEEE floating point 64-bit value
575           0 = RGBALayout terminator
576
577         A Fill component indicates unused bits. After the components have been specified,
578         the remaining Code and Size fields shall be set to zero (0).
579
580         For each component in the Pixel, one of the following Codes or the terminator
581         shall be specified (explained below):
582
583         Code    ASCII
584
585       */
586       struct RGBALayoutTableEntry
587       {
588         byte_t code;
589         char symbol;
590         const char* label;
591       };
592
593       struct RGBALayoutTableEntry const RGBALayoutTable[] = {
594         { 0x52, 'R', "Red component" },
595         { 0x47, 'G', "Green component" },
596         { 0x42, 'B', "Blue component" },
597         { 0x41, 'A', "Alpha component" },
598         { 0x72, 'r', "Red component (LSBs)" },
599         { 0x67, 'g', "Green component (LSBs)" },
600         { 0x62, 'b', "Blue component (LSBs)" },
601         { 0x61, 'a', "Alpha component (LSBs)" },
602         { 0x46, 'F', "Fill component" },
603         { 0x50, 'P', "Palette code" },
604         { 0x55, 'U', "Color Difference Sample (e.g. U, Cb, I etc.)" },
605         { 0x56, 'V', "Color Difference Sample (e.g. V, Cr, Q etc.)" },
606         { 0x57, 'W', "Composite Video" },
607         { 0x58, 'X', "Non co-sited luma component" },
608         { 0x59, 'Y', "Luma component" },
609         { 0x5a, 'Z', "Depth component (SMPTE ST 268 compatible)" },
610         { 0x75, 'u', "Color Difference Sample (e.g. U, Cb, I etc.) (LSBs)" },
611         { 0x76, 'v', "Color Difference Sample (e.g. V, Cr, Q etc.) (LSBs)" },
612         { 0x77, 'w', "Composite Video (LSBs)" },
613         { 0x78, 'x', "Non co-sited luma component (LSBs)" },
614         { 0x79, 'y', "Luma component (LSBs)" },
615         { 0x7a, 'z', "Depth component (LSBs) (SMPTE ST 268 compatible)" },
616         { 0xd8, 'X', "The DCDM X color component (see SMPTE ST 428-1 X')" },
617         { 0xd9, 'Y', "The DCDM Y color component (see SMPTE ST 428-1 Y')" },
618         { 0xda, 'Z', "The DCDM Z color component (see SMPTE ST 428-1 Z')" },
619         { 0x00, '_', "Terminator" }
620       };
621
622
623       size_t const RGBAValueLength = 16;
624
625       byte_t const RGBAValue_RGB_10[RGBAValueLength] = { 'R', 10, 'G', 10, 'B', 10, 0, 0 };
626       byte_t const RGBAValue_RGB_8[RGBAValueLength]  = { 'R', 8,  'G', 8,  'B', 8,  0, 0 };
627       byte_t const RGBAValue_YUV_10[RGBAValueLength] = { 'Y', 10, 'U', 10, 'V', 10, 0, 0 };
628       byte_t const RGBAValue_YUV_8[RGBAValueLength]  = { 'Y', 8,  'U', 8,  'V', 8,  0, 0 };
629       byte_t const RGBAValue_DCDM[RGBAValueLength] = { 0xd8, 10, 0xd9, 10, 0xda, 10, 0, 0 };
630
631
632       class RGBALayout : public Kumu::IArchive
633         {
634           byte_t m_value[RGBAValueLength];
635
636         public:
637           RGBALayout();
638           RGBALayout(const byte_t* value);
639           ~RGBALayout();
640
641           RGBALayout(const RGBALayout& rhs) { Set(rhs.m_value); }
642           const RGBALayout& operator=(const RGBALayout& rhs) { Set(rhs.m_value); return *this; }
643           
644           void Set(const byte_t* value) {
645             memcpy(m_value, value, RGBAValueLength);
646           }
647
648           const char* EncodeString(char* buf, ui32_t buf_len) const;
649
650           bool HasValue() const { return true; }
651           ui32_t ArchiveLength() const { return RGBAValueLength; }
652
653           bool Archive(Kumu::MemIOWriter* Writer) const {
654             return Writer->WriteRaw(m_value, RGBAValueLength);
655           }
656
657           bool Unarchive(Kumu::MemIOReader* Reader) {
658             if ( Reader->Remainder() < RGBAValueLength )
659               {
660                 return false;
661               }
662
663             memcpy(m_value, Reader->CurrentData(), RGBAValueLength);
664             Reader->SkipOffset(RGBAValueLength);
665             return true;
666           }
667         };
668
669
670       //
671       class Raw : public Kumu::ByteString
672         {
673         public:
674           Raw();
675           Raw(const Raw& rhs) { Copy(rhs); }
676           virtual ~Raw();
677
678           const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
679           void Copy(const Raw& rhs) {
680             if ( KM_SUCCESS(Capacity(rhs.Length())) )
681               {
682                 Set(rhs);
683               }
684           }
685
686           //
687           virtual bool Unarchive(Kumu::MemIOReader* Reader);
688           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
689           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
690         };
691
692       //
693       class J2KExtendedCapabilities : public Kumu::IArchive
694         {
695         public:
696           ui32_t Pcap;
697           ui16_t Ccapi[JP2K::MaxCapabilities];
698         
699           bool HasValue() const { return true; }
700           ui32_t ArchiveLength() const { return 0; }
701
702           bool Archive(Kumu::MemIOWriter* Writer) const;
703           bool Unarchive(Kumu::MemIOReader* Reader);
704           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
705       };
706
707     } // namespace MXF
708 } // namespace ASDCP
709
710
711 #endif //_MXFTYPES_H_
712
713 //
714 // end MXFTypes.h
715 //