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