- Added support for optional CPF, CAP and PRF segments
authorPierre-Anthony Lemieux <pal@palemieux.com>
Tue, 17 Dec 2019 20:05:00 +0000 (12:05 -0800)
committerPierre-Anthony Lemieux <pal@palemieux.com>
Tue, 17 Dec 2019 20:05:07 +0000 (12:05 -0800)
- Fixed encoding of J2KExtendedCapabilities

src/AS_DCP.h
src/AS_DCP_JP2K.cpp
src/JP2K.h
src/JP2K_Codestream_Parser.cpp
src/JP2K_Sequence_Parser.cpp
src/MXFTypes.cpp
src/MXFTypes.h

index 0948cbf5b2bff9f854d5b60c5b6cb5b52a4e142b..74991f68f47f819463e5e874975b2ded225b2065 100755 (executable)
@@ -1051,6 +1051,9 @@ namespace ASDCP {
       const ui8_t  MaxCapabilities = 32;
                        const ui16_t MaxPRFN = 4;
                        const ui16_t MaxCPFN = 4;
+                       const i8_t NoExtendedCapabilitiesSignaled = -1;
+                       const ui16_t NoPRFSignaled = 0;
+                       const ui16_t NoCPFSignaled = 0;
 
 #pragma pack(1)
       struct ImageComponent_t  // ISO 15444-1 Annex A.5.1
@@ -1092,18 +1095,19 @@ namespace ASDCP {
       struct ExtendedCapabilities_t // ISO 15444-1 Annex A.5.2
       {
        ui32_t  Pcap; // Pcap = 0 means that no extended capabilities are required
-       ui16_t  Ccap[MaxCapabilities]; // Ccap^i in ISO/IEC 15444-1 corresponds to Ccap[i - 1]
+       i8_t N; // Number of Ccap elements, or NoExtendedCapabilitiesSignaled if no Extended Capabilities are signaled
+       ui16_t  Ccap[MaxCapabilities]; 
       };
 
                        struct Profile_t // ISO 15444-1
       {
-       ui16_t  N; // N = 0 means that the profile is signaled through Rsiz exclusively
+       ui16_t  N; // N = NoPRFSignaled means that Profile is signaled through Rsiz exclusively
        ui16_t  Pprf[MaxPRFN]; // Pprf^i in ISO/IEC 15444-1 corresponds to Pprf[i -1]
       };
 
                        struct CorrespondingProfile_t // ISO 15444-1
       {
-       ui16_t  N; // N = 0 means that no corresponding profile is signaled
+       ui16_t  N; // N = NoCPFSignaled means that no corresponding profile is signaled
        ui16_t  Pcpf[MaxCPFN]; // Pcpf^i in ISO/IEC 15444-1 corresponds to Pcpf[i -1]
       };
 
index a980e0f3ba06f3c44a88d438ceba9d4927952919..129f53d97de10fa68a1a5edf76a5ed9b1e9e76c7 100755 (executable)
@@ -128,19 +128,19 @@ ASDCP::JP2K::operator << (std::ostream& strm, const PictureDescriptor& PDesc)
          }
   }
 
-  if (PDesc.ExtendedCapabilities.Pcap != 0) {
+  if (PDesc.ExtendedCapabilities.N != JP2K::NoExtendedCapabilitiesSignaled && PDesc.ExtendedCapabilities.Pcap != 0) {
 
          strm << "Extended Capabilities:" << std::endl;
 
 
          strm << "                     Pcap:" << PDesc.ExtendedCapabilities.Pcap << std::endl;
 
-         for (i32_t b = 0; b < JP2K::MaxCapabilities; b++) {
+         for (i32_t b = 0, i = 0; b < JP2K::MaxCapabilities; b++) {
 
                  if ((PDesc.ExtendedCapabilities.Pcap >> b) & 0x1) {
 
                          strm << "              Ccap(" << (JP2K::MaxCapabilities - b) << "): " <<
-                                 std::hex << std::showbase << PDesc.ExtendedCapabilities.Ccap[JP2K::MaxCapabilities - b - 1] << std::dec << std::noshowbase
+                                 std::hex << std::showbase << PDesc.ExtendedCapabilities.Ccap[i++] << std::dec << std::noshowbase
                                  << std::endl;
 
                  }
@@ -259,16 +259,20 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream)
          }
   }
 
-  fprintf(stream, "Extended Capabilities: %x\n", PDesc.ExtendedCapabilities.Pcap);
+  if (PDesc.ExtendedCapabilities.N != JP2K::NoExtendedCapabilitiesSignaled) {
 
-       for (i32_t b = 0; b < JP2K::MaxCapabilities; b++) {
+         fprintf(stream, "Extended Capabilities: %x\n", PDesc.ExtendedCapabilities.Pcap);
 
-               if ((PDesc.ExtendedCapabilities.Pcap >> b) & 0x1) {
+         for (i32_t b = 0, i = 0; b < JP2K::MaxCapabilities && i < PDesc.ExtendedCapabilities.N; b++) {
 
-                       fprintf(stream, "           Ccap(%d): %hx\n", JP2K::MaxCapabilities - b, PDesc.ExtendedCapabilities.Ccap[JP2K::MaxCapabilities - b - 1]);
+                 if ((PDesc.ExtendedCapabilities.Pcap >> (JP2K::MaxCapabilities - b - 1)) & 0x1) {
 
-               }
-       }
+                         fprintf(stream, "           Ccap(%d): %hx\n", b + 1, PDesc.ExtendedCapabilities.Ccap[i++]);
+
+                 }
+         }
+
+  }
   
 }
 
