Merge pull request #25 from remia/fix/non-pod-variadic-warning
[asdcplib.git] / src / JP2K.cpp
index b16a6963dac5f674a3863546f004c71b99b53738..4d2c130787acbf289430296076b1279363967fa6 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2005-2009, John Hurst
+Copyright (c) 2005-2014, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -37,45 +37,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using Kumu::DefaultLogSink;
 
 
-// when indexed with the second byte of a marker code, this table will procuce one of
-// two values:
-//   0 - the marker is a standalone marker
-//   1 - the marker designates a marker segment
-//
-const byte_t MarkerSegmentMap[] =
-  {
-    /*      0   1   2   3   4   5   6   7      8   9   a   b   c   d   e   f */
-    /* 0 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 0
-    /* 1 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 1
-    /* 2 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 2
-    /* 3 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 3
-    /* 4 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 4
-    /* 5 */ 0,  1,  1,  1,  1,  1,  0,  1,     1,  0,  0,  0,  1,  1,  1,  1, // 5
-    /* 6 */ 1,  1,  0,  1,  1,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 6
-    /* 7 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 7
-    /* 8 */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 8
-    /* 9 */ 1,  1,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // 9
-    /* a */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // a
-    /* b */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // b
-    /* c */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // c
-    /* d */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // d
-    /* e */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // e
-    /* f */ 0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0, // f
-    /*      0   1   2   3   4   5   6   7      8   9   a   b   c   d   e   f */
-  };
-
-
 //
 ASDCP::Result_t
 ASDCP::JP2K::GetNextMarker(const byte_t** buf, JP2K::Marker& Marker)
 {
   assert((buf != 0) && (*buf != 0 ));
   
-  if ( **buf != 0xff )
+  if (*(*buf)++ != 0xff )
     return ASDCP::RESULT_FAIL;
 
-  Marker.m_IsSegment = (MarkerSegmentMap[*(++(*buf))] == 1);
   Marker.m_Type = (Marker_t)(0xff00 | *(*buf)++);
+  Marker.m_IsSegment = Marker.m_Type != MRK_SOC && Marker.m_Type != MRK_SOD && Marker.m_Type != MRK_EOC;
 
   if ( Marker.m_IsSegment )
     {
@@ -86,13 +58,13 @@ ASDCP::JP2K::GetNextMarker(const byte_t** buf, JP2K::Marker& Marker)
       *buf += Marker.m_DataSize;
     }
 
-
+  /* TODO: why is this here?
   if ( Marker.m_DataSize != 0 && Marker.m_DataSize < 3 )
     {
       DefaultLogSink().Error("Illegal data size: %u\n", Marker.m_DataSize);
       return ASDCP::RESULT_FAIL;
     }
-
+       */
   return ASDCP::RESULT_OK;
 }
 
@@ -102,7 +74,7 @@ ASDCP::JP2K::GetNextMarker(const byte_t** buf, JP2K::Marker& Marker)
 
 //
 void
