Bump patch version post tag.
[asdcplib.git] / src / MXFTypes.cpp
index 58c6fb703ab68dbed1bbbbc0b450d1f9ffbcd21c..72338bbfda5f3290f8de2b9990345e4c52e92ba9 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2005-2012, John Hurst
+Copyright (c) 2005-2019, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -93,7 +93,7 @@ ASDCP::UL::MatchIgnoreStream(const UL& rhs) const
 
 //
 bool
-ASDCP::UL::ExactMatch(const UL& rhs) const
+ASDCP::UL::MatchExact(const UL& rhs) const
 {
   if ( m_Value[0] == rhs.m_Value[0] &&
        m_Value[1] == rhs.m_Value[1] &&
@@ -123,7 +123,7 @@ ASDCP::UL::EncodeString(char* str_buf, ui32_t buf_len) const
   if ( buf_len > 38 ) // room for dotted notation?
     {
       snprintf(str_buf, buf_len,
-              "%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x",
+              "%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x",
               m_Value[0],  m_Value[1],  m_Value[2],  m_Value[3],
               m_Value[4],  m_Value[5],  m_Value[6],  m_Value[7],
               m_Value[8],  m_Value[9],  m_Value[10], m_Value[11],
@@ -189,7 +189,7 @@ ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const
 {
   assert(str_buf);
 
-  snprintf(str_buf, buf_len, "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,",
+  snprintf(str_buf, buf_len, "[%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,",
           m_Value[0],  m_Value[1],  m_Value[2],  m_Value[3],
           m_Value[4],  m_Value[5],  m_Value[6],  m_Value[7],
           m_Value[8],  m_Value[9],  m_Value[10], m_Value[11],
@@ -202,7 +202,7 @@ ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const
     {
       // half-swapped UL, use [bbaa9988.ddcc.ffee.00010203.04050607]
       snprintf(str_buf + offset, buf_len - offset,
-              "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]",
+              "[%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]",
                m_Value[24], m_Value[25], m_Value[26], m_Value[27],
               m_Value[28], m_Value[29], m_Value[30], m_Value[31],
                m_Value[16], m_Value[17], m_Value[18], m_Value[19],
@@ -279,11 +279,14 @@ ASDCP::MXF::UTF16String::Unarchive(Kumu::MemIOReader* Reader)
   erase();
   const ui16_t* p = (ui16_t*)Reader->CurrentData();
   ui32_t length = Reader->Remainder() / 2;
-  char mb_buf[MB_LEN_MAX+1];
+  char mb_buf[MB_LEN_MAX];
+
+  mbstate_t ps;
+  memset(&ps, 0, sizeof(mbstate_t));
 
   for ( ui32_t i = 0; i < length; i++ )
     {
-      int count = wctomb(mb_buf, KM_i16_BE(p[i]));
+      int count = wcrtomb(mb_buf, KM_i16_BE(p[i]), &ps);
 
       if ( count == -1 )
        {
@@ -316,9 +319,12 @@ ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const
   ui32_t length = size();
   ui32_t i = 0;
 
+  mbstate_t ps;
+  memset(&ps, 0, sizeof(mbstate_t));
+
   while ( i < length )
     {
-      int count = mbtowc(&wcp, mbp+i, remainder);
+      int count = mbrtowc(&wcp, mbp+i, remainder, &ps);
 
       if ( count == -1 )
        {
@@ -326,7 +332,9 @@ ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const
          return false;
        }
       else if ( count  == 0 )
-       break;
+       {
+         break;
+       }
 
       bool result = Writer->WriteUi16BE((ui16_t)wcp);
 
@@ -410,7 +418,7 @@ ASDCP::MXF::ISO8String::Archive(Kumu::MemIOWriter* Writer) const
       return false;
     }
 
-  return Writer->WriteString(*this);
+  return Writer->WriteRaw((const byte_t*)c_str(), size());
 }
 
 //------------------------------------------------------------------------------------------
@@ -437,7 +445,7 @@ ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* Prime
 
       DefaultLogSink().Error("Malformed Set\n");
       m_ElementMap.clear();
-      result = RESULT_KLV_CODING;
+      result = RESULT_KLV_CODING(__LINE__, __FILE__);
     }
 }
 
@@ -487,7 +495,10 @@ ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, Kumu::IArchive* Object)
   if ( FindTL(Entry) )
     {
       if ( m_size < m_capacity ) // don't try to unarchive an empty item
-       return Object->Unarchive(this) ? RESULT_OK : RESULT_KLV_CODING;
+       {
+         // TODO: carry on if uachive fails
+         return Object->Unarchive(this) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
+       }
     }
 
   return RESULT_FALSE;
@@ -500,7 +511,7 @@ ASDCP::MXF::TLVReader::ReadUi8(const MDDEntry& Entry, ui8_t* value)
   ASDCP_TEST_NULL(value);
 
   if ( FindTL(Entry) )
-    return MemIOReader::ReadUi8(value) ? RESULT_OK : RESULT_KLV_CODING;
+    return MemIOReader::ReadUi8(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
 
   return RESULT_FALSE;
 }
@@ -512,7 +523,7 @@ ASDCP::MXF::TLVReader::ReadUi16(const MDDEntry& Entry, ui16_t* value)
   ASDCP_TEST_NULL(value);
 
   if ( FindTL(Entry) )
-    return MemIOReader::ReadUi16BE(value) ? RESULT_OK : RESULT_KLV_CODING;
+    return MemIOReader::ReadUi16BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
 
   return RESULT_FALSE;
 }
@@ -524,7 +535,7 @@ ASDCP::MXF::TLVReader::ReadUi32(const MDDEntry& Entry, ui32_t* value)
   ASDCP_TEST_NULL(value);
 
   if ( FindTL(Entry) )
-    return MemIOReader::ReadUi32BE(value) ? RESULT_OK : RESULT_KLV_CODING;
+    return MemIOReader::ReadUi32BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
 
   return RESULT_FALSE;
 }
@@ -536,7 +547,7 @@ ASDCP::MXF::TLVReader::ReadUi64(const MDDEntry& Entry, ui64_t* value)
   ASDCP_TEST_NULL(value);
 
   if ( FindTL(Entry) )
-    return MemIOReader::ReadUi64BE(value) ? RESULT_OK : RESULT_KLV_CODING;
+    return MemIOReader::ReadUi64BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
 
   return RESULT_FALSE;
 }
@@ -556,7 +567,7 @@ ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
 {
   if ( m_Lookup == 0 )
     {
-      DefaultLogSink().Error("No Primer object available\n");
+      DefaultLogSink().Error("No Primer object available.\n");
       return RESULT_FAIL;
     }
 
@@ -568,8 +579,8 @@ ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
       return RESULT_FAIL;
     }
 
-  if ( ! MemIOWriter::WriteUi8(TmpTag.a) ) return RESULT_KLV_CODING;
-  if ( ! MemIOWriter::WriteUi8(TmpTag.b) ) return RESULT_KLV_CODING;
+  if ( ! MemIOWriter::WriteUi8(TmpTag.a) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+  if ( ! MemIOWriter::WriteUi8(TmpTag.b) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
   return RESULT_OK;
 }
 
@@ -589,11 +600,11 @@ ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, Kumu::IArchive* Object
       // write a temp length
       byte_t* l_p = CurrentData();
 
-      if ( ! MemIOWriter::WriteUi16BE(0) ) return RESULT_KLV_CODING;
+      if ( ! MemIOWriter::WriteUi16BE(0) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
 
       ui32_t before = Length();
-      if ( ! Object->Archive(this) ) return RESULT_KLV_CODING;
-      if ( (Length() - before) > 0xffffL ) return RESULT_KLV_CODING;
+      if ( ! Object->Archive(this) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+      if ( (Length() - before) > 0xffffL ) return RESULT_KLV_CODING(__LINE__, __FILE__);
       Kumu::i2p<ui16_t>(KM_i16_BE(Length() - before), l_p);
     }
 
@@ -609,8 +620,8 @@ ASDCP::MXF::TLVWriter::WriteUi8(const MDDEntry& Entry, ui8_t* value)
 
   if ( ASDCP_SUCCESS(result) )
     {
-      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui8_t)) ) return RESULT_KLV_CODING;
-      if ( ! MemIOWriter::WriteUi8(*value) ) return RESULT_KLV_CODING;
+      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui8_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+      if ( ! MemIOWriter::WriteUi8(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
     }
   
   return result;
@@ -625,8 +636,8 @@ ASDCP::MXF::TLVWriter::WriteUi16(const MDDEntry& Entry, ui16_t* value)
 
   if ( KM_SUCCESS(result) )
     {
-      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui16_t)) ) return RESULT_KLV_CODING;
-      if ( ! MemIOWriter::WriteUi16BE(*value) ) return RESULT_KLV_CODING;
+      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui16_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+      if ( ! MemIOWriter::WriteUi16BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
     }
 
   return result;
@@ -641,8 +652,8 @@ ASDCP::MXF::TLVWriter::WriteUi32(const MDDEntry& Entry, ui32_t* value)
 
   if ( KM_SUCCESS(result) )
     {
-      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui32_t)) ) return RESULT_KLV_CODING;
-      if ( ! MemIOWriter::WriteUi32BE(*value) ) return RESULT_KLV_CODING;
+      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui32_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+      if ( ! MemIOWriter::WriteUi32BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
     }
 
   return result;
@@ -657,14 +668,71 @@ ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value)
 
   if ( KM_SUCCESS(result) )
     {
-      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui64_t)) ) return RESULT_KLV_CODING;
-      if ( ! MemIOWriter::WriteUi64BE(*value) ) return RESULT_KLV_CODING;
+      if ( ! MemIOWriter::WriteUi16BE(sizeof(ui64_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+      if ( ! MemIOWriter::WriteUi64BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
     }
 
   return result;
 }
 
 
+//----------------------------------------------------------------------------------------------------
+//
+
+
+ASDCP::MXF::RGBALayout::RGBALayout()
+{
+  memset(m_value, 0, RGBAValueLength);
+}
+
+ASDCP::MXF::RGBALayout::RGBALayout(const byte_t* value)
+{
+  memcpy(m_value, value, RGBAValueLength);
+}
+
+ASDCP::MXF::RGBALayout::~RGBALayout()
+{
+}
+
+static char
+get_char_for_code(byte_t c)
+{
+  for ( int i = 0; ASDCP::MXF::RGBALayoutTable[i].code != 0; ++i )
+    {
+      if ( ASDCP::MXF::RGBALayoutTable[i].code == c )
+       {
+         return ASDCP::MXF::RGBALayoutTable[i].symbol;
+       }
+    }
+
+  return '_';
+}
+
+//
+const char*
+ASDCP::MXF::RGBALayout::EncodeString(char* buf, ui32_t buf_len) const
+{
+  std::string tmp_str;
+  char tmp_buf[64];
+
+  for ( int i = 0; i < RGBAValueLength && m_value[i] != 0; i += 2 )
+    {
+      snprintf(tmp_buf, 64, "%c(%d)", get_char_for_code(m_value[i]), m_value[i+1]);
+
+      if ( ! tmp_str.empty() )
+       {
+         tmp_str += " ";
+       }
+
+      tmp_str += tmp_buf;
+    }
+
+  assert(tmp_str.size() < buf_len);
+  strncpy(buf, tmp_str.c_str(), tmp_str.size());
+  return buf;
+}
+
+
 //----------------------------------------------------------------------------------------------------
 //
 
@@ -706,6 +774,63 @@ ASDCP::MXF::Raw::EncodeString(char* str_buf, ui32_t buf_len) const
   return str_buf;
 }
 
+
+//
+bool
+ASDCP::MXF::J2KExtendedCapabilitiesType::Archive(Kumu::MemIOWriter* Writer) const {
+  if ( ! Writer->WriteUi32BE(Pcap) )
+    {
+      return false;
+    }
+
+    if ( ! Ccap.Archive(Writer) )
+    {
+        return false;
+    }
+
+  return true;
+}
+
+//
+bool
+ASDCP::MXF::J2KExtendedCapabilitiesType::Unarchive(Kumu::MemIOReader* Reader) {
+  if ( ! Reader->ReadUi32BE(&Pcap) )
+    {
+      return false;
+    }
+
+ if ( ! Ccap.Unarchive(Reader) )
+    {
+        return false;
+    }
+
+  return true;
+}
+
+//
+const char*
+ASDCP::MXF::J2KExtendedCapabilitiesType::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+  const int str_len = ( sizeof(ui16_t) + 1 ) * JP2K::MaxCapabilities;
+
+  if ( Pcap != 0 && buf_len > str_len )
+    {
+      for ( int i = 0; i < Ccap.size(); ++i )
+        {
+         snprintf(str_buf+(i*3), 4, "%02hx.", Ccap[i].value);
+        }
+
+      str_buf[str_len-1] = 0;
+    }
+  else
+    {
+      str_buf[0] = 0;
+    }
+
+  return str_buf;
+}
+
+
 //
 // end MXFTypes.cpp
 //