included CMakelists.txt into dist
[asdcplib.git] / src / AS_DCP.h
1 /*
2 Copyright (c) 2003-2014, 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    AS_DCP.h
28     \version $Id$
29     \brief   AS-DCP library, public interface
30
31 The asdcplib library is a set of file access objects that offer simplified
32 access to files conforming to the standards published by the SMPTE
33 D-Cinema Technology Committee 21DC. The file format, labeled AS-DCP,
34 is described in a series of documents which includes but may not
35 be be limited to:
36
37  o SMPTE ST 429-2:2011 DCP Operational Constraints
38  o SMPTE ST 429-3:2006 Sound and Picture Track File
39  o SMPTE ST 429-4:2006 MXF JPEG 2000 Application
40  o SMPTE ST 429-5:2009 Timed Text Track File
41  o SMPTE ST 429-6:2006 MXF Track File Essence Encryption
42  o SMPTE ST 429-10:2008 Stereoscopic Picture Track File
43  o SMPTE ST 429-14:2008 Aux Data Track File
44  o SMPTE ST 330:2004 - UMID
45  o SMPTE ST 336:2001 - KLV
46  o SMPTE ST 377:2004 - MXF (old version, required)
47  o SMPTE ST 377-1:2011 - MXF
48  o SMPTE ST 377-4:2012 - MXF Multichannel Audio Labeling Framework
49  o SMPTE ST 390:2011 - MXF OP-Atom
50  o SMPTE ST 379-1:2009 - MXF Generic Container (GC)
51  o SMPTE ST 381-1:2005 - MPEG2 picture in GC
52  o SMPTE ST 422:2006 - JPEG 2000 picture in GC
53  o SMPTE ST 382:2007 - WAV/PCM sound in GC
54  o IETF RFC 2104 - HMAC/SHA1
55  o NIST FIPS 197 - AES (Rijndael) (via OpenSSL)
56
57  o MXF Interop Track File Specification
58  o MXF Interop Track File Essence Encryption Specification
59  o MXF Interop Operational Constraints Specification
60  - Note: the MXF Interop documents are not formally published.
61    Contact the asdcplib support address to get copies.
62
63 The following use cases are supported by the library:
64
65  o Write essence to a plaintext or ciphertext AS-DCP file:
66  o Read essence from a plaintext or ciphertext AS-DCP file:
67      MPEG2 Video Elementary Stream
68      JPEG 2000 codestreams
69      JPEG 2000 stereoscopic codestream pairs
70      PCM audio streams
71      SMPTE 429-7 Timed Text XML with font and image resources
72      Aux Data (frame-wrapped synchronous blob)
73      Proposed Dolby (TM) Atmos track file
74
75  o Read header metadata from an AS-DCP file
76
77 This project depends upon the following libraries:
78  - OpenSSL http://www.openssl.org/
79  - Expat http://expat.sourceforge.net/  or
80      Xerces-C http://xerces.apache.org/xerces-c/
81    An XML library is not needed if you don't need support for SMPTE ST 429-5:2009.
82 */
83
84 #ifndef _AS_DCP_H_
85 #define _AS_DCP_H_
86
87 #include <KM_error.h>
88 #include <KM_fileio.h>
89 #include <stdio.h>
90 #include <stdarg.h>
91 #include <math.h>
92 #include <iosfwd>
93 #include <string>
94 #include <cstring>
95 #include <list>
96
97 //--------------------------------------------------------------------------------
98 // common integer types
99 // supply your own by defining ASDCP_NO_BASE_TYPES
100
101 #ifndef ASDCP_NO_BASE_TYPES
102 typedef unsigned char  byte_t;
103 typedef char           i8_t;
104 typedef unsigned char  ui8_t;
105 typedef short          i16_t;
106 typedef unsigned short ui16_t;
107 typedef int            i32_t;
108 typedef unsigned int   ui32_t;
109 #endif
110
111
112 //--------------------------------------------------------------------------------
113 // convenience macros
114
115 // Convenience macros for managing return values in predicates
116 #define ASDCP_SUCCESS(v) (((v) < 0) ? 0 : 1)
117 #define ASDCP_FAILURE(v) (((v) < 0) ? 1 : 0)
118
119
120 // Returns RESULT_PTR if the given argument is NULL.
121 // See Result_t below for an explanation of RESULT_* symbols.
122 #define ASDCP_TEST_NULL(p) \
123   if ( (p) == 0  ) { \
124     return ASDCP::RESULT_PTR; \
125   }
126
127 // Returns RESULT_PTR if the given argument is NULL. See Result_t
128 // below for an explanation of RESULT_* symbols. It then assumes
129 // that the argument is a pointer to a string and returns
130 // RESULT_NULL_STR if the first character is '\0'.
131 //
132 #define ASDCP_TEST_NULL_STR(p) \
133   ASDCP_TEST_NULL(p); \
134   if ( (p)[0] == '\0' ) { \
135     return ASDCP::RESULT_NULL_STR; \
136   }
137
138 // Produces copy constructor boilerplate. Allows convenient private
139 // declatarion of copy constructors to prevent the compiler from
140 // silently manufacturing default methods.
141 #define ASDCP_NO_COPY_CONSTRUCT(T)   \
142           T(const T&); \
143           T& operator=(const T&)
144
145 //--------------------------------------------------------------------------------
146 // All library components are defined in the namespace ASDCP
147 //
148 namespace ASDCP {
149   //
150   // The version number declaration and explanation have moved to ../configure.ac
151   const char* Version();
152
153   // UUIDs are passed around as strings of UUIDlen bytes
154   const ui32_t UUIDlen = 16;
155
156   // Encryption keys are passed around as strings of KeyLen bytes
157   const ui32_t KeyLen = 16;
158
159   //---------------------------------------------------------------------------------
160   // return values
161
162   using Kumu::Result_t;
163
164   using Kumu::RESULT_FALSE;
165   using Kumu::RESULT_OK;
166   using Kumu::RESULT_FAIL;
167   using Kumu::RESULT_PTR;
168   using Kumu::RESULT_NULL_STR;
169   using Kumu::RESULT_ALLOC;
170   using Kumu::RESULT_PARAM;
171   using Kumu::RESULT_SMALLBUF;
172   using Kumu::RESULT_INIT;
173   using Kumu::RESULT_NOT_FOUND;
174   using Kumu::RESULT_NO_PERM;
175   using Kumu::RESULT_FILEOPEN;
176   using Kumu::RESULT_BADSEEK;
177   using Kumu::RESULT_READFAIL;
178   using Kumu::RESULT_WRITEFAIL;
179   using Kumu::RESULT_STATE;
180   using Kumu::RESULT_ENDOFFILE;
181   using Kumu::RESULT_CONFIG;
182
183   KM_DECLARE_RESULT(FORMAT,     -101, "The file format is not proper OP-Atom/AS-DCP.");
184   KM_DECLARE_RESULT(RAW_ESS,    -102, "Unknown raw essence file type.");
185   KM_DECLARE_RESULT(RAW_FORMAT, -103, "Raw essence format invalid.");
186   KM_DECLARE_RESULT(RANGE,      -104, "Frame number out of range.");
187   KM_DECLARE_RESULT(CRYPT_CTX,  -105, "AESEncContext required when writing to encrypted file.");
188   KM_DECLARE_RESULT(LARGE_PTO,  -106, "Plaintext offset exceeds frame buffer size.");
189   KM_DECLARE_RESULT(CAPEXTMEM,  -107, "Cannot resize externally allocated memory.");
190   KM_DECLARE_RESULT(CHECKFAIL,  -108, "The check value did not decrypt correctly.");
191   KM_DECLARE_RESULT(HMACFAIL,   -109, "HMAC authentication failure.");
192   KM_DECLARE_RESULT(HMAC_CTX,   -110, "HMAC context required.");
193   KM_DECLARE_RESULT(CRYPT_INIT, -111, "Error initializing block cipher context.");
194   KM_DECLARE_RESULT(EMPTY_FB,   -112, "Empty frame buffer.");
195   KM_DECLARE_RESULT(KLV_CODING, -113, "KLV coding error.");
196   KM_DECLARE_RESULT(SPHASE,     -114, "Stereoscopic phase mismatch.");
197   KM_DECLARE_RESULT(SFORMAT,    -115, "Rate mismatch, file may contain stereoscopic essence.");
198
199   //---------------------------------------------------------------------------------
200   // file identification
201
202   // The file accessors in this library implement a bounded set of essence types.
203   // This list will be expanded when support for new types is added to the library.
204   enum EssenceType_t {
205     ESS_UNKNOWN,              // the file is not a supported AS-DCP of AS-02 essence container
206
207     // 
208     ESS_MPEG2_VES,            // the file contains an MPEG-2 video elementary stream
209
210     // d-cinema essence types
211     ESS_JPEG_2000,            // the file contains one or more JPEG 2000 codestreams
212     ESS_PCM_24b_48k,          // the file contains one or more PCM audio pairs
213     ESS_PCM_24b_96k,          // the file contains one or more PCM audio pairs
214     ESS_TIMED_TEXT,           // the file contains an XML timed text document and one or more resources
215     ESS_JPEG_2000_S,          // the file contains one or more JPEG 2000 codestream pairs (stereoscopic)
216     ESS_DCDATA_UNKNOWN,       // the file contains one or more D-Cinema Data bytestreams
217     ESS_DCDATA_DOLBY_ATMOS,   // the file contains one or more DolbyATMOS bytestreams
218
219     // IMF essence types
220     ESS_AS02_JPEG_2000,       // the file contains one or more JPEG 2000 codestreams
221     ESS_AS02_PCM_24b_48k,     // the file contains one or more PCM audio pairs, clip wrapped
222     ESS_AS02_PCM_24b_96k,     // the file contains one or more PCM audio pairs, clip wrapped
223     ESS_AS02_TIMED_TEXT,      // the file contains a TTML document and zero or more resources
224
225     ESS_ACES,                 // the file contains one ACES codestream
226     ESS_MAX
227   };
228
229   // Determine the type of essence contained in the given MXF file. RESULT_OK
230   // is returned if the file is successfully opened and contains a valid MXF
231   // stream. If there is an error, the result code will indicate the reason.
232   Result_t EssenceType(const std::string& filename, EssenceType_t& type);
233
234   // Determine the type of essence contained in the given raw file. RESULT_OK
235   // is returned if the file is successfully opened and contains a known
236   // stream type. If there is an error, the result code will indicate the reason.
237   Result_t RawEssenceType(const std::string& filename, EssenceType_t& type);
238
239
240   //---------------------------------------------------------------------------------
241   // base types
242
243   // A simple container for rational numbers.
244   class Rational
245   {
246   public:
247     i32_t Numerator;
248     i32_t Denominator;
249
250     Rational() : Numerator(0), Denominator(0) {}
251     Rational(i32_t n, i32_t d) : Numerator(n), Denominator(d) {}
252
253     inline double Quotient() const {
254       return (double)Numerator / (double)Denominator;
255     }
256
257     inline bool operator==(const Rational& rhs) const {
258       return ( rhs.Numerator == Numerator && rhs.Denominator == Denominator );
259     }
260
261     inline bool operator!=(const Rational& rhs) const {
262       return ( rhs.Numerator != Numerator || rhs.Denominator != Denominator );
263     }
264
265     inline bool operator<(const Rational& rhs) {
266       if ( Numerator < rhs.Numerator )     return true;
267       if ( Numerator == rhs.Numerator && Denominator < rhs.Denominator )    return true;
268       return false;
269     }
270
271     inline bool operator>(const Rational& rhs) {
272       if ( Numerator > rhs.Numerator )     return true;
273       if ( Numerator == rhs.Numerator && Denominator > rhs.Denominator )     return true;
274       return false;
275     }
276   };
277
278   // Encodes a rational number as a string having a single delimiter character between
279   // numerator and denominator.  Retuns the buffer pointer to allow convenient in-line use.
280   const char* EncodeRational(const Rational&, char* str_buf, ui32_t buf_len, char delimiter = ' ');
281
282   // Decodes a rational number havng a single non-digit delimiter character between
283   // the numerator and denominator.  Returns false if the string does not contain
284   // the expected syntax.
285   bool DecodeRational(const char* str_rat, Rational&);
286
287
288   // common edit rates, use these instead of hard coded constants
289   const Rational EditRate_24 = Rational(24,1);
290   const Rational EditRate_23_98 = Rational(24000,1001); // Not a DCI-compliant value!
291   const Rational EditRate_48 = Rational(48,1);
292   const Rational SampleRate_48k = Rational(48000,1);
293   const Rational SampleRate_96k = Rational(96000,1);
294
295   // Additional frame rates, see ST 428-11, ST 429-13
296   // These rates are new and not supported by all systems. Do not assume that
297   // a package made using one of these rates will work just anywhere!
298   const Rational EditRate_25 = Rational(25,1);
299   const Rational EditRate_30 = Rational(30,1);
300   const Rational EditRate_50 = Rational(50,1);
301   const Rational EditRate_60 = Rational(60,1);
302   const Rational EditRate_96 = Rational(96,1);
303   const Rational EditRate_100 = Rational(100,1);
304   const Rational EditRate_120 = Rational(120,1);
305
306   // Archival frame rates, see ST 428-21
307   // These rates are new and not supported by all systems. Do not assume that
308   // a package made using one of these rates will work just anywhere!
309   const Rational EditRate_16 = Rational(16,1);
310   const Rational EditRate_18 = Rational(200,11); // 18.182
311   const Rational EditRate_20 = Rational(20,1);
312   const Rational EditRate_22 = Rational(240,11); // 21.818
313
314
315   // Non-reference counting container for internal member objects.
316   // Please do not use this class for any other purpose.
317   template <class T>
318     class mem_ptr
319     {
320       T* m_p; // the thing we point to
321       mem_ptr(T&);
322
323     public:
324       mem_ptr() : m_p(0) {}
325       mem_ptr(T* p) : m_p(p) {}
326       ~mem_ptr() { delete m_p; }
327
328       inline T&   operator*()  const { return *m_p; }
329       inline T*   operator->() const { return m_p; }
330       inline      operator T*()const { return m_p; }
331       inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
332       inline T*   set(T* p)          { delete m_p; m_p = p; return m_p; }
333       inline T*   get()        const { return m_p; }
334       inline void release()          { m_p = 0; }
335       inline bool empty()      const { return m_p == 0; }
336     };
337
338
339   //---------------------------------------------------------------------------------
340   // WriterInfo class - encapsulates writer identification details used for
341   // OpenWrite() calls.  Replace these values at runtime to identify your product.
342   //
343   // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
344   // in a file is determined by the MXF Operational Pattern and any constraining
345   // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
346   // (AKA JPEG Interop) and SMPTE. The two differ in the values of three labels:
347   //
348   //   OPAtom
349   //      Interop : 06 0e 2b 34 04 01 01 01  0d 01 02 01 10 00 00 00
350   //      SMPTE   : 06 0e 2b 34 04 01 01 02  0d 01 02 01 10 00 00 00
351   //
352   //   EKLV Packet:
353   //      Interop : 06 0e 2b 34 02 04 01 07  0d 01 03 01 02 7e 01 00
354   //      SMPTE   : 06 0e 2b 34 02 04 01 01  0d 01 03 01 02 7e 01 00
355   //
356   //   GenericDescriptor/SubDescriptors:
357   //      Interop : 06 0e 2b 34 01 01 01 02  06 01 01 04 06 10 00 00
358   //      SMPTE   : 06 0e 2b 34 01 01 01 09  06 01 01 04 06 10 00 00
359   //
360   // asdcplib will read any (otherwise valid) file which has any combination of the
361   // above values. When writing files, MXF Interop labels are used by default. To
362   // write a file containing SMPTE labels, replace the default label set value in
363   // the WriterInfo before calling OpenWrite()
364   //
365   //
366   enum LabelSet_t
367   {
368     LS_MXF_UNKNOWN,
369     LS_MXF_INTEROP,
370     LS_MXF_SMPTE,
371     LS_MAX
372   };
373
374   //
375   struct WriterInfo
376   {
377     byte_t      ProductUUID[UUIDlen];
378     byte_t      AssetUUID[UUIDlen];
379     byte_t      ContextID[UUIDlen];
380     byte_t      CryptographicKeyID[UUIDlen];
381     bool        EncryptedEssence; // true if essence data is (or is going to be) encrypted
382     bool        UsesHMAC;         // true if HMAC exists or is to be calculated
383     std::string ProductVersion;
384     std::string CompanyName;
385     std::string ProductName;
386     LabelSet_t  LabelSetType;
387
388     WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
389     {
390       static byte_t default_ProductUUID_Data[UUIDlen] = {
391         0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
392         0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
393
394       memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
395       memset(AssetUUID, 0, UUIDlen);
396       memset(ContextID, 0, UUIDlen);
397       memset(CryptographicKeyID, 0, UUIDlen);
398
399       ProductVersion = "Unreleased ";
400       ProductVersion += Version();
401       CompanyName = "DCI";
402       ProductName = "asdcplib";
403     }
404   };
405
406   // Print WriterInfo to std::ostream
407   std::ostream& operator << (std::ostream& strm, const WriterInfo& winfo);
408   // Print WriterInfo to stream, stderr by default.
409   void WriterInfoDump(const WriterInfo&, FILE* = 0);
410
411   //---------------------------------------------------------------------------------
412   // cryptographic support
413
414   // The following classes define interfaces to Rijndael contexts having the following properties:
415   //  o 16 byte key
416   //  o CBC mode with 16 byte block size
417   const ui32_t CBC_KEY_SIZE = 16;
418   const ui32_t CBC_BLOCK_SIZE = 16;
419   const ui32_t HMAC_SIZE = 20;
420
421   //
422   class AESEncContext
423     {
424       class h__AESContext;
425       mem_ptr<h__AESContext> m_Context;
426       ASDCP_NO_COPY_CONSTRUCT(AESEncContext);
427
428     public:
429       AESEncContext();
430       ~AESEncContext();
431
432       // Initializes Rijndael CBC encryption context.
433       // Returns error if the key argument is NULL.
434       Result_t InitKey(const byte_t* key);
435
436       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
437       // any number of times for a given key.
438       // Returns error if the i_vec argument is NULL.
439       Result_t SetIVec(const byte_t* i_vec);
440       Result_t GetIVec(byte_t* i_vec) const;
441
442       // Encrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
443       // Returns error if either argument is NULL.
444       Result_t EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size);
445     };
446
447   //
448   class AESDecContext
449     {
450       class h__AESContext;
451       mem_ptr<h__AESContext> m_Context;
452       ASDCP_NO_COPY_CONSTRUCT(AESDecContext);
453
454     public:
455       AESDecContext();
456       ~AESDecContext();
457
458       // Initializes Rijndael CBC decryption context.
459       // Returns error if the key argument is NULL.
460       Result_t InitKey(const byte_t* key);
461
462       // Initializes 16 byte CBC Initialization Vector. This operation may be performed
463       // any number of times for a given key.
464       // Returns error if the i_vec argument is NULL.
465       Result_t SetIVec(const byte_t* i_vec);
466
467       // Decrypt a block of data. The block size must be a multiple of CBC_BLOCK_SIZE.
468       // Returns error if either argument is NULL.
469       Result_t DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size);
470     };
471
472   //
473   class HMACContext
474     {
475       class h__HMACContext;
476       mem_ptr<h__HMACContext> m_Context;
477       ASDCP_NO_COPY_CONSTRUCT(HMACContext);
478
479     public:
480       HMACContext();
481       ~HMACContext();
482
483       // Initializes HMAC context. The key argument must point to a binary
484       // key that is CBC_KEY_SIZE bytes in length. Returns error if the key
485       // argument is NULL.
486       Result_t InitKey(const byte_t* key, LabelSet_t);
487
488       // Reset internal state, allows repeated cycles of Update -> Finalize
489       void Reset();
490
491       // Add data to the digest. Returns error if the key argument is NULL or
492       // if the digest has been finalized.
493       Result_t Update(const byte_t* buf, ui32_t buf_len);
494
495       // Finalize digest.  Returns error if the digest has already been finalized.
496       Result_t Finalize();
497
498       // Writes HMAC value to given buffer. buf must point to a writable area of
499       // memory that is at least HMAC_SIZE bytes in length. Returns error if the
500       // buf argument is NULL or if the digest has not been finalized.
501       Result_t GetHMACValue(byte_t* buf) const;
502
503       // Tests the given value against the finalized value in the object. buf must
504       // point to a readable area of memory that is at least HMAC_SIZE bytes in length.
505       // Returns error if the buf argument is NULL or if the values do ot match.
506       Result_t TestHMACValue(const byte_t* buf) const;
507     };
508
509   //---------------------------------------------------------------------------------
510   // frame buffer base class
511   //
512   // The supported essence types are stored using per-frame KLV packetization. The
513   // following class implements essence-neutral functionality for managing a buffer
514   // containing a frame of essence.
515
516   class FrameBuffer
517     {
518       ASDCP_NO_COPY_CONSTRUCT(FrameBuffer);
519
520     protected:
521       byte_t* m_Data;          // pointer to memory area containing frame data
522       ui32_t  m_Capacity;      // size of memory area pointed to by m_Data
523       bool    m_OwnMem;        // if false, m_Data points to externally allocated memory
524       ui32_t  m_Size;          // size of frame data in memory area pointed to by m_Data
525       ui32_t  m_FrameNumber;   // delivery-order frame number
526
527       // It is possible to read raw ciphertext from an encrypted AS-DCP file.
528       // After reading an encrypted AS-DCP file in raw mode, the frame buffer will
529       // contain the encrypted source value portion of the Encrypted Triplet, followed
530       // by the integrity pack, if it exists.
531       // The buffer will begin with the IV and CheckValue, followed by encrypted essence
532       // and optional integrity pack
533       // The SourceLength and PlaintextOffset values from the packet will be held in the
534       // following variables:
535       ui32_t  m_SourceLength;       // plaintext length (delivered plaintext+decrypted ciphertext)
536       ui32_t  m_PlaintextOffset;    // offset to first byte of ciphertext
537
538      public:
539       FrameBuffer();
540       virtual ~FrameBuffer();
541
542       // Instructs the object to use an externally allocated buffer. The external
543       // buffer will not be cleaned up by the frame buffer when it exits.
544       // Call with (0,0) to revert to internally allocated buffer.
545       // Returns error if the buf_addr argument is NULL and buf_size is non-zero.
546       Result_t SetData(byte_t* buf_addr, ui32_t buf_size);
547
548       // Sets the size of the internally allocate buffer. Returns RESULT_CAPEXTMEM
549       // if the object is using an externally allocated buffer via SetData();
550       // Resets content size to zero.
551       Result_t Capacity(ui32_t cap);
552
553       // returns the size of the buffer
554       inline ui32_t  Capacity() const { return m_Capacity; }
555
556       // returns a const pointer to the essence data
557       inline const byte_t* RoData() const { return m_Data; }
558
559       // returns a non-const pointer to the essence data
560       inline byte_t* Data() { return m_Data; }
561
562       // set the size of the buffer's contents
563       inline ui32_t  Size(ui32_t size) { return m_Size = size; }
564
565       // returns the size of the buffer's contents
566       inline ui32_t  Size() const { return m_Size; }
567
568       // Sets the absolute frame number of this frame in the file in delivery order.
569       inline void    FrameNumber(ui32_t num) { m_FrameNumber = num; }
570
571       // Returns the absolute frame number of this frame in the file in delivery order.
572       inline ui32_t  FrameNumber() const { return m_FrameNumber; }
573
574       // Sets the length of the plaintext essence data
575       inline void    SourceLength(ui32_t len) { m_SourceLength = len; }
576
577       // When this value is 0 (zero), the buffer contains only plaintext. When it is
578       // non-zero, the buffer contains raw ciphertext and the return value is the length
579       // of the original plaintext.
580       inline ui32_t  SourceLength() const { return m_SourceLength; }
581
582       // Sets the offset into the buffer at which encrypted data begins
583       inline void    PlaintextOffset(ui32_t ofst) { m_PlaintextOffset = ofst; }
584
585       // Returns offset into buffer of first byte of ciphertext.
586       inline ui32_t  PlaintextOffset() const { return m_PlaintextOffset; }
587     };
588
589   //---------------------------------------------------------------------------------
590   // Accessors in the MXFReader and MXFWriter classes below return these types to
591   // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
592
593   namespace MXF {
594     // #include<Metadata.h> to use these
595     class OP1aHeader;
596     class OPAtomIndexFooter;
597     class RIP;
598   };
599
600   //---------------------------------------------------------------------------------
601   // MPEG2 video elementary stream support
602
603   //
604   namespace MPEG2
605     {
606       // MPEG picture coding type
607       enum FrameType_t {
608         FRAME_U = 0x00, // Unknown
609         FRAME_I = 0x01, // I-Frame
610         FRAME_P = 0x02, // P-Frame
611         FRAME_B = 0x03  // B-Frame
612       };
613
614       // convert FrameType_t to char
615       inline char FrameTypeChar(FrameType_t type)
616         {
617           switch ( type )
618             {
619             case FRAME_I: return 'I';
620             case FRAME_B: return 'B';
621             case FRAME_P: return 'P';
622             default: return 'U';
623             }
624         }
625
626       // Structure represents the metadata elements in the file header's
627       // MPEG2VideoDescriptor object.
628       struct VideoDescriptor
629         {
630           Rational EditRate;                //
631           ui32_t   FrameRate;               //
632           Rational SampleRate;              //
633           ui8_t    FrameLayout;             //
634           ui32_t   StoredWidth;             //
635           ui32_t   StoredHeight;            //
636           Rational AspectRatio;             //
637           ui32_t   ComponentDepth;          //
638           ui32_t   HorizontalSubsampling;   //
639           ui32_t   VerticalSubsampling;     //
640           ui8_t    ColorSiting;             //
641           ui8_t    CodedContentType;        //
642           bool     LowDelay;                //
643           ui32_t   BitRate;                 //
644           ui8_t    ProfileAndLevel;         //
645           ui32_t   ContainerDuration;       //
646       };
647
648       // Print VideoDescriptor to std::ostream
649       std::ostream& operator << (std::ostream& strm, const VideoDescriptor& vdesc);
650       // Print VideoDescriptor to stream, stderr by default.
651       void VideoDescriptorDump(const VideoDescriptor&, FILE* = 0);
652
653       // A container for MPEG frame data.
654       class FrameBuffer : public ASDCP::FrameBuffer
655         {
656           ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
657
658         protected:
659           FrameType_t m_FrameType;
660           ui8_t       m_TemporalOffset;
661           bool        m_ClosedGOP;
662           bool        m_GOPStart;
663
664         public:
665           FrameBuffer() :
666             m_FrameType(FRAME_U), m_TemporalOffset(0),
667             m_ClosedGOP(false), m_GOPStart(false) {}
668
669           FrameBuffer(ui32_t size) :
670             m_FrameType(FRAME_U), m_TemporalOffset(0),
671             m_ClosedGOP(false), m_GOPStart(false)
672             {
673               Capacity(size);
674             }
675
676           virtual ~FrameBuffer() {}
677
678           // Sets the MPEG frame type of the picture data in the frame buffer.
679           inline void FrameType(FrameType_t type) { m_FrameType = type; }
680
681           // Returns the MPEG frame type of the picture data in the frame buffer.
682           inline FrameType_t FrameType() const { return m_FrameType; }
683
684           // Sets the MPEG temporal offset of the picture data in the frame buffer.
685           inline void TemporalOffset(ui8_t offset) { m_TemporalOffset = offset; }
686
687           // Returns the MPEG temporal offset of the picture data in the frame buffer.
688           inline ui8_t TemporalOffset() const { return m_TemporalOffset; }
689
690           // Sets the MPEG GOP 'start' attribute for the frame buffer.
691           inline void GOPStart(bool start) { m_GOPStart = start; }
692
693           // True if the frame in the buffer is the first in the GOP (in transport order)
694           inline bool GOPStart() const { return m_GOPStart; }
695
696           // Sets the MPEG GOP 'closed' attribute for the frame buffer.
697           inline void ClosedGOP(bool closed) { m_ClosedGOP = closed; }
698
699           // Returns true if the frame in the buffer is from a closed GOP, false if
700           // the frame is from an open GOP.  Always returns false unless GOPStart()
701           // returns true.
702           inline bool ClosedGOP() const { return m_ClosedGOP; }
703
704           // Print object state to stream, include n bytes of frame data if indicated.
705           // Default stream is stderr.
706           void    Dump(FILE* = 0, ui32_t dump_len = 0) const;
707         };
708
709
710       // An object which opens and reads an MPEG2 Video Elementary Stream file.  The call to
711       // OpenRead() reads metadata from the file and populates an internal VideoDescriptor object.
712       // Each subsequent call to ReadFrame() reads exactly one frame from the stream into the
713       // given FrameBuffer object.
714       class Parser
715         {
716           class h__Parser;
717           mem_ptr<h__Parser> m_Parser;
718           ASDCP_NO_COPY_CONSTRUCT(Parser);
719
720         public:
721           Parser();
722           virtual ~Parser();
723
724           // Opens the stream for reading, parses enough data to provide a complete
725           // set of stream metadata for the MXFWriter below.
726           Result_t OpenRead(const std::string& filename) const;
727
728           // Fill a VideoDescriptor struct with the values from the file's header.
729           // Returns RESULT_INIT if the file is not open.
730           Result_t FillVideoDescriptor(VideoDescriptor&) const;
731
732           // Rewind the stream to the beginning.
733           Result_t Reset() const;
734
735           // Reads the next sequential frame in the input file and places it in the
736           // frame buffer. Fails if the buffer is too small or the stream is empty.
737           // The frame buffer's PlaintextOffset parameter will be set to the first
738           // data byte of the first slice. Set this value to zero if you want
739           // encrypted headers.
740           Result_t ReadFrame(FrameBuffer&) const;
741         };
742
743       // A class which creates and writes MPEG frame data to an AS-DCP format MXF file.
744       // Not yet implemented
745       class MXFWriter
746         {
747           class h__Writer;
748           mem_ptr<h__Writer> m_Writer;
749           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
750
751         public:
752           MXFWriter();
753           virtual ~MXFWriter();
754
755           // Warning: direct manipulation of MXF structures can interfere
756           // with the normal operation of the wrapper.  Caveat emptor!
757           virtual MXF::OP1aHeader& OP1aHeader();
758           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
759           virtual MXF::RIP& RIP();
760
761           // Open the file for writing. The file must not exist. Returns error if
762           // the operation cannot be completed or if nonsensical data is discovered
763           // in the essence descriptor.
764           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
765                              const VideoDescriptor&, ui32_t HeaderSize = 16384);
766
767           // Writes a frame of essence to the MXF file. If the optional AESEncContext
768           // argument is present, the essence is encrypted prior to writing.
769           // Fails if the file is not open, is finalized, or an operating system
770           // error occurs.
771           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
772
773           // Closes the MXF file, writing the index and revised header.
774           Result_t Finalize();
775         };
776
777       // A class which reads MPEG frame data from an AS-DCP format MXF file.
778       class MXFReader
779         {
780           class h__Reader;
781           mem_ptr<h__Reader> m_Reader;
782           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
783
784         public:
785           MXFReader();
786           virtual ~MXFReader();
787
788           // Warning: direct manipulation of MXF structures can interfere
789           // with the normal operation of the wrapper.  Caveat emptor!
790           virtual MXF::OP1aHeader& OP1aHeader();
791           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
792           virtual MXF::RIP& RIP();
793
794           // Open the file for reading. The file must exist. Returns error if the
795           // operation cannot be completed.
796           Result_t OpenRead(const std::string& filename) const;
797
798           // Returns RESULT_INIT if the file is not open.
799           Result_t Close() const;
800
801           // Fill a VideoDescriptor struct with the values from the file's header.
802           // Returns RESULT_INIT if the file is not open.
803           Result_t FillVideoDescriptor(VideoDescriptor&) const;
804
805           // Fill a WriterInfo struct with the values from the file's header.
806           // Returns RESULT_INIT if the file is not open.
807           Result_t FillWriterInfo(WriterInfo&) const;
808
809           // Reads a frame of essence from the MXF file. If the optional AESEncContext
810           // argument is present, the essence is decrypted after reading. If the MXF
811           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
812           // will contain the ciphertext frame data. If the HMACContext argument is
813           // not NULL, the HMAC will be calculated (if the file supports it).
814           // Returns RESULT_INIT if the file is not open, failure if the frame number is
815           // out of range, or if optional decrypt or HAMC operations fail.
816           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
817
818           // Using the index table read from the footer partition, lookup the frame number
819           // and return the offset into the file at which to read that frame of essence.
820           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
821           // out of range.
822           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
823
824           // Calculates the first frame in transport order of the GOP in which the requested
825           // frame is located.  Calls ReadFrame() to fetch the frame at the calculated position.
826           // Returns RESULT_INIT if the file is not open.
827           Result_t ReadFrameGOPStart(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
828
829           // Calculates the first frame in transport order of the GOP in which the requested
830           // frame is located.  Sets key_frame_number to the number of the frame at the calculated position.
831           // Returns RESULT_INIT if the file is not open.
832           Result_t FindFrameGOPStart(ui32_t frame_number, ui32_t& key_frame_number) const;
833
834           // Returns the type of the frame at the given position.
835           // Returns RESULT_INIT if the file is not open or RESULT_RANGE if the index is out of range.
836           Result_t FrameType(ui32_t frame_number, FrameType_t&) const;
837
838           // Print debugging information to stream
839           void     DumpHeaderMetadata(FILE* = 0) const;
840           void     DumpIndex(FILE* = 0) const;
841         };
842     } // namespace MPEG2
843
844   //---------------------------------------------------------------------------------
845   //
846
847
848
849   namespace PCM
850     {
851       // The default value of the ChannelFormat element of the AudioDescriptor struct
852       // is CF_NONE. If the value is set to one of the other ChannelFormat_t enum
853       // values, the file's Wave Audio Descriptor will contain a Channel Assignment
854       // element.
855       //
856       // The channel format should be one of (CF_CFG_1, CF_CFG_2, or CF_CFG_3) for
857       // SMPTE 429-2 files. It should normally be CF_NONE for JPEG Interop files, but
858       // the 429-2 may also be used.
859       //
860       enum ChannelFormat_t {
861         CF_NONE,
862         CF_CFG_1, // 5.1 with optional HI/VI
863         CF_CFG_2, // 6.1 (5.1 + center surround) with optional HI/VI
864         CF_CFG_3, // 7.1 (SDDS) with optional HI/VI
865         CF_CFG_4, // Wild Track Format
866         CF_CFG_5, // 7.1 DS with optional HI/VI
867         CF_CFG_6, // ST 377-4 (MCA) labels (see also ASDCP::MXF::decode_mca_string)
868         CF_MAXIMUM
869       };
870
871       struct AudioDescriptor
872         {
873           Rational EditRate;         // rate of frame wrapping
874           Rational AudioSamplingRate;  // rate of audio sample
875           ui32_t   Locked;             //
876           ui32_t   ChannelCount;       // number of channels
877           ui32_t   QuantizationBits;   // number of bits per single-channel sample
878           ui32_t   BlockAlign;         // number of bytes ber sample, all channels
879           ui32_t   AvgBps;             //
880           ui32_t   LinkedTrackID;      //
881           ui32_t   ContainerDuration;  // number of frames
882           ChannelFormat_t ChannelFormat; // audio channel arrangement
883       };
884
885       // Print AudioDescriptor to std::ostream
886       std::ostream& operator << (std::ostream& strm, const AudioDescriptor& adesc);
887       // Print debugging information to stream (stderr default)
888       void   AudioDescriptorDump(const AudioDescriptor&, FILE* = 0);
889
890       // Returns size in bytes of a single sample of data described by ADesc
891       inline ui32_t CalcSampleSize(const AudioDescriptor& ADesc)
892         {
893           return (ADesc.QuantizationBits / 8) * ADesc.ChannelCount;
894         }
895
896       // Returns number of samples per frame of data described by ADesc
897       inline ui32_t CalcSamplesPerFrame(const AudioDescriptor& ADesc)
898         {
899           double tmpd = ADesc.AudioSamplingRate.Quotient() / ADesc.EditRate.Quotient();
900           return (ui32_t)ceil(tmpd);
901         }
902
903       // Returns the size in bytes of a frame of data described by ADesc
904       inline ui32_t CalcFrameBufferSize(const AudioDescriptor& ADesc)
905         {
906           return CalcSampleSize(ADesc) * CalcSamplesPerFrame(ADesc);
907         }
908
909       //
910       class FrameBuffer : public ASDCP::FrameBuffer
911         {
912         public:
913           FrameBuffer() {}
914           FrameBuffer(ui32_t size) { Capacity(size); }
915           virtual ~FrameBuffer() {}
916
917           // Print debugging information to stream (stderr default)
918           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
919         };
920
921       // An object which opens and reads a WAV file.  The call to OpenRead() reads metadata from
922       // the file and populates an internal AudioDescriptor object. Each subsequent call to
923       // ReadFrame() reads exactly one frame from the stream into the given FrameBuffer object.
924       // A "frame" is either 2000 or 2002 samples, depending upon the value of PictureRate.
925       class WAVParser
926         {
927           class h__WAVParser;
928           mem_ptr<h__WAVParser> m_Parser;
929           ASDCP_NO_COPY_CONSTRUCT(WAVParser);
930
931         public:
932           WAVParser();
933           virtual ~WAVParser();
934
935           // Opens the stream for reading, parses enough data to provide a complete
936           // set of stream metadata for the MXFWriter below. PictureRate controls
937           // ther frame rate for the MXF frame wrapping option.
938           Result_t OpenRead(const std::string& filename, const Rational& PictureRate) const;
939
940           // Fill an AudioDescriptor struct with the values from the file's header.
941           // Returns RESULT_INIT if the file is not open.
942           Result_t FillAudioDescriptor(AudioDescriptor&) const;
943
944           // Rewind the stream to the beginning.
945           Result_t Reset() const;
946
947           // Reads the next sequential frame in the input file and places it in the
948           // frame buffer. Fails if the buffer is too small or the stream is empty.
949           Result_t ReadFrame(FrameBuffer&) const;
950
951           Result_t Seek(ui32_t frame_number) const;
952         };
953
954
955       //
956       class MXFWriter
957         {
958           class h__Writer;
959           mem_ptr<h__Writer> m_Writer;
960           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
961
962         public:
963           MXFWriter();
964           virtual ~MXFWriter();
965
966           // Warning: direct manipulation of MXF structures can interfere
967           // with the normal operation of the wrapper.  Caveat emptor!
968           virtual MXF::OP1aHeader& OP1aHeader();
969           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
970           virtual MXF::RIP& RIP();
971
972           // Open the file for writing. The file must not exist. Returns error if
973           // the operation cannot be completed or if nonsensical data is discovered
974           // in the essence descriptor.
975           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
976                              const AudioDescriptor&, ui32_t HeaderSize = 16384);
977
978           // Writes a frame of essence to the MXF file. If the optional AESEncContext
979           // argument is present, the essence is encrypted prior to writing.
980           // Fails if the file is not open, is finalized, or an operating system
981           // error occurs.
982           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
983
984           // Closes the MXF file, writing the index and revised header.
985           Result_t Finalize();
986         };
987
988       //
989       class MXFReader
990         {
991           class h__Reader;
992           mem_ptr<h__Reader> m_Reader;
993           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
994
995         public:
996           MXFReader();
997           virtual ~MXFReader();
998
999           // Warning: direct manipulation of MXF structures can interfere
1000           // with the normal operation of the wrapper.  Caveat emptor!
1001           virtual MXF::OP1aHeader& OP1aHeader();
1002           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1003           virtual MXF::RIP& RIP();
1004
1005           // Open the file for reading. The file must exist. Returns error if the
1006           // operation cannot be completed.
1007           Result_t OpenRead(const std::string& filename) const;
1008
1009           // Returns RESULT_INIT if the file is not open.
1010           Result_t Close() const;
1011
1012           // Fill an AudioDescriptor struct with the values from the file's header.
1013           // Returns RESULT_INIT if the file is not open.
1014           Result_t FillAudioDescriptor(AudioDescriptor&) const;
1015
1016           // Fill a WriterInfo struct with the values from the file's header.
1017           // Returns RESULT_INIT if the file is not open.
1018           Result_t FillWriterInfo(WriterInfo&) const;
1019
1020           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1021           // argument is present, the essence is decrypted after reading. If the MXF
1022           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1023           // will contain the ciphertext frame data. If the HMACContext argument is
1024           // not NULL, the HMAC will be calculated (if the file supports it).
1025           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1026           // out of range, or if optional decrypt or HAMC operations fail.
1027           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1028
1029           // Using the index table read from the footer partition, lookup the frame number
1030           // and return the offset into the file at which to read that frame of essence.
1031           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1032           // out of range.
1033           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1034
1035           // Print debugging information to stream
1036           void     DumpHeaderMetadata(FILE* = 0) const;
1037           void     DumpIndex(FILE* = 0) const;
1038         };
1039     } // namespace PCM
1040
1041   //---------------------------------------------------------------------------------
1042   //
1043   namespace JP2K
1044     {
1045       const ui32_t MaxComponents = 3;
1046       const ui32_t MaxPrecincts = 32; // ISO 15444-1 Annex A.6.1
1047       const ui32_t MaxDefaults = 256; // made up
1048
1049 #pragma pack(1)
1050       struct ImageComponent_t  // ISO 15444-1 Annex A.5.1
1051       {
1052         ui8_t Ssize;
1053         ui8_t XRsize;
1054         ui8_t YRsize;
1055       };
1056
1057       struct CodingStyleDefault_t // ISO 15444-1 Annex A.6.1
1058       {
1059         ui8_t   Scod;
1060
1061         struct
1062         {
1063           ui8_t  ProgressionOrder;
1064           ui8_t  NumberOfLayers[sizeof(ui16_t)];
1065           ui8_t  MultiCompTransform;
1066         } SGcod;
1067
1068         struct
1069         {
1070           ui8_t  DecompositionLevels;
1071           ui8_t  CodeblockWidth;
1072           ui8_t  CodeblockHeight;
1073           ui8_t  CodeblockStyle;
1074           ui8_t  Transformation;
1075           ui8_t  PrecinctSize[MaxPrecincts];
1076         } SPcod;
1077       };
1078
1079       struct QuantizationDefault_t // ISO 15444-1 Annex A.6.4
1080       {
1081         ui8_t  Sqcd;
1082         ui8_t  SPqcd[MaxDefaults];
1083         ui8_t  SPqcdLength;
1084       };
1085 #pragma pack()
1086
1087       struct PictureDescriptor
1088       {
1089         Rational       EditRate;
1090         ui32_t         ContainerDuration;
1091         Rational       SampleRate;
1092         ui32_t         StoredWidth;
1093         ui32_t         StoredHeight;
1094         Rational       AspectRatio;
1095         ui16_t         Rsize;
1096         ui32_t         Xsize;
1097         ui32_t         Ysize;
1098         ui32_t         XOsize;
1099         ui32_t         YOsize;
1100         ui32_t         XTsize;
1101         ui32_t         YTsize;
1102         ui32_t         XTOsize;
1103         ui32_t         YTOsize;
1104         ui16_t         Csize;
1105         ImageComponent_t      ImageComponents[MaxComponents];
1106         CodingStyleDefault_t  CodingStyleDefault;
1107         QuantizationDefault_t QuantizationDefault;
1108       };
1109
1110       // Print debugging information to std::ostream
1111       std::ostream& operator << (std::ostream& strm, const PictureDescriptor& pdesc);
1112       // Print debugging information to stream (stderr default)
1113       void   PictureDescriptorDump(const PictureDescriptor&, FILE* = 0);
1114
1115       //
1116       class FrameBuffer : public ASDCP::FrameBuffer
1117         {
1118         public:
1119           FrameBuffer() {}
1120           FrameBuffer(ui32_t size) { Capacity(size); }
1121           virtual ~FrameBuffer() {}
1122
1123           // Print debugging information to stream (stderr default)
1124           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1125         };
1126
1127
1128       // An object which opens and reads a JPEG 2000 codestream file.  The file is expected
1129       // to contain exactly one complete frame of picture essence as an unwrapped (raw)
1130       // ISO/IEC 15444 codestream.
1131       class CodestreamParser
1132         {
1133           class h__CodestreamParser;
1134           mem_ptr<h__CodestreamParser> m_Parser;
1135           ASDCP_NO_COPY_CONSTRUCT(CodestreamParser);
1136
1137         public:
1138           CodestreamParser();
1139           virtual ~CodestreamParser();
1140
1141           // Opens a file for reading, parses enough data to provide a complete
1142           // set of stream metadata for the MXFWriter below.
1143           // The frame buffer's PlaintextOffset parameter will be set to the first
1144           // byte of the data segment. Set this value to zero if you want
1145           // encrypted headers.
1146           Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1147
1148           // Fill a PictureDescriptor struct with the values from the file's codestream.
1149           // Returns RESULT_INIT if the file is not open.
1150           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1151         };
1152
1153       // Parses the data in the frame buffer to fill in the picture descriptor. Copies
1154       // the offset of the image data into start_of_data. Returns error if the parser fails.
1155       Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
1156
1157       // An object which reads a sequence of files containing JPEG 2000 pictures.
1158       class SequenceParser
1159         {
1160           class h__SequenceParser;
1161           mem_ptr<h__SequenceParser> m_Parser;
1162           ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1163
1164         public:
1165           SequenceParser();
1166           virtual ~SequenceParser();
1167
1168           // Opens a directory for reading.  The directory is expected to contain one or
1169           // more files, each containing the codestream for exactly one picture. The
1170           // files must be named such that the frames are in temporal order when sorted
1171           // alphabetically by filename. The parser will automatically parse enough data
1172           // from the first file to provide a complete set of stream metadata for the
1173           // MXFWriter below.  If the "pedantic" parameter is given and is true, the
1174           // parser will check the metadata for each codestream and fail if a
1175           // mismatch is detected.
1176           Result_t OpenRead(const std::string& filename, bool pedantic = false) const;
1177
1178           // Opens a file sequence for reading.  The sequence is expected to contain one or
1179           // more filenames, each naming a file containing the codestream for exactly one
1180           // picture. The parser will automatically parse enough data
1181           // from the first file to provide a complete set of stream metadata for the
1182           // MXFWriter below.  If the "pedantic" parameter is given and is true, the
1183           // parser will check the metadata for each codestream and fail if a
1184           // mismatch is detected.
1185           Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic = false) const;
1186
1187           // Fill a PictureDescriptor struct with the values from the first file's codestream.
1188           // Returns RESULT_INIT if the directory is not open.
1189           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1190
1191           // Rewind the directory to the beginning.
1192           Result_t Reset() const;
1193
1194           // Reads the next sequential frame in the directory and places it in the
1195           // frame buffer. Fails if the buffer is too small or the direcdtory
1196           // contains no more files.
1197           // The frame buffer's PlaintextOffset parameter will be set to the first
1198           // byte of the data segment. Set this value to zero if you want
1199           // encrypted headers.
1200           Result_t ReadFrame(FrameBuffer&) const;
1201         };
1202
1203
1204       //
1205       class MXFWriter
1206         {
1207           class h__Writer;
1208           mem_ptr<h__Writer> m_Writer;
1209           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1210
1211         public:
1212           MXFWriter();
1213           virtual ~MXFWriter();
1214
1215           // Warning: direct manipulation of MXF structures can interfere
1216           // with the normal operation of the wrapper.  Caveat emptor!
1217           virtual MXF::OP1aHeader& OP1aHeader();
1218           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1219           virtual MXF::RIP& RIP();
1220
1221           // Open the file for writing. The file must not exist. Returns error if
1222           // the operation cannot be completed or if nonsensical data is discovered
1223           // in the essence descriptor.
1224           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1225                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1226
1227           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1228           // argument is present, the essence is encrypted prior to writing.
1229           // Fails if the file is not open, is finalized, or an operating system
1230           // error occurs.
1231           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1232
1233           // Closes the MXF file, writing the index and revised header.
1234           Result_t Finalize();
1235         };
1236
1237       //
1238       class MXFReader
1239         {
1240           class h__Reader;
1241           mem_ptr<h__Reader> m_Reader;
1242           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1243
1244         public:
1245           MXFReader();
1246           virtual ~MXFReader();
1247
1248           // Warning: direct manipulation of MXF structures can interfere
1249           // with the normal operation of the wrapper.  Caveat emptor!
1250           virtual MXF::OP1aHeader& OP1aHeader();
1251           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1252           virtual MXF::RIP& RIP();
1253
1254           // Open the file for reading. The file must exist. Returns error if the
1255           // operation cannot be completed.
1256           Result_t OpenRead(const std::string& filename) const;
1257
1258           // Returns RESULT_INIT if the file is not open.
1259           Result_t Close() const;
1260
1261           // Fill an AudioDescriptor struct with the values from the file's header.
1262           // Returns RESULT_INIT if the file is not open.
1263           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1264
1265           // Fill a WriterInfo struct with the values from the file's header.
1266           // Returns RESULT_INIT if the file is not open.
1267           Result_t FillWriterInfo(WriterInfo&) const;
1268
1269           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1270           // argument is present, the essence is decrypted after reading. If the MXF
1271           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1272           // will contain the ciphertext frame data. If the HMACContext argument is
1273           // not NULL, the HMAC will be calculated (if the file supports it).
1274           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1275           // out of range, or if optional decrypt or HAMC operations fail.
1276           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1277
1278           // Using the index table read from the footer partition, lookup the frame number
1279           // and return the offset into the file at which to read that frame of essence.
1280           // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1281           // out of range.
1282           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1283
1284           // Print debugging information to stream
1285           void     DumpHeaderMetadata(FILE* = 0) const;
1286           void     DumpIndex(FILE* = 0) const;
1287         };
1288
1289
1290       // Stereoscopic Image support
1291       //
1292
1293       enum StereoscopicPhase_t
1294       {
1295         SP_LEFT,
1296         SP_RIGHT
1297       };
1298
1299       struct SFrameBuffer
1300       {
1301         JP2K::FrameBuffer Left;
1302         JP2K::FrameBuffer Right;
1303
1304         SFrameBuffer(ui32_t size) {
1305           Left.Capacity(size);
1306           Right.Capacity(size);
1307         }
1308       };
1309
1310       class MXFSWriter
1311       {
1312           class h__SWriter;
1313           mem_ptr<h__SWriter> m_Writer;
1314           ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
1315
1316         public:
1317           MXFSWriter();
1318           virtual ~MXFSWriter();
1319
1320           // Warning: direct manipulation of MXF structures can interfere
1321           // with the normal operation of the wrapper.  Caveat emptor!
1322           virtual MXF::OP1aHeader& OP1aHeader();
1323           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1324           virtual MXF::RIP& RIP();
1325
1326           // Open the file for writing. The file must not exist. Returns error if
1327           // the operation cannot be completed or if nonsensical data is discovered
1328           // in the essence descriptor.
1329           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1330                              const PictureDescriptor&, ui32_t HeaderSize = 16384);
1331
1332           // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
1333           // argument is present, the essence is encrypted prior to writing.
1334           // Fails if the file is not open, is finalized, or an operating system
1335           // error occurs.
1336           Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1337
1338           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1339           // argument is present, the essence is encrypted prior to writing.
1340           // Fails if the file is not open, is finalized, or an operating system
1341           // error occurs. Frames must be written in the proper phase (L-R-L-R),
1342           // RESULT_SPHASE will be returned if phase is reversed. The first frame
1343           // written must be left eye.
1344           Result_t WriteFrame(const FrameBuffer&, StereoscopicPhase_t phase,
1345                               AESEncContext* = 0, HMACContext* = 0);
1346
1347           // Closes the MXF file, writing the index and revised header.  Returns
1348           // RESULT_SPHASE if WriteFrame was called an odd number of times.
1349           Result_t Finalize();
1350         };
1351
1352       //
1353       class MXFSReader
1354         {
1355           class h__SReader;
1356           mem_ptr<h__SReader> m_Reader;
1357           ASDCP_NO_COPY_CONSTRUCT(MXFSReader);
1358
1359         public:
1360           MXFSReader();
1361           virtual ~MXFSReader();
1362
1363           // Warning: direct manipulation of MXF structures can interfere
1364           // with the normal operation of the wrapper.  Caveat emptor!
1365           virtual MXF::OP1aHeader& OP1aHeader();
1366           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1367           virtual MXF::RIP& RIP();
1368
1369           // Open the file for reading. The file must exist. Returns error if the
1370           // operation cannot be completed.
1371           Result_t OpenRead(const std::string& filename) const;
1372
1373           // Returns RESULT_INIT if the file is not open.
1374           Result_t Close() const;
1375
1376           // Fill an AudioDescriptor struct with the values from the file's header.
1377           // Returns RESULT_INIT if the file is not open.
1378           Result_t FillPictureDescriptor(PictureDescriptor&) const;
1379
1380           // Fill a WriterInfo struct with the values from the file's header.
1381           // Returns RESULT_INIT if the file is not open.
1382           Result_t FillWriterInfo(WriterInfo&) const;
1383
1384           // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
1385           // argument is present, the essence is decrypted after reading. If the MXF
1386           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1387           // will contain the ciphertext frame data. If the HMACContext argument is
1388           // not NULL, the HMAC will be calculated (if the file supports it).
1389           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1390           // out of range, or if optional decrypt or HAMC operations fail.
1391           Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1392
1393           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1394           // argument is present, the essence is decrypted after reading. If the MXF
1395           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1396           // will contain the ciphertext frame data. If the HMACContext argument is
1397           // not NULL, the HMAC will be calculated (if the file supports it).
1398           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1399           // out of range, or if optional decrypt or HAMC operations fail.
1400           Result_t ReadFrame(ui32_t frame_number, StereoscopicPhase_t phase,
1401                              FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1402
1403           // Using the index table read from the footer partition, lookup the frame number
1404           // and return the offset into the file at which to read that frame of essence.
1405           // Returns RESULT_INIT if the file is not open, and RESULT_FRAME if the frame number is
1406           // out of range.
1407           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1408
1409           // Print debugging information to stream
1410           void     DumpHeaderMetadata(FILE* = 0) const;
1411           void     DumpIndex(FILE* = 0) const;
1412         };
1413     } // namespace JP2K
1414
1415   //---------------------------------------------------------------------------------
1416   //
1417   namespace TimedText
1418     {
1419       enum MIMEType_t { MT_BIN, MT_PNG, MT_OPENTYPE };
1420
1421       struct TimedTextResourceDescriptor
1422       {
1423         byte_t      ResourceID[UUIDlen];
1424           MIMEType_t  Type;
1425
1426         TimedTextResourceDescriptor() : Type(MT_BIN) {}
1427       };
1428
1429       typedef std::list<TimedTextResourceDescriptor> ResourceList_t;
1430
1431       struct TimedTextDescriptor
1432       {
1433         Rational       EditRate;                //
1434         ui32_t         ContainerDuration;
1435         byte_t         AssetID[UUIDlen];
1436         std::string    NamespaceName;
1437         std::string    EncodingName;
1438         ResourceList_t ResourceList;
1439
1440       TimedTextDescriptor() : ContainerDuration(0), EncodingName("UTF-8") {} // D-Cinema format is always UTF-8
1441       };
1442
1443       // Print debugging information to std::ostream
1444       std::ostream& operator << (std::ostream& strm, const TimedTextDescriptor& tinfo);
1445       // Print debugging information to stream (stderr default)
1446       void   DescriptorDump(const TimedTextDescriptor&, FILE* = 0);
1447
1448       //
1449       class FrameBuffer : public ASDCP::FrameBuffer
1450       {
1451         ASDCP_NO_COPY_CONSTRUCT(FrameBuffer); // TODO: should have copy construct
1452
1453       protected:
1454         byte_t      m_AssetID[UUIDlen];
1455         std::string m_MIMEType;
1456
1457       public:
1458         FrameBuffer() { memset(m_AssetID, 0, UUIDlen); }
1459         FrameBuffer(ui32_t size) { Capacity(size); memset(m_AssetID, 0, UUIDlen); }
1460         virtual ~FrameBuffer() {}
1461
1462         inline const byte_t* AssetID() const { return m_AssetID; }
1463         inline void          AssetID(const byte_t* buf) { memcpy(m_AssetID, buf, UUIDlen); }
1464         inline const char*   MIMEType() const { return m_MIMEType.c_str(); }
1465         inline void          MIMEType(const std::string& s) { m_MIMEType = s; }
1466
1467         // Print debugging information to stream (stderr default)
1468         void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1469       };
1470
1471       // An abstract base for a lookup service that returns the resource data
1472       // identified by the given ancillary resource id.
1473       //
1474       class IResourceResolver
1475       {
1476       public:
1477         virtual ~IResourceResolver() {}
1478         virtual Result_t ResolveRID(const byte_t* uuid, FrameBuffer&) const = 0; // return data for RID
1479       };
1480
1481       // Resolves resource references by testing the named directory for file names containing
1482       // the respective UUID.
1483       //
1484       class LocalFilenameResolver : public ASDCP::TimedText::IResourceResolver
1485         {
1486           std::string m_Dirname;
1487           ASDCP_NO_COPY_CONSTRUCT(LocalFilenameResolver);
1488
1489         public:
1490           LocalFilenameResolver();
1491           virtual ~LocalFilenameResolver();
1492           Result_t OpenRead(const std::string& dirname);
1493           Result_t ResolveRID(const byte_t* uuid, FrameBuffer& FrameBuf) const;
1494         };
1495
1496       //
1497       class DCSubtitleParser
1498         {
1499           class h__SubtitleParser;
1500           mem_ptr<h__SubtitleParser> m_Parser;
1501           ASDCP_NO_COPY_CONSTRUCT(DCSubtitleParser);
1502
1503         public:
1504           DCSubtitleParser();
1505           virtual ~DCSubtitleParser();
1506
1507           // Opens an XML file for reading, parses data to provide a complete
1508           // set of stream metadata for the MXFWriter below.
1509           Result_t OpenRead(const std::string& filename) const;
1510
1511           // Parses an XML document to provide a complete set of stream metadata
1512           // for the MXFWriter below. The optional filename argument is used to
1513           // initialize the default resource resolver (see ReadAncillaryResource).
1514           Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
1515
1516           // Fill a TimedTextDescriptor struct with the values from the file's contents.
1517           // Returns RESULT_INIT if the file is not open.
1518           Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1519
1520           // Reads the complete Timed Text Resource into the given string.
1521           Result_t ReadTimedTextResource(std::string&) const;
1522
1523           // Reads the Ancillary Resource having the given ID. Fails if the buffer
1524           // is too small or the resource does not exist. The optional Resolver
1525           // argument can be provided which will be used to retrieve the resource
1526           // having a particulat UUID. If a Resolver is not supplied, the default
1527           // internal resolver will return the contents of the file having the UUID
1528           // as the filename. The filename must exist in the same directory as the
1529           // XML file opened with OpenRead().
1530           Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&,
1531                                          const IResourceResolver* Resolver = 0) const;
1532         };
1533
1534       //
1535       class MXFWriter
1536         {
1537           class h__Writer;
1538           mem_ptr<h__Writer> m_Writer;
1539           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1540
1541         public:
1542           MXFWriter();
1543           virtual ~MXFWriter();
1544
1545           // Warning: direct manipulation of MXF structures can interfere
1546           // with the normal operation of the wrapper.  Caveat emptor!
1547           virtual MXF::OP1aHeader& OP1aHeader();
1548           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1549           virtual MXF::RIP& RIP();
1550
1551           // Open the file for writing. The file must not exist. Returns error if
1552           // the operation cannot be completed or if nonsensical data is discovered
1553           // in the essence descriptor.
1554           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1555                              const TimedTextDescriptor&, ui32_t HeaderSize = 16384);
1556
1557           // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
1558           // encoded. If the optional AESEncContext argument is present, the essence
1559           // is encrypted prior to writing. Fails if the file is not open, is finalized,
1560           // or an operating system error occurs.
1561           // This method may only be called once, and it must be called before any
1562           // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
1563           // conditions are not met.
1564           Result_t WriteTimedTextResource(const std::string& XMLDoc, AESEncContext* = 0, HMACContext* = 0);
1565
1566           // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
1567           // argument is present, the essence is encrypted prior to writing.
1568           // Fails if the file is not open, is finalized, or an operating system
1569           // error occurs. RESULT_STATE will be returned if the method is called before
1570           // WriteTimedTextResource()
1571           Result_t WriteAncillaryResource(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1572
1573           // Closes the MXF file, writing the index and revised header.
1574           Result_t Finalize();
1575         };
1576
1577       //
1578       class MXFReader
1579         {
1580           class h__Reader;
1581           mem_ptr<h__Reader> m_Reader;
1582           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1583
1584         public:
1585           MXFReader();
1586           virtual ~MXFReader();
1587
1588           // Warning: direct manipulation of MXF structures can interfere
1589           // with the normal operation of the wrapper.  Caveat emptor!
1590           virtual MXF::OP1aHeader& OP1aHeader();
1591           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1592           virtual MXF::RIP& RIP();
1593
1594           // Open the file for reading. The file must exist. Returns error if the
1595           // operation cannot be completed.
1596           Result_t OpenRead(const std::string& filename) const;
1597
1598           // Returns RESULT_INIT if the file is not open.
1599           Result_t Close() const;
1600
1601           // Fill a TimedTextDescriptor struct with the values from the file's header.
1602           // Returns RESULT_INIT if the file is not open.
1603           Result_t FillTimedTextDescriptor(TimedTextDescriptor&) const;
1604
1605           // Fill a WriterInfo struct with the values from the file's header.
1606           // Returns RESULT_INIT if the file is not open.
1607           Result_t FillWriterInfo(WriterInfo&) const;
1608
1609           // Reads the complete Timed Text Resource into the given string. Fails if the resource
1610           // is encrypted and AESDecContext is NULL (use the following method to retrieve the
1611           // raw ciphertet block).
1612           Result_t ReadTimedTextResource(std::string&, AESDecContext* = 0, HMACContext* = 0) const;
1613
1614           // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
1615           // argument is present, the resource is decrypted after reading. If the MXF
1616           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1617           // will contain the ciphertext frame data. If the HMACContext argument is
1618           // not NULL, the HMAC will be calculated (if the file supports it).
1619           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1620           // out of range, or if optional decrypt or HAMC operations fail.
1621           Result_t ReadTimedTextResource(FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1622
1623           // Reads the timed-text resource having the given UUID from the MXF file. If the
1624           // optional AESEncContext argument is present, the resource is decrypted after
1625           // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
1626           // the frame buffer will contain the ciphertext frame data. If the HMACContext
1627           // argument is not NULL, the HMAC will be calculated (if the file supports it).
1628           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1629           // out of range, or if optional decrypt or HAMC operations fail.
1630           Result_t ReadAncillaryResource(const byte_t* uuid, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1631
1632           // Print debugging information to stream
1633           void     DumpHeaderMetadata(FILE* = 0) const;
1634           void     DumpIndex(FILE* = 0) const;
1635         };
1636     } // namespace TimedText
1637
1638   //---------------------------------------------------------------------------------
1639   //
1640   namespace DCData
1641   {
1642     struct DCDataDescriptor
1643     {
1644       Rational EditRate;                 // Sample rate
1645       ui32_t   ContainerDuration;          // number of frames
1646       byte_t   AssetID[UUIDlen];           // The UUID for the DCData track
1647       byte_t   DataEssenceCoding[UUIDlen]; // The coding for the data carried
1648     };
1649
1650     // Print DCDataDescriptor to std::ostream
1651     std::ostream& operator << (std::ostream& strm, const DCDataDescriptor& ddesc);
1652     // Print debugging information to stream (stderr default)
1653     void DCDataDescriptorDump(const DCDataDescriptor&, FILE* = 0);
1654
1655     //
1656     class FrameBuffer : public ASDCP::FrameBuffer
1657         {
1658      public:
1659           FrameBuffer() {}
1660           FrameBuffer(ui32_t size) { Capacity(size); }
1661           virtual ~FrameBuffer() {}
1662
1663           // Print debugging information to stream (stderr default)
1664           void Dump(FILE* = 0, ui32_t dump_bytes = 0) const;
1665         };
1666
1667     // An object which opens and reads a DC Data file.  The file is expected
1668     // to contain exactly one complete frame of DC data essence as an unwrapped (raw)
1669     // byte stream.
1670     class BytestreamParser
1671         {
1672           class h__BytestreamParser;
1673           mem_ptr<h__BytestreamParser> m_Parser;
1674           ASDCP_NO_COPY_CONSTRUCT(BytestreamParser);
1675
1676      public:
1677           BytestreamParser();
1678           virtual ~BytestreamParser();
1679
1680           // Opens a file for reading, parses enough data to provide a complete
1681       // set of stream metadata for the MXFWriter below.
1682           // The frame buffer's PlaintextOffset parameter will be set to the first
1683           // byte of the data segment. Set this value to zero if you want
1684           // encrypted headers.
1685           Result_t OpenReadFrame(const std::string& filename, FrameBuffer&) const;
1686
1687           // Fill a DCDataDescriptor struct with the values from the file's bytestream.
1688           // Returns RESULT_INIT if the file is not open.
1689           Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1690         };
1691
1692     // An object which reads a sequence of files containing DC Data.
1693     class SequenceParser
1694         {
1695           class h__SequenceParser;
1696           mem_ptr<h__SequenceParser> m_Parser;
1697           ASDCP_NO_COPY_CONSTRUCT(SequenceParser);
1698
1699      public:
1700           SequenceParser();
1701           virtual ~SequenceParser();
1702
1703           // Opens a directory for reading.  The directory is expected to contain one or
1704           // more files, each containing the bytestream for exactly one frame. The files
1705       // must be named such that the frames are in temporal order when sorted
1706           // alphabetically by filename.
1707           Result_t OpenRead(const std::string& filename) const;
1708
1709           // Opens a file sequence for reading.  The sequence is expected to contain one or
1710           // more filenames, each naming a file containing the bytestream for exactly one
1711           // frame.
1712           Result_t OpenRead(const std::list<std::string>& file_list) const;
1713
1714           // Fill a DCDataDescriptor struct with default values.
1715           // Returns RESULT_INIT if the directory is not open.
1716           Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1717
1718           // Rewind the directory to the beginning.
1719           Result_t Reset() const;
1720
1721           // Reads the next sequential frame in the directory and places it in the
1722           // frame buffer. Fails if the buffer is too small or the direcdtory
1723           // contains no more files.
1724           // The frame buffer's PlaintextOffset parameter will be set to the first
1725           // byte of the data segment. Set this value to zero if you want
1726           // encrypted headers.
1727           Result_t ReadFrame(FrameBuffer&) const;
1728         };
1729
1730     //
1731     class MXFWriter
1732         {
1733           class h__Writer;
1734           mem_ptr<h__Writer> m_Writer;
1735           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1736
1737      public:
1738           MXFWriter();
1739           virtual ~MXFWriter();
1740
1741           // Warning: direct manipulation of MXF structures can interfere
1742           // with the normal operation of the wrapper.  Caveat emptor!
1743           virtual MXF::OP1aHeader& OP1aHeader();
1744           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1745           virtual MXF::RIP& RIP();
1746
1747           // Open the file for writing. The file must not exist. Returns error if
1748           // the operation cannot be completed or if nonsensical data is discovered
1749           // in the essence descriptor.
1750           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1751                              const DCDataDescriptor&, ui32_t HeaderSize = 16384);
1752
1753           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1754           // argument is present, the essence is encrypted prior to writing.
1755           // Fails if the file is not open, is finalized, or an operating system
1756           // error occurs.
1757           Result_t WriteFrame(const FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1758
1759           // Closes the MXF file, writing the index and revised header.
1760           Result_t Finalize();
1761         };
1762
1763     //
1764     class MXFReader
1765         {
1766           class h__Reader;
1767           mem_ptr<h__Reader> m_Reader;
1768           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1769
1770      public:
1771           MXFReader();
1772           virtual ~MXFReader();
1773
1774           // Warning: direct manipulation of MXF structures can interfere
1775           // with the normal operation of the wrapper.  Caveat emptor!
1776           virtual MXF::OP1aHeader& OP1aHeader();
1777           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1778           virtual MXF::RIP& RIP();
1779
1780           // Open the file for reading. The file must exist. Returns error if the
1781           // operation cannot be completed.
1782           Result_t OpenRead(const std::string& filename) const;
1783
1784           // Returns RESULT_INIT if the file is not open.
1785           Result_t Close() const;
1786
1787           // Fill a DCDataDescriptor struct with the values from the file's header.
1788           // Returns RESULT_INIT if the file is not open.
1789           Result_t FillDCDataDescriptor(DCDataDescriptor&) const;
1790
1791           // Fill a WriterInfo struct with the values from the file's header.
1792           // Returns RESULT_INIT if the file is not open.
1793           Result_t FillWriterInfo(WriterInfo&) const;
1794
1795           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1796           // argument is present, the essence is decrypted after reading. If the MXF
1797           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1798           // will contain the ciphertext frame data. If the HMACContext argument is
1799           // not NULL, the HMAC will be calculated (if the file supports it).
1800           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1801           // out of range, or if optional decrypt or HAMC operations fail.
1802           Result_t ReadFrame(ui32_t frame_number, FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1803
1804           // Using the index table read from the footer partition, lookup the frame number
1805           // and return the offset into the file at which to read that frame of essence.
1806           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1807           // out of range.
1808           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1809
1810           // Print debugging information to stream
1811           void     DumpHeaderMetadata(FILE* = 0) const;
1812           void     DumpIndex(FILE* = 0) const;
1813         };
1814
1815   } // namespace DCData
1816
1817   //---------------------------------------------------------------------------------
1818   //
1819   namespace ATMOS
1820   {
1821     struct AtmosDescriptor : public DCData::DCDataDescriptor
1822     {
1823       ui32_t FirstFrame;       // Frame number of the frame to align with the FFOA of the picture track
1824       ui16_t MaxChannelCount;  // Max number of channels in bitstream
1825       ui16_t MaxObjectCount;   // Max number of objects in bitstream
1826       byte_t AtmosID[UUIDlen]; // UUID of Atmos Project
1827       ui8_t  AtmosVersion;     // ATMOS Coder Version used to create bitstream
1828     };
1829
1830     // Print AtmosDescriptor to std::ostream
1831     std::ostream& operator << (std::ostream& strm, const AtmosDescriptor& adesc);
1832     // Print debugging information to stream (stderr default)
1833     void AtmosDescriptorDump(const AtmosDescriptor&, FILE* = 0);
1834     // Determine if a file is a raw atmos file
1835     bool IsDolbyAtmos(const std::string& filename);
1836
1837     //
1838     class MXFWriter
1839         {
1840
1841       class h__Writer;
1842           mem_ptr<h__Writer> m_Writer;
1843           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
1844
1845      public:
1846           MXFWriter();
1847           virtual ~MXFWriter();
1848
1849           // Warning: direct manipulation of MXF structures can interfere
1850           // with the normal operation of the wrapper.  Caveat emptor!
1851           virtual MXF::OP1aHeader& OP1aHeader();
1852           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1853           virtual MXF::RIP& RIP();
1854
1855           // Open the file for writing. The file must not exist. Returns error if
1856           // the operation cannot be completed or if nonsensical data is discovered
1857           // in the essence descriptor.
1858           Result_t OpenWrite(const std::string& filename, const WriterInfo&,
1859                              const AtmosDescriptor&, ui32_t HeaderSize = 16384);
1860
1861           // Writes a frame of essence to the MXF file. If the optional AESEncContext
1862           // argument is present, the essence is encrypted prior to writing.
1863           // Fails if the file is not open, is finalized, or an operating system
1864           // error occurs.
1865       Result_t WriteFrame(const DCData::FrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
1866
1867           // Closes the MXF file, writing the index and revised header.
1868           Result_t Finalize();
1869         };
1870
1871     //
1872     class MXFReader
1873         {
1874       class h__Reader;
1875           mem_ptr<h__Reader> m_Reader;
1876           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
1877
1878      public:
1879           MXFReader();
1880           virtual ~MXFReader();
1881
1882           // Warning: direct manipulation of MXF structures can interfere
1883           // with the normal operation of the wrapper.  Caveat emptor!
1884           virtual MXF::OP1aHeader& OP1aHeader();
1885           virtual MXF::OPAtomIndexFooter& OPAtomIndexFooter();
1886           virtual MXF::RIP& RIP();
1887
1888           // Open the file for reading. The file must exist. Returns error if the
1889           // operation cannot be completed.
1890           Result_t OpenRead(const std::string& filename) const;
1891
1892           // Returns RESULT_INIT if the file is not open.
1893           Result_t Close() const;
1894
1895           // Fill an AtmosDescriptor struct with the values from the file's header.
1896           // Returns RESULT_INIT if the file is not open.
1897           Result_t FillAtmosDescriptor(AtmosDescriptor&) const;
1898
1899           // Fill a WriterInfo struct with the values from the file's header.
1900           // Returns RESULT_INIT if the file is not open.
1901           Result_t FillWriterInfo(WriterInfo&) const;
1902
1903           // Reads a frame of essence from the MXF file. If the optional AESEncContext
1904           // argument is present, the essence is decrypted after reading. If the MXF
1905           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
1906           // will contain the ciphertext frame data. If the HMACContext argument is
1907           // not NULL, the HMAC will be calculated (if the file supports it).
1908           // Returns RESULT_INIT if the file is not open, failure if the frame number is
1909           // out of range, or if optional decrypt or HAMC operations fail.
1910           Result_t ReadFrame(ui32_t frame_number, DCData::FrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
1911
1912           // Using the index table read from the footer partition, lookup the frame number
1913           // and return the offset into the file at which to read that frame of essence.
1914           // Returns RESULT_INIT if the file is not open, and RESULT_RANGE if the frame number is
1915           // out of range.
1916           Result_t LocateFrame(ui32_t FrameNum, Kumu::fpos_t& streamOffset, i8_t& temporalOffset, i8_t& keyFrameOffset) const;
1917
1918           // Print debugging information to stream
1919           void     DumpHeaderMetadata(FILE* = 0) const;
1920           void     DumpIndex(FILE* = 0) const;
1921         };
1922
1923   } // namespace ATMOS
1924
1925
1926
1927 } // namespace ASDCP
1928
1929
1930 #endif // _AS_DCP_H_
1931
1932 //
1933 // end AS_DCP.h
1934 //