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