Added library names
[asdcplib.git] / src / JP2K_Sequence_Parser.cpp
index 5cb4e91adbfbbc20262f523c4b687788ff4f6e56..a0fd5d0b9c2fde47ac8143fe13a5cd5b1cd228b4 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2011, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <AS_DCP.h>
 #include <KM_fileio.h>
+#include <KM_log.h>
 #include <list>
 #include <string>
 #include <algorithm>
@@ -50,8 +51,15 @@ public:
   FileList() {}
   ~FileList() {}
 
+  const FileList& operator=(const std::list<std::string>& pathlist) {
+    std::list<std::string>::const_iterator i;
+    for ( i = pathlist.begin(); i != pathlist.end(); i++ )
+      push_back(*i);
+    return *this;
+  }
+
   //
-  Result_t InitFromDirectory(const char* path)
+  Result_t InitFromDirectory(const std::string& path)
   {
     char next_file[Kumu::MaxFilePath];
     Kumu::DirScanner Scanner;
@@ -70,7 +78,9 @@ public:
            std::string Str(m_DirName);
            Str += "/";
            Str += next_file;
-           push_back(Str);
+
+           if ( ! Kumu::PathIsDirectory(Str) )
+             push_back(Str);
          }
 
        sort();
@@ -89,13 +99,16 @@ class ASDCP::JP2K::SequenceParser::h__SequenceParser
   FileList           m_FileList;
   FileList::iterator m_CurrentFile;
   CodestreamParser   m_Parser;
+  bool               m_Pedantic;
+
+  Result_t OpenRead();
 
   ASDCP_NO_COPY_CONSTRUCT(h__SequenceParser);
 
 public:
   PictureDescriptor  m_PDesc;
 
-  h__SequenceParser() : m_FramesRead(0)
+  h__SequenceParser() : m_FramesRead(0), m_Pedantic(false)
   {
     memset(&m_PDesc, 0, sizeof(m_PDesc));
     m_PDesc.EditRate = Rational(24,1); 
@@ -106,7 +119,8 @@ public:
     Close();
   }
 
-  Result_t OpenRead(const char* filename);
+  Result_t OpenRead(const std::string& filename, bool pedantic);
+  Result_t OpenRead(const std::list<std::string>& file_list, bool pedantic);
   void     Close() {}
 
   Result_t Reset()
@@ -122,48 +136,151 @@ public:
 
 //
 ASDCP::Result_t
-ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const char* filename)
+ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead()
 {
-  ASDCP_TEST_NULL_STR(filename);
-
-  Result_t result = m_FileList.InitFromDirectory(filename);
-
   if ( m_FileList.empty() )
     return RESULT_ENDOFFILE;
 
+  m_CurrentFile = m_FileList.begin();
+  CodestreamParser Parser;
+  FrameBuffer TmpBuffer;
+
+  Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str());
+
+  if ( file_size == 0 )
+    return RESULT_NOT_FOUND;
+
+  assert(file_size <= 0xFFFFFFFFL);
+  Result_t result = TmpBuffer.Capacity((ui32_t) file_size);
+
   if ( ASDCP_SUCCESS(result) )
-    {
-      m_CurrentFile = m_FileList.begin();
+    result = Parser.OpenReadFrame((*m_CurrentFile).c_str(), TmpBuffer);
+      
+  if ( ASDCP_SUCCESS(result) )
+    result = Parser.FillPictureDescriptor(m_PDesc);
 
-      CodestreamParser Parser;
-      FrameBuffer TmpBuffer;
+  // how big is it?
+  if ( ASDCP_SUCCESS(result) )
+    m_PDesc.ContainerDuration = m_FileList.size();
 
-      Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str());
+  return result;
+}
 
