fix: allow full 64 bits of index duration through API
[asdcplib.git] / src / AS_02.h
1 /*
2 Copyright (c) 2011-2018, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
3 John Hurst
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10 1. Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15 3. The name of the author may not be used to endorse or promote products
16    derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 
29 /*! \file    AS_02.h
30     \version $Id$       
31     \brief   AS-02 library, public interface
32
33 This module implements MXF AS-02 is a set of file access objects that
34 offer simplified access to files conforming to the standards published
35 by the SMPTE Media and Packaging Technology Committee 35PM. The file
36 format, labeled IMF Essence Component (AKA "AS-02" for historical
37 reasons), is described in the following document:
38
39  o SMPTE 2067-5:2013 IMF Essence Component
40
41 The following use cases are supported by the module:
42
43  o Write essence to a plaintext or ciphertext AS-02 file:
44      JPEG 2000 codestreams
45      PCM audio streams
46
47  o Read essence from a plaintext or ciphertext AS-02 file:
48      JPEG 2000 codestreams
49      PCM audio streams
50
51  o Read header metadata from an AS-02 file
52
53 NOTE: ciphertext support for clip-wrapped PCM is not yet complete.
54 */
55
56 #ifndef _AS_02_H_
57 #define _AS_02_H_
58
59 #include "Metadata.h"
60
61
62 namespace AS_02
63 {
64   using Kumu::Result_t;
65
66   KM_DECLARE_RESULT(AS02_FORMAT,        -116, "The file format is not proper OP-1a/AS-02.");
67
68   namespace MXF {
69     //
70     // reads distributed index tables and provides a uniform lookup with
71     // translated StreamOffest values (that is, StreamOffest is adjusted
72     // to the actual file position
73     class AS02IndexReader : public ASDCP::MXF::Partition
74     {
75       Kumu::ByteString m_IndexSegmentData;
76       ui64_t m_Duration;
77       ui32_t m_BytesPerEditUnit;
78
79       Result_t InitFromBuffer(const byte_t* p, ui32_t l, const ui64_t& body_offset, const ui64_t& essence_container_offset);
80
81       ASDCP_NO_COPY_CONSTRUCT(AS02IndexReader);
82       AS02IndexReader();
83           
84     public:
85       ASDCP::IPrimerLookup *m_Lookup;
86     
87       AS02IndexReader(const ASDCP::Dictionary*);
88       virtual ~AS02IndexReader();
89     
90       Result_t InitFromFile(const Kumu::IFileReader& reader, const ASDCP::MXF::RIP& rip, const bool has_header_essence);
91       ui64_t GetDuration() const;
92       void     Dump(FILE* = 0);
93       Result_t GetMDObjectByID(const Kumu::UUID&, ASDCP::MXF::InterchangeObject** = 0);
94       Result_t GetMDObjectByType(const byte_t*, ASDCP::MXF::InterchangeObject** = 0);
95       Result_t GetMDObjectsByType(const byte_t* ObjectID, std::list<ASDCP::MXF::InterchangeObject*>& ObjectList);
96       Result_t Lookup(ui32_t frame_num, ASDCP::MXF::IndexTableSegment::IndexEntry&) const;
97     };
98
99     
100     // Returns size in bytes of a single sample of data described by ADesc
101     inline ui32_t CalcSampleSize(const ASDCP::MXF::WaveAudioDescriptor& d)
102     {
103       return (d.QuantizationBits / 8) * d.ChannelCount;
104     }
105
106       // Returns number of samples per frame of data described by ADesc
107     inline ui32_t CalcSamplesPerFrame(const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate)
108     {
109       double tmpd = d.AudioSamplingRate.Quotient() / edit_rate.Quotient();
110       return (ui32_t)ceil(tmpd);
111     }
112
113     // Returns the size in bytes of a frame of data described by ADesc
114     inline ui32_t CalcFrameBufferSize(const ASDCP::MXF::WaveAudioDescriptor& d, const ASDCP::Rational& edit_rate)
115     {
116       return CalcSampleSize(d) * CalcSamplesPerFrame(d, edit_rate);
117     }
118
119     // Returns number of frames for data described by ADesc, given a duration in samples and an edit rate
120     inline ui32_t CalcFramesFromDurationInSamples(const ui32_t duration_samples, const ASDCP::MXF::WaveAudioDescriptor& d,
121                                                   const ASDCP::Rational& edit_rate)
122     {
123       ui32_t spf = CalcSamplesPerFrame(d, edit_rate);
124       ui32_t frames = duration_samples / spf;
125       
126       if ( duration_samples % spf != 0 )
127         {
128           ++frames;
129         }
130
131       return frames;
132     }
133
134   } // namespace MXF
135
136
137   // IMF App 2 edit rates not already exposed in namespace ASDCP
138   const ASDCP::Rational EditRate_29_97 = ASDCP::Rational(30000, 1001);
139   const ASDCP::Rational EditRate_59_94 = ASDCP::Rational(60000, 1001);
140
141   //---------------------------------------------------------------------------------
142   // Accessors in the MXFReader and MXFWriter classes below return these types to
143   // provide direct access to MXF metadata structures declared in MXF.h and Metadata.h
144
145   // See ST 2067-5 Sec. x.y.z
146   enum IndexStrategy_t
147   {
148     IS_LEAD,
149     IS_FOLLOW,
150     IS_FILE_SPECIFIC,
151     IS_MAX
152   };
153  
154   namespace JP2K
155   { 
156     //
157     class MXFWriter
158     {
159       class h__Writer;
160       ASDCP::mem_ptr<h__Writer> m_Writer;
161       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
162       
163     public:
164       MXFWriter();
165       virtual ~MXFWriter();
166
167       // Warning: direct manipulation of MXF structures can interfere
168       // with the normal operation of the wrapper.  Caveat emptor!
169       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
170       virtual ASDCP::MXF::RIP& RIP();
171
172       // Open the file for writing. The file must not exist. Returns error if
173       // the operation cannot be completed or if nonsensical data is discovered
174       // in the essence descriptor.
175       Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
176                          ASDCP::MXF::FileDescriptor* essence_descriptor,
177                          ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list,
178                          const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384,
179                          const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10);
180
181       // Writes a frame of essence to the MXF file. If the optional AESEncContext
182       // argument is present, the essence is encrypted prior to writing.
183       // Fails if the file is not open, is finalized, or an operating system
184       // error occurs.
185       Result_t WriteFrame(const ASDCP::JP2K::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
186
187       // Closes the MXF file, writing the index and revised header.
188       Result_t Finalize();
189     };
190
191     //
192     class MXFReader
193     {
194       class h__Reader;
195       ASDCP::mem_ptr<h__Reader> m_Reader;
196       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
197
198     public:
199       MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory);
200       virtual ~MXFReader();
201
202       // Warning: direct manipulation of MXF structures can interfere
203       // with the normal operation of the wrapper.  Caveat emptor!
204       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
205       virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
206       virtual ASDCP::MXF::RIP& RIP();
207
208       // Open the file for reading. The file must exist. Returns error if the
209       // operation cannot be completed.
210       Result_t OpenRead(const std::string& filename) const;
211
212       // Returns RESULT_INIT if the file is not open.
213       Result_t Close() const;
214
215       // Fill a WriterInfo struct with the values from the file's header.
216       // Returns RESULT_INIT if the file is not open.
217       Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
218
219       // Reads a frame of essence from the MXF file. If the optional AESEncContext
220       // argument is present, the essence is decrypted after reading. If the MXF
221       // file is encrypted and the AESDecContext argument is NULL, the frame buffer
222       // will contain the ciphertext frame data. If the HMACContext argument is
223       // not NULL, the HMAC will be calculated (if the file supports it).
224       // Returns RESULT_INIT if the file is not open, failure if the frame number is
225       // out of range, or if optional decrypt or HAMC operations fail.
226       Result_t ReadFrame(ui32_t frame_number, ASDCP::JP2K::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
227
228       // Print debugging information to stream
229       void     DumpHeaderMetadata(FILE* = 0) const;
230       void     DumpIndex(FILE* = 0) const;
231     };
232     
233   } //namespace JP2K
234   
235
236   //---------------------------------------------------------------------------------
237   //
238   namespace PCM
239   {
240     // see AS_DCP.h for related data types
241
242     // An AS-02 PCM file is clip-wrapped, but the interface defined below mimics that used
243     // for frame-wrapped essence elsewhere in this library.  The concept of frame rate
244     // therefore is only relevant to these classes and is not reflected in or affected by
245     // the contents of the MXF file.  The frame rate that is set on the writer is only
246     // for compatibility with the existing parsers, samples are packed contiguously into
247     // the same clip-wrapped packet.  Similarly, the edit rate must be set when initializing
248     // the reader to signal the number of samples to be read by each call to ReadFrame();
249
250     //
251       class MXFWriter
252     {
253       class h__Writer;
254       ASDCP::mem_ptr<h__Writer> m_Writer;
255       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
256
257     public:
258       MXFWriter();
259       virtual ~MXFWriter();
260
261       // Warning: direct manipulation of MXF structures can interfere
262       // with the normal operation of the wrapper.  Caveat emptor!
263       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
264       virtual ASDCP::MXF::RIP& RIP();
265
266       // Open the file for writing. The file must not exist. Returns error if
267       // the operation cannot be completed or if nonsensical data is discovered
268       // in the essence descriptor.
269       Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
270                          ASDCP::MXF::FileDescriptor* essence_descriptor,
271                          ASDCP::MXF::InterchangeObject_list_t& essence_sub_descriptor_list,
272                          const ASDCP::Rational& edit_rate, ui32_t HeaderSize = 16384);
273
274       // Writes a frame of essence to the MXF file. If the optional AESEncContext
275       // argument is present, the essence is encrypted prior to writing.
276       // Fails if the file is not open, is finalized, or an operating system
277       // error occurs.
278       Result_t WriteFrame(const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
279       
280       // Closes the MXF file, writing the index and revised header.
281       Result_t Finalize();
282     };
283
284     //
285     class MXFReader
286     {
287       class h__Reader;
288       ASDCP::mem_ptr<h__Reader> m_Reader;
289       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
290
291     public:
292       MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory);
293       virtual ~MXFReader();
294
295       // Warning: direct manipulation of MXF structures can interfere
296       // with the normal operation of the wrapper.  Caveat emptor!
297       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
298       virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
299       virtual ASDCP::MXF::RIP& RIP();
300
301       // Open the file for reading. The file must exist. Returns error if the
302       // operation cannot be completed.
303       Result_t OpenRead(const std::string& filename, const ASDCP::Rational& EditRate) const;
304
305       // Returns RESULT_INIT if the file is not open.
306       Result_t Close() const;
307
308       // Fill a WriterInfo struct with the values from the file's header.
309       // Returns RESULT_INIT if the file is not open.
310       Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
311
312       // Reads a frame of essence from the MXF file. If the optional AESEncContext
313       // argument is present, the essence is decrypted after reading. If the MXF
314       // file is encrypted and the AESDecContext argument is NULL, the frame buffer
315       // will contain the ciphertext frame data. If the HMACContext argument is
316       // not NULL, the HMAC will be calculated (if the file supports it).
317       // Returns RESULT_INIT if the file is not open, failure if the frame number is
318       // out of range, or if optional decrypt or HAMC operations fail.
319       Result_t ReadFrame(ui32_t frame_number, ASDCP::PCM::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
320       
321       // Print debugging information to stream
322       void     DumpHeaderMetadata(FILE* = 0) const;
323       void     DumpIndex(FILE* = 0) const;
324     };
325   } // namespace PCM
326
327   //---------------------------------------------------------------------------------
328   //
329   namespace TimedText
330     {
331       using ASDCP::TimedText::TimedTextDescriptor;
332       using ASDCP::TimedText::TimedTextResourceDescriptor;
333       using ASDCP::TimedText::ResourceList_t;
334
335       //
336       class Type5UUIDFilenameResolver : public ASDCP::TimedText::IResourceResolver
337         {
338           typedef std::map<Kumu::UUID, std::string> ResourceMap;
339             
340           ResourceMap m_ResourceMap;
341           std::string m_Dirname;
342           KM_NO_COPY_CONSTRUCT(Type5UUIDFilenameResolver);
343
344         public:
345           Type5UUIDFilenameResolver();
346           virtual ~Type5UUIDFilenameResolver();
347           Result_t OpenRead(const std::string& dirname);
348           Result_t ResolveRID(const byte_t* uuid, ASDCP::TimedText::FrameBuffer& FrameBuf) const;
349         };
350       
351
352       // Generate UUID asset ID values from file contents
353       Kumu::UUID CreatePNGNameId(const std::string& image_name);
354       Kumu::UUID CreateFontNameId(const std::string& font_name);
355
356       //
357       class ST2052_TextParser
358         {
359           class h__TextParser;
360           ASDCP::mem_ptr<h__TextParser> m_Parser;
361           ASDCP_NO_COPY_CONSTRUCT(ST2052_TextParser);
362
363         public:
364           ST2052_TextParser();
365           virtual ~ST2052_TextParser();
366
367           // Opens an XML file for reading, parses data to provide a complete
368           // set of stream metadata for the MXFWriter below.
369           Result_t OpenRead(const std::string& filename) const;
370
371           // Parse an XML string 
372           Result_t OpenRead(const std::string& xml_doc, const std::string& filename) const;
373
374           // The "profile_name" parameter was removed from OpenRead() because it made the API
375           // awkward WRT lexical compatibility with TimedText_Parser. The value can still be
376           // modified by changing the descriptor's NamespaceName property after the call to
377           // FillTimedTextDescriptor() has set it.
378                               
379           // Fill a TimedTextDescriptor struct with the values from the file's contents.
380           // Returns RESULT_INIT if the file is not open.
381           Result_t FillTimedTextDescriptor(ASDCP::TimedText::TimedTextDescriptor&) const;
382
383           // Reads the complete Timed Text Resource into the given string.
384           Result_t ReadTimedTextResource(std::string&) const;
385
386           // Reads the Ancillary Resource having the given ID. Fails if the buffer
387           // is too small or the resource does not exist. The optional Resolver
388           // argument can be provided which will be used to retrieve the resource
389           // having a particulat UUID. If a Resolver is not supplied, the default
390           // internal resolver will return the contents of the file having the UUID
391           // as the filename. The filename must exist in the same directory as the
392           // XML file opened with OpenRead().
393           Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer&,
394                                          const ASDCP::TimedText::IResourceResolver* Resolver = 0) const;
395         };
396
397       //
398       class MXFWriter
399         {
400           class h__Writer;
401           ASDCP::mem_ptr<h__Writer> m_Writer;
402           ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
403
404         public:
405           MXFWriter();
406           virtual ~MXFWriter();
407
408           // Warning: direct manipulation of MXF structures can interfere
409           // with the normal operation of the wrapper.  Caveat emptor!
410           virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
411           virtual ASDCP::MXF::RIP& RIP();
412
413           // Open the file for writing. The file must not exist. Returns error if
414           // the operation cannot be completed or if nonsensical data is discovered
415           // in the essence descriptor.
416           Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
417                              const ASDCP::TimedText::TimedTextDescriptor&, ui32_t HeaderSize = 16384);
418
419           // Writes the Timed-Text Resource to the MXF file. The file must be UTF-8
420           // encoded. If the optional AESEncContext argument is present, the essence
421           // is encrypted prior to writing. Fails if the file is not open, is finalized,
422           // or an operating system error occurs.
423           // This method may only be called once, and it must be called before any
424           // call to WriteAncillaryResource(). RESULT_STATE will be returned if these
425           // conditions are not met.
426           Result_t WriteTimedTextResource(const std::string& XMLDoc, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
427
428           // Writes an Ancillary Resource to the MXF file. If the optional AESEncContext
429           // argument is present, the essence is encrypted prior to writing.
430           // Fails if the file is not open, is finalized, or an operating system
431           // error occurs. RESULT_STATE will be returned if the method is called before
432           // WriteTimedTextResource()
433           Result_t WriteAncillaryResource(const ASDCP::TimedText::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
434
435           // Closes the MXF file, writing the index and revised header.
436           Result_t Finalize();
437         };
438
439       //
440       class MXFReader
441         {
442           class h__Reader;
443           ASDCP::mem_ptr<h__Reader> m_Reader;
444           ASDCP_NO_COPY_CONSTRUCT(MXFReader);
445
446     public:
447           MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory);
448           virtual ~MXFReader();
449
450           // Warning: direct manipulation of MXF structures can interfere
451           // with the normal operation of the wrapper.  Caveat emptor!
452           virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
453           virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
454           virtual ASDCP::MXF::RIP& RIP();
455
456           // Open the file for reading. The file must exist. Returns error if the
457           // operation cannot be completed.
458           Result_t OpenRead(const std::string& filename) const;
459
460           // Returns RESULT_INIT if the file is not open.
461           Result_t Close() const;
462
463           // Fill a TimedTextDescriptor struct with the values from the file's header.
464           // Returns RESULT_INIT if the file is not open.
465           Result_t FillTimedTextDescriptor(ASDCP::TimedText::TimedTextDescriptor&) const;
466
467           // Fill a WriterInfo struct with the values from the file's header.
468           // Returns RESULT_INIT if the file is not open.
469           Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
470
471           // Reads the complete Timed Text Resource into the given string. Fails if the resource
472           // is encrypted and AESDecContext is NULL (use the following method to retrieve the
473           // raw ciphertet block).
474           Result_t ReadTimedTextResource(std::string&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
475
476           // Reads the complete Timed Text Resource from the MXF file. If the optional AESEncContext
477           // argument is present, the resource is decrypted after reading. If the MXF
478           // file is encrypted and the AESDecContext argument is NULL, the frame buffer
479           // will contain the ciphertext frame data. If the HMACContext argument is
480           // not NULL, the HMAC will be calculated (if the file supports it).
481           // Returns RESULT_INIT if the file is not open, failure if the frame number is
482           // out of range, or if optional decrypt or HAMC operations fail.
483           Result_t ReadTimedTextResource(ASDCP::TimedText::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
484
485           // Reads the timed-text resource having the given UUID from the MXF file. If the
486           // optional AESEncContext argument is present, the resource is decrypted after
487           // reading. If the MXF file is encrypted and the AESDecContext argument is NULL,
488           // the frame buffer will contain the ciphertext frame data. If the HMACContext
489           // argument is not NULL, the HMAC will be calculated (if the file supports it).
490           // Returns RESULT_INIT if the file is not open, failure if the frame number is
491           // out of range, or if optional decrypt or HAMC operations fail.
492           Result_t ReadAncillaryResource(const Kumu::UUID&, ASDCP::TimedText::FrameBuffer&, ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
493
494           // Print debugging information to stream
495           void     DumpHeaderMetadata(FILE* = 0) const;
496           void     DumpIndex(FILE* = 0) const;
497         };
498     } // namespace TimedText
499
500   namespace ISXD
501   { 
502     //
503     class MXFWriter
504     {
505       class h__Writer;
506       ASDCP::mem_ptr<h__Writer> m_Writer;
507       ASDCP_NO_COPY_CONSTRUCT(MXFWriter);
508       
509     public:
510       MXFWriter();
511       virtual ~MXFWriter();
512
513       // Warning: direct manipulation of MXF structures can interfere
514       // with the normal operation of the wrapper.  Caveat emptor!
515       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
516       virtual ASDCP::MXF::RIP& RIP();
517
518       // Open the file for writing. The file must not exist. Returns error if
519       // the operation cannot be completed or if nonsensical data is discovered
520       // in the essence descriptor.
521       Result_t OpenWrite(const std::string& filename, const ASDCP::WriterInfo&,
522                          const std::string& isxd_document_namespace,
523                          const ASDCP::Rational& edit_rate, const ui32_t& header_size = 16384,
524                          const IndexStrategy_t& strategy = IS_FOLLOW, const ui32_t& partition_space = 10);
525
526       // Writes a frame of essence to the MXF file. If the optional AESEncContext
527       // argument is present, the essence is encrypted prior to writing.
528       // Fails if the file is not open, is finalized, or an operating system
529       // error occurs.
530       Result_t WriteFrame(const ASDCP::FrameBuffer&, ASDCP::AESEncContext* = 0, ASDCP::HMACContext* = 0);
531
532       // Writes an XML text document to the MXF file as per RP 2057. If the
533       // optional AESEncContext argument is present, the document is encrypted
534       // prior to writing. Fails if the file is not open, is finalized, or an
535       // operating system error occurs.
536       Result_t AddDmsGenericPartUtf8Text(const ASDCP::FrameBuffer& frame_buffer, ASDCP::AESEncContext* enc = 0, ASDCP::HMACContext* hmac = 0);
537
538       // Closes the MXF file, writing the index and revised header.
539       Result_t Finalize();
540     };
541
542     //
543     class MXFReader
544     {
545       class h__Reader;
546       ASDCP::mem_ptr<h__Reader> m_Reader;
547       ASDCP_NO_COPY_CONSTRUCT(MXFReader);
548
549     public:
550       MXFReader(const Kumu::IFileReaderFactory& fileReaderFactory);
551       virtual ~MXFReader();
552
553       // Warning: direct manipulation of MXF structures can interfere
554       // with the normal operation of the wrapper.  Caveat emptor!
555       virtual ASDCP::MXF::OP1aHeader& OP1aHeader();
556       virtual AS_02::MXF::AS02IndexReader& AS02IndexReader();
557       virtual ASDCP::MXF::RIP& RIP();
558
559       // Open the file for reading. The file must exist. Returns error if the
560       // operation cannot be completed.
561       Result_t OpenRead(const std::string& filename) const;
562
563       // Returns RESULT_INIT if the file is not open.
564       Result_t Close() const;
565
566       // Fill a WriterInfo struct with the values from the file's header.
567       // Returns RESULT_INIT if the file is not open.
568       Result_t FillWriterInfo(ASDCP::WriterInfo&) const;
569
570       // Reads a frame of essence from the MXF file. If the optional AESEncContext
571       // argument is present, the essence is decrypted after reading. If the MXF
572       // file is encrypted and the AESDecContext argument is NULL, the frame buffer
573       // will contain the ciphertext frame data. If the HMACContext argument is
574       // not NULL, the HMAC will be calculated (if the file supports it).
575       // Returns RESULT_INIT if the file is not open, failure if the frame number is
576       // out of range, or if optional decrypt or HAMC operations fail.
577       Result_t ReadFrame(ui32_t frame_number, ASDCP::FrameBuffer&,
578                          ASDCP::AESDecContext* = 0, ASDCP::HMACContext* = 0) const;
579
580       // Reads a Generic Stream Partition payload. Returns RESULT_INIT if the file is
581       // not open, or RESULT_FORMAT if the SID is not present in the  RIP, or if the
582       // actual partition at ByteOffset does not have a matching BodySID value.
583       // Encryption is not currently supported.
584       Result_t ReadGenericStreamPartitionPayload(ui32_t SID, ASDCP::FrameBuffer& FrameBuf);
585   
586       // Print debugging information to stream
587       void     DumpHeaderMetadata(FILE* = 0) const;
588       void     DumpIndex(FILE* = 0) const;
589     };
590     
591   }
592
593 } // namespace AS_02
594
595 #endif // _AS_02_H_
596
597 //
598 // end AS_02.h
599 //