Release me
[asdcplib.git] / src / AS_DCP_JP2K.cpp
index 62c9e7897f96a20c1396e61361509585caad909d..a4bffc67eeefc4c1af7e0e9e3a2b52bf2e9bfcdf 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2013, John Hurst
+Copyright (c) 2004-2016, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,7 @@ static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE 429-4 frame wrappin
 static std::string JP2K_S_PACKAGE_LABEL = "File Package: SMPTE 429-10 frame wrapping of stereoscopic JPEG 2000 codestreams";
 static std::string PICT_DEF_LABEL = "Picture Track";
 
-int s_exp_lookup[16] = { 0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,2048, 4096, 8192, 16384, 32768 };
+static int s_exp_lookup[16] = { 0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,2048, 4096, 8192, 16384, 32768 };
 
 //
 std::ostream&
@@ -69,7 +69,7 @@ ASDCP::JP2K::operator << (std::ostream& strm, const PictureDescriptor& PDesc)
   strm << "  bits  h-sep v-sep" << std::endl;
 
   ui32_t i;
-  for ( i = 0; i < PDesc.Csize; i++ )
+  for ( i = 0; i < PDesc.Csize && i < MaxComponents; ++i )
     {
       strm << "  " << std::setw(4) << PDesc.ImageComponents[i].Ssize + 1 /* See ISO 15444-1, Table A11, for the origin of '+1' */
           << "  " << std::setw(5) << PDesc.ImageComponents[i].XRsize
@@ -90,13 +90,13 @@ ASDCP::JP2K::operator << (std::ostream& strm, const PictureDescriptor& PDesc)
 
   ui32_t precinct_set_size = 0;
 
-  for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ )
+  for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i )
     precinct_set_size++;
 
   strm << "          Precincts: " << (short) precinct_set_size << std::endl;
   strm << "precinct dimensions:" << std::endl;
 
-  for ( i = 0; i < precinct_set_size; i++ )
+  for ( i = 0; i < precinct_set_size && i < MaxPrecincts; ++i )
     strm << "    " << i + 1 << ": " << s_exp_lookup[PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]&0x0f] << " x "
         << s_exp_lookup[(PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]>>4)&0x0f] << std::endl;
 
@@ -154,7 +154,7 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream)
   fprintf(stream, "  bits  h-sep v-sep\n");
 
   ui32_t i;
-  for ( i = 0; i < PDesc.Csize; i++ )
+  for ( i = 0; i < PDesc.Csize && i < MaxComponents; i++ )
     {
       fprintf(stream, "  %4d  %5d %5d\n",
              PDesc.ImageComponents[i].Ssize + 1, // See ISO 15444-1, Table A11, for the origin of '+1'
@@ -163,34 +163,34 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream)
              );
     }
   