-      if ( file_size == 0 )
-       result = RESULT_NOT_FOUND;
+//
+ASDCP::Result_t
+ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const std::string& filename, bool pedantic)
+{
+  m_Pedantic = pedantic;
 
-      if ( ASDCP_SUCCESS(result) )
-       {
-         assert(file_size <= 0xFFFFFFFFL);
-         result = TmpBuffer.Capacity((ui32_t) file_size);
-       }
+  Result_t result = m_FileList.InitFromDirectory(filename);
 
-      if ( ASDCP_SUCCESS(result) )
-       result = Parser.OpenReadFrame((*m_CurrentFile).c_str(), TmpBuffer);
-      
-      if ( ASDCP_SUCCESS(result) )
-       result = Parser.FillPictureDescriptor(m_PDesc);
+  if ( ASDCP_SUCCESS(result) )
+    result = OpenRead();
 
-      // how big is it?
-      if ( ASDCP_SUCCESS(result) )
-       m_PDesc.ContainerDuration = m_FileList.size();
+  return result;
+}
+
+
+//
+ASDCP::Result_t
+ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const std::list<std::string>& file_list, bool pedantic)
+{
+  m_Pedantic = pedantic;
+  m_FileList = file_list;
+  return OpenRead();
+}
+
+
+//
+bool
+operator==(const ASDCP::JP2K::ImageComponent_t& lhs, const ASDCP::JP2K::ImageComponent_t& rhs)
+{
+  if ( lhs.Ssize != rhs.Ssize ) return false;
+  if ( lhs.XRsize != rhs.XRsize ) return false;
+  if ( lhs.YRsize != rhs.YRsize ) return false;
+  return true;
+}
+
+//
+bool
+operator==(const ASDCP::JP2K::QuantizationDefault_t& lhs, const ASDCP::JP2K::QuantizationDefault_t& rhs)
+{
+  if ( lhs.Sqcd != rhs.Sqcd ) return false;
+  if ( lhs.SPqcdLength != rhs.SPqcdLength ) return false;
+  
+  for ( ui32_t i = 0; i < JP2K::MaxDefaults; i++ )
+    {
+      if ( lhs.SPqcd[i] != rhs.SPqcd[i]  )
+       return false;
     }
 
-  return result;
+  return true;
 }
 
 //
+bool
+operator==(const ASDCP::JP2K::CodingStyleDefault_t& lhs, const ASDCP::JP2K::CodingStyleDefault_t& rhs)
+{
+  if ( lhs.Scod != rhs.Scod ) return false;
+
+  // SGcod
+  if ( lhs.SGcod.ProgressionOrder != rhs.SGcod.ProgressionOrder ) return false;
+  if ( lhs.SGcod.MultiCompTransform != rhs.SGcod.MultiCompTransform ) return false;
+
+  for ( ui32_t i = 0; i < sizeof(ui16_t); i++ )
+    {
+      if ( lhs.SGcod.NumberOfLayers[i] != lhs.SGcod.NumberOfLayers[i]  )
+       return false;
+    }
+
+  // SPcod
+  if ( lhs.SPcod.DecompositionLevels != rhs.SPcod.DecompositionLevels ) return false;
+  if ( lhs.SPcod.CodeblockWidth != rhs.SPcod.CodeblockWidth ) return false;
+  if ( lhs.SPcod.CodeblockHeight != rhs.SPcod.CodeblockHeight ) return false;
+  if ( lhs.SPcod.CodeblockStyle != rhs.SPcod.CodeblockStyle ) return false;
+  if ( lhs.SPcod.Transformation != rhs.SPcod.Transformation ) return false;
+  
+  for ( ui32_t i = 0; i < JP2K::MaxPrecincts; i++ )
+    {
+      if ( lhs.SPcod.PrecinctSize[i] != rhs.SPcod.PrecinctSize[i]  )
+       return false;
+    }
+
+  return true;
+}
+
+//
+bool
+operator==(const ASDCP::JP2K::PictureDescriptor& lhs, const ASDCP::JP2K::PictureDescriptor& rhs)
+{
+  if ( lhs.EditRate != rhs.EditRate ) return false;
+  //  if ( lhs.ContainerDuration != rhs.ContainerDuration ) return false;
+  if ( lhs.SampleRate != rhs.SampleRate ) return false;
+  if ( lhs.StoredWidth != rhs.StoredWidth ) return false;
+  if ( lhs.StoredHeight != rhs.StoredHeight ) return false;
+  if ( lhs.AspectRatio != rhs.AspectRatio ) return false;
+  if ( lhs.Rsize != rhs.Rsize ) return false;
+  if ( lhs.Xsize != rhs.Xsize ) return false;
+  if ( lhs.Ysize != rhs.Ysize ) return false;
+  if ( lhs.XOsize != rhs.XOsize ) return false;
+  if ( lhs.YOsize != rhs.YOsize ) return false;
+  if ( lhs.XTsize != rhs.XTsize ) return false;
+  if ( lhs.YTsize != rhs.YTsize ) return false;
+  if ( lhs.XTOsize != rhs.XTOsize ) return false;
+  if ( lhs.YTOsize != rhs.YTOsize ) return false;
+  if ( lhs.Csize != rhs.Csize ) return false;
+  if ( ! ( lhs.CodingStyleDefault == rhs.CodingStyleDefault ) ) return false;
+  if ( ! ( lhs.QuantizationDefault == rhs.QuantizationDefault ) ) return false;
+  
+  for ( ui32_t i = 0; i < JP2K::MaxComponents; i++ )
+    {
+      if ( ! ( lhs.ImageComponents[i] == rhs.ImageComponents[i] ) )
+       return false;
+    }
+
+  return true;
+}
+
 //
 ASDCP::Result_t
 ASDCP::JP2K::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB)
