/*
-Copyright (c) 2003-2007, John Hurst
+Copyright (c) 2003-2008, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
// in file format, and if no changes were made to AS_DCP.h, the new version would be
// 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
const ui32_t VERSION_MAJOR = 1;
- const ui32_t VERSION_APIMINOR = 2;
- const ui32_t VERSION_IMPMINOR = 17;
+ const ui32_t VERSION_APIMINOR = 3;
+ const ui32_t VERSION_IMPMINOR = 18;
const char* Version();
// UUIDs are passed around as strings of UUIDlen bytes
Result_t FillPictureDescriptor(PictureDescriptor&) const;
};
+ // Parses the data in the frame buffer to fill in the picture descriptor. Copies
+ // the offset of the image data into start_of_data. Returns error if the parser fails.
+ Result_t ParseMetadataIntoDesc(const FrameBuffer&, PictureDescriptor&, byte_t* start_of_data = 0);
+
// An object which reads a sequence of files containing JPEG 2000 pictures.
class SequenceParser
{
SP_LEFT,
SP_RIGHT
};
+
+ struct SFrameBuffer
+ {
+ JP2K::FrameBuffer Left;
+ JP2K::FrameBuffer Right;
+ SFrameBuffer(ui32_t size) {
+ Left.Capacity(size);
+ Right.Capacity(size);
+ }
+ };
class MXFSWriter
- {
+ {
class h__SWriter;
mem_ptr<h__SWriter> m_Writer;
ASDCP_NO_COPY_CONSTRUCT(MXFSWriter);
Result_t OpenWrite(const char* filename, const WriterInfo&,
const PictureDescriptor&, ui32_t HeaderSize = 16384);
+ // Writes a pair of frames of essence to the MXF file. If the optional AESEncContext
+ // argument is present, the essence is encrypted prior to writing.
+ // Fails if the file is not open, is finalized, or an operating system
+ // error occurs.
+ Result_t WriteFrame(const SFrameBuffer&, AESEncContext* = 0, HMACContext* = 0);
+
// Writes a frame of essence to the MXF file. If the optional AESEncContext
// argument is present, the essence is encrypted prior to writing.
// Fails if the file is not open, is finalized, or an operating system
// Returns RESULT_INIT if the file is not open.
Result_t FillWriterInfo(WriterInfo&) const;
+ // Reads a pair of frames of essence from the MXF file. If the optional AESEncContext
+ // argument is present, the essence is decrypted after reading. If the MXF
+ // file is encrypted and the AESDecContext argument is NULL, the frame buffer
+ // will contain the ciphertext frame data. If the HMACContext argument is
+ // not NULL, the HMAC will be calculated (if the file supports it).
+ // Returns RESULT_INIT if the file is not open, failure if the frame number is
+ // out of range, or if optional decrypt or HAMC operations fail.
+ Result_t ReadFrame(ui32_t frame_number, SFrameBuffer&, AESDecContext* = 0, HMACContext* = 0) const;
+
// Reads a frame of essence from the MXF file. If the optional AESEncContext
// argument is present, the essence is decrypted after reading. If the MXF
// file is encrypted and the AESDecContext argument is NULL, the frame buffer
return m_Reader->OpenRead(filename, ASDCP::ESS_JPEG_2000_S);
}
+//
+ASDCP::Result_t
+ASDCP::JP2K::MXFSReader::ReadFrame(ui32_t FrameNum, SFrameBuffer& FrameBuf, AESDecContext* Ctx, HMACContext* HMAC) const
+{
+ Result_t result = RESULT_INIT;
+
+ if ( m_Reader && m_Reader->m_File.IsOpen() )
+ {
+ result = m_Reader->ReadFrame(FrameNum, SP_LEFT, FrameBuf.Left, Ctx, HMAC);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = m_Reader->ReadFrame(FrameNum, SP_RIGHT, FrameBuf.Right, Ctx, HMAC);
+ }
+
+ return result;
+}
+
//
ASDCP::Result_t
ASDCP::JP2K::MXFSReader::ReadFrame(ui32_t FrameNum, StereoscopicPhase_t phase, FrameBuffer& FrameBuf,
return RESULT_INIT;
}
-
// Fill the struct with the values from the file's header.
// Returns RESULT_INIT if the file is not open.
ASDCP::Result_t
return result;
}
+ASDCP::Result_t
+ASDCP::JP2K::MXFSWriter::WriteFrame(const SFrameBuffer& FrameBuf, AESEncContext* Ctx, HMACContext* HMAC)
+{
+ if ( m_Writer.empty() )
+ return RESULT_INIT;
+
+ Result_t result = m_Writer->WriteFrame(FrameBuf.Left, SP_LEFT, Ctx, HMAC);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = m_Writer->WriteFrame(FrameBuf.Right, SP_RIGHT, Ctx, HMAC);
+
+ return result;
+}
// Writes a frame of essence to the MXF file. If the optional AESEncContext
// argument is present, the essence is encrypted prior to writing.
/*
-Copyright (c) 2004-2006, John Hurst
+Copyright (c) 2004-2008, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
if ( ASDCP_SUCCESS(result) )
{
- Marker NextMarker;
- ui32_t i;
- const byte_t* p = FB.RoData();
- const byte_t* end_p = p + FB.Size();
+ byte_t start_of_data = 0; // out param
+ result = ParseMetadataIntoDesc(FB, m_PDesc, &start_of_data);
- while ( p < end_p && ASDCP_SUCCESS(result) )
- {
- result = GetNextMarker(&p, NextMarker);
-
- if ( ASDCP_FAILURE(result) )
- {
- result = RESULT_RAW_ESS;
- break;
- }
-
- switch ( NextMarker.m_Type )
- {
- case MRK_SOD:
- FB.PlaintextOffset(p - FB.RoData());
- p = end_p;
- break;
-
- case MRK_SIZ:
- {
- Accessor::SIZ SIZ_(NextMarker);
- m_PDesc.StoredWidth = SIZ_.Xsize();
- m_PDesc.StoredHeight = SIZ_.Ysize();
- m_PDesc.AspectRatio = Rational(SIZ_.Xsize(), SIZ_.Ysize());
- m_PDesc.Rsize = SIZ_.Rsize();
- m_PDesc.Xsize = SIZ_.Xsize();
- m_PDesc.Ysize = SIZ_.Ysize();
- m_PDesc.XOsize = SIZ_.XOsize();
- m_PDesc.YOsize = SIZ_.YOsize();
- m_PDesc.XTsize = SIZ_.XTsize();
- m_PDesc.YTsize = SIZ_.YTsize();
- m_PDesc.XTOsize = SIZ_.XTOsize();
- m_PDesc.YTOsize = SIZ_.YTOsize();
- m_PDesc.Csize = SIZ_.Csize();
-
- if ( m_PDesc.Csize != 3 )
- {
- DefaultLogSink().Error("Unexpected number of components: %u\n", m_PDesc.Csize);
- return RESULT_RAW_FORMAT;
- }
-
- for ( i = 0; i < m_PDesc.Csize; i++ )
- SIZ_.ReadComponent(i, m_PDesc.ImageComponents[i]);
- }
- break;
-
- case MRK_COD:
- memset(&m_PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t));
-
- if ( NextMarker.m_DataSize > sizeof(CodingStyleDefault_t) )
- {
- DefaultLogSink().Error("Unexpectedly large CodingStyle data: %u\n", NextMarker.m_DataSize);
- return RESULT_RAW_FORMAT;
- }
-
- memcpy(&m_PDesc.CodingStyleDefault, NextMarker.m_Data, NextMarker.m_DataSize);
- break;
-
- case MRK_QCD:
- memset(&m_PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t));
-
- if ( NextMarker.m_DataSize < 16 )
- {
- DefaultLogSink().Error("No quantization signaled\n");
- return RESULT_RAW_FORMAT;
- }
-
- if ( NextMarker.m_DataSize > MaxDefaults )
- {
- DefaultLogSink().Error("Quantization Default length exceeds maximum %d\n", NextMarker.m_DataSize);
- return RESULT_RAW_FORMAT;
- }
-
- memcpy(&m_PDesc.QuantizationDefault, NextMarker.m_Data, NextMarker.m_DataSize);
- m_PDesc.QuantizationDefault.SPqcdLength = NextMarker.m_DataSize - 1;
- break;
- }
- }
+ if ( ASDCP_SUCCESS(result) )
+ FB.PlaintextOffset(start_of_data);
}
return result;
}
};
+ASDCP::Result_t
+ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDesc, byte_t* start_of_data)
+{
+ Result_t result = RESULT_OK;
+ Marker NextMarker;
+ ui32_t i;
+ const byte_t* p = FB.RoData();
+ const byte_t* end_p = p + FB.Size();
+
+ while ( p < end_p && ASDCP_SUCCESS(result) )
+ {
+ result = GetNextMarker(&p, NextMarker);
+
+ if ( ASDCP_FAILURE(result) )
+ {
+ result = RESULT_RAW_ESS;
+ break;
+ }
+
+ switch ( NextMarker.m_Type )
+ {
+ case MRK_SOD:
+ if ( start_of_data != 0 )
+ *start_of_data = p - FB.RoData();
+
+ p = end_p;
+ break;
+
+ case MRK_SIZ:
+ {
+ Accessor::SIZ SIZ_(NextMarker);
+ PDesc.StoredWidth = SIZ_.Xsize();
+ PDesc.StoredHeight = SIZ_.Ysize();
+ PDesc.AspectRatio = Rational(SIZ_.Xsize(), SIZ_.Ysize());
+ PDesc.Rsize = SIZ_.Rsize();
+ PDesc.Xsize = SIZ_.Xsize();
+ PDesc.Ysize = SIZ_.Ysize();
+ PDesc.XOsize = SIZ_.XOsize();
+ PDesc.YOsize = SIZ_.YOsize();
+ PDesc.XTsize = SIZ_.XTsize();
+ PDesc.YTsize = SIZ_.YTsize();
+ PDesc.XTOsize = SIZ_.XTOsize();
+ PDesc.YTOsize = SIZ_.YTOsize();
+ PDesc.Csize = SIZ_.Csize();
+
+ if ( PDesc.Csize != 3 )
+ {
+ DefaultLogSink().Error("Unexpected number of components: %u\n", PDesc.Csize);
+ return RESULT_RAW_FORMAT;
+ }
+
+ for ( i = 0; i < PDesc.Csize; i++ )
+ SIZ_.ReadComponent(i, PDesc.ImageComponents[i]);
+ }
+ break;
+
+ case MRK_COD:
+ memset(&PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t));
+
+ if ( NextMarker.m_DataSize > sizeof(CodingStyleDefault_t) )
+ {
+ DefaultLogSink().Error("Unexpectedly large CodingStyle data: %u\n", NextMarker.m_DataSize);
+ return RESULT_RAW_FORMAT;
+ }
+
+ memcpy(&PDesc.CodingStyleDefault, NextMarker.m_Data, NextMarker.m_DataSize);
+ break;
+
+ case MRK_QCD:
+ memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t));
+
+ if ( NextMarker.m_DataSize < 16 )
+ {
+ DefaultLogSink().Error("No quantization signaled\n");
+ return RESULT_RAW_FORMAT;
+ }
+
+ if ( NextMarker.m_DataSize > MaxDefaults )
+ {
+ DefaultLogSink().Error("Quantization Default length exceeds maximum %d\n", NextMarker.m_DataSize);
+ return RESULT_RAW_FORMAT;
+ }
+
+ memcpy(&PDesc.QuantizationDefault, NextMarker.m_Data, NextMarker.m_DataSize);
+ PDesc.QuantizationDefault.SPqcdLength = NextMarker.m_DataSize - 1;
+ break;
+ }
+ }
+
+ return result;
+}
+
//------------------------------------------------------------------------------------------
ASDCP::JP2K::CodestreamParser::CodestreamParser()