-  fprintf(stream, "               Scod: %hd\n", PDesc.CodingStyleDefault.Scod);
-  fprintf(stream, "   ProgressionOrder: %hd\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder);
+  fprintf(stream, "               Scod: %hhu\n", PDesc.CodingStyleDefault.Scod);
+  fprintf(stream, "   ProgressionOrder: %hhu\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder);
   fprintf(stream, "     NumberOfLayers: %hd\n",
          KM_i16_BE(Kumu::cp2i<ui16_t>(PDesc.CodingStyleDefault.SGcod.NumberOfLayers)));
 
-  fprintf(stream, " MultiCompTransform: %hd\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform);
-  fprintf(stream, "DecompositionLevels: %hd\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels);
-  fprintf(stream, "     CodeblockWidth: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth);
-  fprintf(stream, "    CodeblockHeight: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight);
-  fprintf(stream, "     CodeblockStyle: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle);
-  fprintf(stream, "     Transformation: %hd\n", PDesc.CodingStyleDefault.SPcod.Transformation);
+  fprintf(stream, " MultiCompTransform: %hhu\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform);
+  fprintf(stream, "DecompositionLevels: %hhu\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels);
+  fprintf(stream, "     CodeblockWidth: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth);
+  fprintf(stream, "    CodeblockHeight: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight);
+  fprintf(stream, "     CodeblockStyle: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle);
+  fprintf(stream, "     Transformation: %hhu\n", PDesc.CodingStyleDefault.SPcod.Transformation);
 
 
   ui32_t precinct_set_size = 0;
 
-  for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; i++ )
+  for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i )
     precinct_set_size++;
 
-  fprintf(stream, "          Precincts: %hd\n", precinct_set_size);
+  fprintf(stream, "          Precincts: %u\n", precinct_set_size);
   fprintf(stream, "precinct dimensions:\n");
 
-  for ( i = 0; i < precinct_set_size; i++ )
+  for ( i = 0; i < precinct_set_size && i < MaxPrecincts; i++ )
     fprintf(stream, "    %d: %d x %d\n", i + 1,
            s_exp_lookup[PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]&0x0f],
            s_exp_lookup[(PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]>>4)&0x0f]
            );
 
-  fprintf(stream, "               Sqcd: %hd\n", PDesc.QuantizationDefault.Sqcd);
+  fprintf(stream, "               Sqcd: %hhu\n", PDesc.QuantizationDefault.Sqcd);
 
   char tmp_buf[MaxDefaults*2];
   fprintf(stream, "              SPqcd: %s\n",
@@ -296,7 +296,7 @@ ASDCP::MD_to_JP2K_PDesc(const ASDCP::MXF::GenericPictureEssenceDescriptor&  Esse
     }
   else
     {
-      DefaultLogSink().Error("Unexpected PictureComponentSizing size: %u, should be 17\n", tmp_size);
+      DefaultLogSink().Warn("Unexpected PictureComponentSizing size: %u, should be 17.\n", tmp_size);
     }
 
   // CodingStyleDefault
@@ -392,12 +392,15 @@ lh__Reader::OpenRead(const std::string& filename, EssenceType_t type)
              DefaultLogSink().Warn("EditRate and SampleRate do not match (%.03f, %.03f).\n",
                                    m_EditRate.Quotient(), m_SampleRate.Quotient());
              
-             if ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 ||
-                  m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 ||
-                  m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 ||
-                  m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 ||
-                  m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 ||
-                  m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 )
+             if ( ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 )
+                  || ( m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 )
+                  || ( m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 )
+                  || ( m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 )
+                  || ( m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 )
+                  || ( m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 )
+                  || ( m_EditRate == EditRate_96 && m_SampleRate == EditRate_192 )
+                  || ( m_EditRate == EditRate_100 && m_SampleRate == EditRate_200 )
+                  || ( m_EditRate == EditRate_120 && m_SampleRate == EditRate_240 ) )
                {
                  DefaultLogSink().Debug("File may contain JPEG Interop stereoscopic images.\n");
                  return RESULT_SFORMAT;
@@ -456,6 +459,30 @@ lh__Reader::OpenRead(const std::string& filename, EssenceType_t type)
                  return RESULT_FORMAT;
                }
            }
+         else if ( m_EditRate == EditRate_96 )
+           {
+             if ( m_SampleRate != EditRate_192 )
+               {
+                 DefaultLogSink().Error("EditRate and SampleRate not correct for 96/192 stereoscopic essence.\n");
+                 return RESULT_FORMAT;
+               }
+           }
+         else if ( m_EditRate == EditRate_100 )
+           {
+             if ( m_SampleRate != EditRate_200 )
+               {
+                 DefaultLogSink().Error("EditRate and SampleRate not correct for 100/200 stereoscopic essence.\n");
+                 return RESULT_FORMAT;
+               }
+           }
+         else if ( m_EditRate == EditRate_120 )
+           {
+             if ( m_SampleRate != EditRate_240 )
+               {
+                 DefaultLogSink().Error("EditRate and SampleRate not correct for 120/240 stereoscopic essence.\n");
+                 return RESULT_FORMAT;
+               }
+           }
          else
            {
              DefaultLogSink().Error("EditRate not correct for stereoscopic essence: %d/%d.\n",
@@ -684,7 +711,6 @@ public:
 
     if ( ASDCP_FAILURE(m_IndexAccess.Lookup(FrameNum, TmpEntry)) )
       {
-       DefaultLogSink().Error("Frame value out of range: %u\n", FrameNum);
        return RESULT_RANGE;
       }
 
@@ -1013,7 +1039,7 @@ lh__Writer::SetSourceStream(const PictureDescriptor& PDesc, const std::string& l
 
   if ( ASDCP_SUCCESS(result) )
     {
-      result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_JPEG_2000WrappingFrame)),
+      result = WriteASDCPHeader(label, UL(m_Dict->ul(MDD_MXFGCFUFrameWrappedPictureElement)),
                                PICT_DEF_LABEL, UL(m_EssenceUL), UL(m_Dict->ul(MDD_PictureDataDef)),
                                LocalEditRate, derive_timecode_rate_from_edit_rate(m_PDesc.EditRate));
     }
@@ -1038,7 +1064,7 @@ lh__Writer::WriteFrame(const JP2K::FrameBuffer& FrameBuf, bool add_index,
   ui64_t StreamOffset = m_StreamOffset;
 
   if ( ASDCP_SUCCESS(result) )
-    result = WriteEKLVPacket(FrameBuf, m_EssenceUL, Ctx, HMAC);
+    result = WriteEKLVPacket(FrameBuf, m_EssenceUL, MXF_BER_LENGTH, Ctx, HMAC);
 
   if ( ASDCP_SUCCESS(result) && add_index )
     {  
@@ -1331,6 +1357,15 @@ ASDCP::JP2K::MXFSWriter::OpenWrite(const std::string& filename, const WriterInfo
       else if ( PDesc.EditRate == ASDCP::EditRate_60 )
        TmpPDesc.EditRate = ASDCP::EditRate_120;
 
+      else if ( PDesc.EditRate == ASDCP::EditRate_96 )
+       TmpPDesc.EditRate = ASDCP::EditRate_192;
+
+      else if ( PDesc.EditRate == ASDCP::EditRate_100 )
+       TmpPDesc.EditRate = ASDCP::EditRate_200;
+
+      else if ( PDesc.EditRate == ASDCP::EditRate_120 )
+       TmpPDesc.EditRate = ASDCP::EditRate_240;
+
       result = m_Writer->SetSourceStream(TmpPDesc, JP2K_S_PACKAGE_LABEL, PDesc.EditRate);
     }