@@ -174,6 +291,18 @@ ASDCP::JP2K::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB)
   // open the file
   Result_t result = m_Parser.OpenReadFrame((*m_CurrentFile).c_str(), FB);
 
+  if ( ASDCP_SUCCESS(result) && m_Pedantic )
+    {
+      PictureDescriptor PDesc;
+      result = m_Parser.FillPictureDescriptor(PDesc);
+
+      if ( ASDCP_SUCCESS(result) && ! ( m_PDesc == PDesc ) )
+       {
+         Kumu::DefaultLogSink().Error("JPEG-2000 codestream parameters do not match at frame %d\n", m_FramesRead + 1);
+         result = RESULT_RAW_FORMAT;
+       }
+    }
+
   if ( ASDCP_SUCCESS(result) )
     {
       FB.FrameNumber(m_FramesRead++);
@@ -197,11 +326,25 @@ ASDCP::JP2K::SequenceParser::~SequenceParser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::JP2K::SequenceParser::OpenRead(const char* filename, bool pedantic) const
+ASDCP::JP2K::SequenceParser::OpenRead(const std::string& filename, bool pedantic) const
+{
+  const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
+
+  Result_t result = m_Parser->OpenRead(filename, pedantic);
+
+  if ( ASDCP_FAILURE(result) )
+    const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser.release();
+
+  return result;
+}
+
+//
+Result_t
+ASDCP::JP2K::SequenceParser::OpenRead(const std::list<std::string>& file_list, bool pedantic) const
 {
   const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
 
-  Result_t result = m_Parser->OpenRead(filename);
+  Result_t result = m_Parser->OpenRead(file_list, pedantic);
 
   if ( ASDCP_FAILURE(result) )
     const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser.release();
@@ -209,6 +352,7 @@ ASDCP::JP2K::SequenceParser::OpenRead(const char* filename, bool pedantic) const
   return result;
 }
 
+
 // Rewinds the stream to the beginning.
 ASDCP::Result_t
 ASDCP::JP2K::SequenceParser::Reset() const
@@ -230,6 +374,7 @@ ASDCP::JP2K::SequenceParser::ReadFrame(FrameBuffer& FB) const
   return m_Parser->ReadFrame(FB);
 }
 
+//
 ASDCP::Result_t
 ASDCP::JP2K::SequenceParser::FillPictureDescriptor(PictureDescriptor& PDesc) const
 {