Commit a bunch of portability fixes (64- vs. 32-bit types).
[asdcplib.git] / src / AS_DCP_JP2K.cpp
index 8f771739ffb8b6865aca548c3a84871b49692ea8..39dceedd72b4e681f93bdfe39f8108911e0dc62d 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2007, John Hurst
+Copyright (c) 2004-2008, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "AS_DCP_internal.h"
 
 using namespace ASDCP::JP2K;
-
+using Kumu::GenRandomValue;
 
 //------------------------------------------------------------------------------------------
 
@@ -84,7 +84,8 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream)
   fprintf(stream, "    ImageComponents:\n");
   fprintf(stream, "  bits  h-sep v-sep\n");
 
-  for ( ui32_t i = 0; i < PDesc.Csize; i++ )
+  ui32_t i;
+  for ( i = 0; i < PDesc.Csize; i++ )
     {
       fprintf(stream, "  %4d  %5d %5d\n",
              PDesc.ImageComponents[i].Ssize + 1, // See ISO 15444-1, Table A11, for the origin of '+1'
@@ -106,7 +107,7 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream)
   fprintf(stream, "     Transformation: %hd\n", PDesc.CodingStyleDefault.SPcod.Transformation);
 
 
-  ui32_t precinct_set_size = 0, i;
+  ui32_t precinct_set_size = 0;
 
   for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ )
     precinct_set_size++;
@@ -159,7 +160,8 @@ lh__Reader::MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDesc)
   MXF::RGBAEssenceDescriptor* PDescObj = (MXF::RGBAEssenceDescriptor*)m_EssenceDescriptor;
 
   PDesc.EditRate           = m_EditRate;
-  PDesc.ContainerDuration  = PDescObj->ContainerDuration;
+  assert(PDescObj->ContainerDuration <= 0xFFFFFFFFL);
+  PDesc.ContainerDuration  = (ui32_t) PDescObj->ContainerDuration;
   PDesc.StoredWidth        = PDescObj->StoredWidth;
   PDesc.StoredHeight       = PDescObj->StoredHeight;
   PDesc.AspectRatio        = PDescObj->AspectRatio;
@@ -225,7 +227,7 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type)
 
       if ( ObjectList.empty() )
        {
-         DefaultLogSink().Error("MXF Metadata contains no Track Sets\n");
+         DefaultLogSink().Error("MXF Metadata contains no Track Sets.\n");
          return RESULT_FORMAT;
        }
 
@@ -235,16 +237,23 @@ lh__Reader::OpenRead(const char* filename, EssenceType_t type)
        {
          if ( m_EditRate != m_EssenceDescriptor->SampleRate )
            {
-             DefaultLogSink().Error("EditRate and SampleRate do not match (%.03f, %.03f)\n",
+             DefaultLogSink().Error("EditRate and SampleRate do not match (%.03f, %.03f).\n",
                                     m_EditRate.Quotient(), m_EssenceDescriptor->SampleRate.Quotient());
-             return RESULT_SFORMAT;
+             
+             if ( m_EditRate == EditRate_24 && m_EssenceDescriptor->SampleRate == EditRate_48 )
+               {
+                 DefaultLogSink().Error("File may contain JPEG Interop stereoscopic images.\n");
+                 return RESULT_SFORMAT;
+               }
+
+             return RESULT_FORMAT;
            }
        }
       else if ( type == ASDCP::ESS_JPEG_2000_S )
        {
          if ( ! ( m_EditRate == EditRate_24 && m_EssenceDescriptor->SampleRate == EditRate_48 ) )
            {
-             DefaultLogSink().Error("EditRate and SampleRate not correct for 24/48 stereoscopic essence\n");
+             DefaultLogSink().Error("EditRate and SampleRate not correct for 24/48 stereoscopic essence.\n");
              return RESULT_FORMAT;
            }
        }
@@ -484,6 +493,23 @@ ASDCP::JP2K::MXFSReader::OpenRead(const char* filename) const
   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,
@@ -495,7 +521,6 @@ ASDCP::JP2K::MXFSReader::ReadFrame(ui32_t FrameNum, StereoscopicPhase_t phase, F
   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
@@ -784,14 +809,12 @@ ASDCP::JP2K::MXFWriter::OpenWrite(const char* filename, const WriterInfo& Info,
                                  const PictureDescriptor& PDesc, ui32_t HeaderSize)
 {
   m_Writer = new h__Writer;
-  
+  m_Writer->m_Info = Info;
+
   Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000, HeaderSize);
 
   if ( ASDCP_SUCCESS(result) )
-    {
-      m_Writer->m_Info = Info;
-      result = m_Writer->SetSourceStream(PDesc, JP2K_PACKAGE_LABEL);
-    }
+    result = m_Writer->SetSourceStream(PDesc, JP2K_PACKAGE_LABEL);
 
   if ( ASDCP_FAILURE(result) )
     m_Writer.release();
@@ -889,11 +912,15 @@ ASDCP::JP2K::MXFSWriter::OpenWrite(const char* filename, const WriterInfo& Info,
       return RESULT_FORMAT;
     }
 
+  if ( PDesc.StoredWidth > 2048 )
+    DefaultLogSink().Warn("Wrapping non-standard 4K stereoscopic content. I hope you know what you are doing!\n");
+
+  m_Writer->m_Info = Info;
+
   Result_t result = m_Writer->OpenWrite(filename, ASDCP::ESS_JPEG_2000_S, HeaderSize);
 
   if ( ASDCP_SUCCESS(result) )
     {
-      m_Writer->m_Info = Info;
       PictureDescriptor TmpPDesc = PDesc;
       TmpPDesc.EditRate = ASDCP::EditRate_48;
 
@@ -906,6 +933,19 @@ ASDCP::JP2K::MXFSWriter::OpenWrite(const char* filename, const WriterInfo& Info,
   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.