@@ -360,7 +364,9 @@ ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
 
   // Extended capabilities
 
-  if (PDesc.ExtendedCapabilities.Pcap == 0) {
+  if (PDesc.ExtendedCapabilities.N == JP2K::NoExtendedCapabilitiesSignaled) {
+
+         /* No extended capabilities are signaled */
 
          EssenceSubDescriptor.J2KExtendedCapabilities.set_has_value(false);
 
@@ -368,9 +374,11 @@ ASDCP::JP2K_PDesc_to_MD(const JP2K::PictureDescriptor& PDesc,
 
          EssenceSubDescriptor.J2KExtendedCapabilities.get().Pcap = PDesc.ExtendedCapabilities.Pcap;
 
+         EssenceSubDescriptor.J2KExtendedCapabilities.get().Ccap.resize(PDesc.ExtendedCapabilities.N);
+
          std::copy(PDesc.ExtendedCapabilities.Ccap,
-                 PDesc.ExtendedCapabilities.Ccap + JP2K::MaxCapabilities,
-                 EssenceSubDescriptor.J2KExtendedCapabilities.get().Ccap);
+                 PDesc.ExtendedCapabilities.Ccap + PDesc.ExtendedCapabilities.N,
+                 EssenceSubDescriptor.J2KExtendedCapabilities.get().Ccap.begin());
 
          EssenceSubDescriptor.J2KExtendedCapabilities.set_has_value(true);
 
@@ -480,14 +488,16 @@ ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor&  Esse
   if (EssenceSubDescriptor.J2KExtendedCapabilities.empty()) {
 
          PDesc.ExtendedCapabilities.Pcap = 0;
+         PDesc.ExtendedCapabilities.N = JP2K::NoExtendedCapabilitiesSignaled;
 
   }
   else {
 
          PDesc.ExtendedCapabilities.Pcap = EssenceSubDescriptor.J2KExtendedCapabilities.const_get().Pcap;
+         PDesc.ExtendedCapabilities.N = EssenceSubDescriptor.J2KExtendedCapabilities.const_get().Ccap.size();
 
-         std::copy(EssenceSubDescriptor.J2KExtendedCapabilities.const_get().Ccap,
-                 EssenceSubDescriptor.J2KExtendedCapabilities.const_get().Ccap + JP2K::MaxCapabilities,
+         std::copy(EssenceSubDescriptor.J2KExtendedCapabilities.const_get().Ccap.begin(),
+                 EssenceSubDescriptor.J2KExtendedCapabilities.const_get().Ccap.end(),
                  PDesc.ExtendedCapabilities.Ccap);
 
   }
index 5599b2bb97298a8656cbfd4209161d5a8149fa0e..8128de5367f6e15f8b03c5e3992aeb6056c041a7 100755 (executable)
@@ -260,7 +260,7 @@ namespace JP2K
 
       public:
           PRF(const Marker& M) {
-              assert(M.m_Type == MRK_CPF);
+              assert(M.m_Type == MRK_PRF);
 
                          m_Data = (ui16_t*) M.m_Data;
                          m_N = M.m_DataSize >> 1;
@@ -282,6 +282,8 @@ namespace JP2K
 
                  ui32_t m_Pcap;
 
+                 i8_t m_N;
+
           KM_NO_COPY_CONSTRUCT(CAP);
           CAP();
 
@@ -291,12 +293,15 @@ namespace JP2K
 
               m_Data = (ui16_t *) (M.m_Data + 4);
                          m_Pcap = KM_i32_BE(*(ui32_t*)(M.m_Data));
+                         m_N = (M.m_DataSize - 4) >> 1;
           }
 
           ~CAP() {}
 
           inline ui32_t pcap() const { return m_Pcap; }
 
+                 inline i8_t N() const { return m_N; }
+
           inline ui16_t ccap(ui16_t i) const { return KM_i16_BE(m_Data[2 * (i - 1)]); }
 
           void Dump(FILE* stream = 0) const;
index 43665e690f427dced353c8cc971ff4230f254cf3..9d5540911a699b4e774447479144eaf6579d7927 100755 (executable)
@@ -101,6 +101,12 @@ ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDe
   const byte_t* p = FB.RoData();
   const byte_t* end_p = p + FB.Size();
 
+  /* initialize optional items */
+
+  PDesc.ExtendedCapabilities.N = JP2K::NoExtendedCapabilitiesSignaled;
+  PDesc.Profile.N = 0;
+  PDesc.CorrespondingProfile.N = 0;
+
   while ( p < end_p && ASDCP_SUCCESS(result) )
     {
       result = GetNextMarker(&p, NextMarker);
@@ -185,19 +191,14 @@ ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDe
            
                        PDesc.ExtendedCapabilities.Pcap = CAP_.pcap();
 
-                       for(i32_t b = 32, i = 1; b > 0; b--) {
-
-                               if ( (PDesc.ExtendedCapabilities.Pcap >> (b - 1)) & 0x1 ) {
+                       PDesc.ExtendedCapabilities.N = CAP_.N();
 
-                                       PDesc.ExtendedCapabilities.Ccap[32 - b] = CAP_.ccap(i++);
+                       for (i32_t i = 0; i < CAP_.N(); i++) {
 
-                               } else {
-
-                                       PDesc.ExtendedCapabilities.Ccap[32 - b] = 0;
-
-                               }
+                               PDesc.ExtendedCapabilities.Ccap[i] = CAP_.ccap(i);
 
                        }
+
          }
          break;
 
index a1ece3facc18fc9f98c4439a04adefd854647849..e8d779c612aaf5900b3496627ffb290ee3ff6148 100755 (executable)
@@ -255,7 +255,9 @@ operator==(const ASDCP::JP2K::ExtendedCapabilities_t& lhs, const ASDCP::JP2K::Ex
 {
        if (lhs.Pcap != rhs.Pcap) return false;
 
-       for (ui32_t i = 0; i < JP2K::MaxCapabilities; i++)
+       if (lhs.N != rhs.N) return false;
+
+       for (ui32_t i = 0; i < lhs.N; i++)
        {
                if (lhs.Ccap[i] != rhs.Ccap[i])
                        return false;
index 7346b6c66006ee2a29931167a6f4ff3ea45ec982..39d928b8ad73d6b22ba632eee2eeb9c0233af428 100755 (executable)
@@ -783,12 +783,9 @@ ASDCP::MXF::J2KExtendedCapabilities::Archive(Kumu::MemIOWriter* Writer) const {
       return false;
     }
 
-  for ( int i = 0; i < JP2K::MaxCapabilities; ++i )
+    if ( ! Ccap.Archive(Writer) )
     {
-      if ( ! Writer->WriteUi16BE(Ccap[i]) )
-        {
-          return false;
-        }
+        return false;
     }
 
   return true;
@@ -802,12 +799,9 @@ ASDCP::MXF::J2KExtendedCapabilities::Unarchive(Kumu::MemIOReader* Reader) {
       return false;
     }
 
 for ( int i = 0; i < JP2K::MaxCapabilities; ++i )
if ( ! Ccap.Unarchive(Reader) )
     {
-      if ( ! Reader->ReadUi16BE(&Ccap[i]) )
-        {
-          return false;
-        }
+        return false;
     }
 
   return true;
@@ -821,7 +815,7 @@ ASDCP::MXF::J2KExtendedCapabilities::EncodeString(char* str_buf, ui32_t buf_len)
 
   if ( Pcap != 0 && buf_len > str_len )
     {
-      for ( int i = 0; i < JP2K::MaxCapabilities; ++i )
+      for ( int i = 0; i < Ccap.size(); ++i )
         {
          snprintf(str_buf+(i*3), 4, "%02hx.", Ccap[i]);
         }
index 39f75d5caceb3b01e55086a98a05ac2b7cea9c4c..eb8b3dfe0b52e83144f77570c421afcfbae7a18e 100755 (executable)
@@ -694,7 +694,7 @@ namespace ASDCP
         {
         public:
          ui32_t Pcap;
-         ui16_t Ccap[JP2K::MaxCapabilities];
+         Array<Kumu::ArchivableUi16> Ccap;
        
          bool HasValue() const { return true; }
          ui32_t ArchiveLength() const { return 0; }