-ASDCP::JP2K::Accessor::SIZ::ReadComponent(ui32_t index, ASDCP::JP2K::ImageComponent_t& IC)
+ASDCP::JP2K::Accessor::SIZ::ReadComponent(const ui32_t index, ASDCP::JP2K::ImageComponent_t& IC) const
 {
   assert ( index < Csize() );
   const byte_t* p = m_MarkerData + 36 + (index * 3);
@@ -113,7 +85,7 @@ ASDCP::JP2K::Accessor::SIZ::ReadComponent(ui32_t index, ASDCP::JP2K::ImageCompon
 
 //
 void
-ASDCP::JP2K::Accessor::SIZ::Dump(FILE* stream)
+ASDCP::JP2K::Accessor::SIZ::Dump(FILE* stream) const
 {
   if ( stream == 0 )
     stream = stderr;
@@ -146,19 +118,79 @@ ASDCP::JP2K::Accessor::SIZ::Dump(FILE* stream)
 
 //
 void
-ASDCP::JP2K::Accessor::COM::Dump(FILE* stream)
+ASDCP::JP2K::Accessor::COD::Dump(FILE* stream) const
+{
+  if ( stream == 0 )
+    stream = stderr;
+
+  fprintf(stream, "COD: \n");
+  const char* prog_order_str = "RESERVED";
+  const char* transformations_str = prog_order_str;
+
+  switch ( ProgOrder() )
+    {
+    case 0: prog_order_str = "LRCP"; break;
+    case 1: prog_order_str = "RLCP"; break;
+    case 2: prog_order_str = "RPCL"; break;
+    case 3: prog_order_str = "PCRL"; break;
+    case 4: prog_order_str = "CPRL"; break;
+    }
+
+  switch ( Transformation() )
+    {
+    case 0: transformations_str = "9/7"; break;
+    case 1: transformations_str = "5/3"; break;
+    }
+
+  fprintf(stream, "      ProgOrder: %s\n", prog_order_str);
+  fprintf(stream, "         Layers: %hu\n", Layers());
+  fprintf(stream, "   DecompLevels: %hhu\n", DecompLevels());
+  fprintf(stream, " CodeBlockWidth: %d\n", 1 << CodeBlockWidth());
+  fprintf(stream, "CodeBlockHeight: %d\n", 1 << CodeBlockHeight());
+  fprintf(stream, " CodeBlockStyle: %d\n", CodeBlockStyle());
+  fprintf(stream, " Transformation: %s\n", transformations_str);
+}
+
+//
+const char*
+ASDCP::JP2K::Accessor::GetQuantizationTypeString(const Accessor::QuantizationType_t t)
+{
+  switch ( t )
+    {
+    case QT_NONE: return "none";
+    case QT_DERIVED: return "scalar derived";
+    case QT_EXP: return "scalar expounded";
+    }
+
+  return "**UNKNOWN**";
+}
+
+//
+void
+ASDCP::JP2K::Accessor::QCD::Dump(FILE* stream) const
+{
+  if ( stream == 0 )
+    stream = stderr;
+
+  fprintf(stream, "QCD: \n");
+  fprintf(stream, "QuantizationType: %s\n", GetQuantizationTypeString(QuantizationType()));
+  fprintf(stream, "       GuardBits: %d\n", GuardBits());
+  fprintf(stream, "           SPqcd: %d\n", GuardBits());
+  Kumu::hexdump(m_MarkerData, m_DataSize, stream);
+}
+
+//
+void
+ASDCP::JP2K::Accessor::COM::Dump(FILE* stream) const
 {
   if ( stream == 0 )
     stream = stderr;
 
   if ( IsText() )
     {
-      char* t_str = (char*)malloc(CommentSize() + 1);
-      assert( t_str != 0 );
-      ui32_t cs = CommentSize();
-      memcpy(t_str, CommentData(), cs);
-      t_str[cs] = 0;
-      fprintf(stream, "COM:%s\n", t_str);
+      std::string tmp_str;
+      tmp_str.assign((char*)CommentData(), CommentSize());
+      fprintf(stream, "COM:%s\n", tmp_str.c_str());
     }
   else
     {
@@ -167,6 +199,78 @@ ASDCP::JP2K::Accessor::COM::Dump(FILE* stream)
     }
 }
 
+//
+void
+ASDCP::JP2K::Accessor::PRF::Dump(FILE* stream) const
+{
+  if ( stream == 0 )
+    stream = stderr;
+
+  fprintf(stream, "PRF: \n");
+
+  if (N() == 0) {
+
+         fprintf(stream, "     N/A");
+
+  } else {
+
+         for (ui16_t i = 1; i <= N(); i++) {
+                 fprintf(stream, "pprf(%d): %d\n", i, pprf(i));
+         }
+
+  }
+}
+
+//
+void
+ASDCP::JP2K::Accessor::CPF::Dump(FILE* stream) const
+{
+  if ( stream == 0 )
+    stream = stderr;
+
+  fprintf(stream, "CPF: \n");
+
+  if (N() == 0) {
+
+         fprintf(stream, "     N/A");
+
+  } else {
+
+         for (ui16_t i = 1; i <= N(); i++) {
+                 fprintf(stream, "pcpf(%d): %d\n", i, pcpf(i));
+         }
+
+  }
+}
+
+
+//
+void
+ASDCP::JP2K::Accessor::CAP::Dump(FILE* stream) const
+{
+  if ( stream == 0 )
+    stream = stderr;
+
+  fprintf(stream, "CAP: \n");
+
+  ui32_t pcap = this->pcap();
+
+  if (pcap == 0) {
+
+         fprintf(stream, "     None");
+
+  } else {
+
+         for (i32_t b = 32, i = 1; b > 0; b--) {
+
+                 if ((pcap >> (32 - b)) & 0x1) {
+
+                         fprintf(stream, "     ccap(%d): %d\n", b, this->ccap(i++));
+
+                 }
+         }
+  }
+}
 
 //-------------------------------------------------------------------------------------------------------
 //
@@ -214,6 +318,9 @@ ASDCP::JP2K::GetMarkerString(Marker_t m)
     case MRK_EPH: return "EPH: End of packet header"; break;
     case MRK_CRG: return "CRG: Component registration"; break;
     case MRK_COM: return "COM: Comment"; break;
+    case MRK_CPF: return "CPF: Corresponding profile"; break;
+    case MRK_CAP: return "CAP: Capabilities"; break;
+    case MRK_PRF: return "PRF: Profile"; break;
     }
 
   return "Unknown marker code";