fixed the make file to include new location of CMakeLists.txt (src)
[asdcplib.git] / src / as-02-unwrap.cpp
index 42d48205f292f8fe0a6a3d1697b74da7b0914147..43fe12f8c2617665bb8e09542dd60fd59cc55999 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2011-2012, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
+Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS,
 John Hurst
 
 All rights reserved.
@@ -69,7 +69,7 @@ banner(FILE* stream = stdout)
 {
   fprintf(stream, "\n\
 %s (asdcplib %s)\n\n\
-Copyright (c) 2011-2013, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst\n\n\
+Copyright (c) 2011-2015, Robert Scheler, Heiko Sparenberg Fraunhofer IIS, John Hurst\n\n\
 asdcplib may be copied only under the terms of the license found at\n\
 the top of every file in the asdcplib distribution kit.\n\n\
 Specify the -h (help) option for further information about %s\n\n",
@@ -86,7 +86,7 @@ USAGE: %s [-h|-help] [-V]\n\
        %s [-1|-2] [-b <buffer-size>] [-d <duration>]\n\
        [-f <starting-frame>] [-m] [-p <frame-rate>] [-R] [-s <size>] [-v] [-W]\n\
        [-w] <input-file> [<file-prefix>]\n\n",
-         PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME);
+         PROGRAM_NAME, PROGRAM_NAME);
 
   fprintf(stream, "\
 Options:\n\
@@ -178,7 +178,7 @@ public:
 
              case 'b':
                TEST_EXTRA_ARG(i, 'b');
-               fb_size = abs(atoi(argv[i]));
+               fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
 
                if ( verbose_flag )
                  fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
@@ -188,12 +188,12 @@ public:
              case 'd':
                TEST_EXTRA_ARG(i, 'd');
                duration_flag = true;
-               duration = abs(atoi(argv[i]));
+               duration = Kumu::xabs(strtol(argv[i], 0, 10));
                break;
 
              case 'f':
                TEST_EXTRA_ARG(i, 'f');
-               start_frame = abs(atoi(argv[i]));
+               start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
                break;
 
              case 'h': help_flag = true; break;
@@ -201,12 +201,12 @@ public:
 
              case 'p':
                TEST_EXTRA_ARG(i, 'p');
-               picture_rate = abs(atoi(argv[i]));
+               picture_rate = Kumu::xabs(strtol(argv[i], 0, 10));
                break;
 
              case 's':
                TEST_EXTRA_ARG(i, 's');
-               fb_dump_size = abs(atoi(argv[i]));
+               fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10));
                break;
 
              case 'V': version_flag = true; break;
@@ -215,7 +215,7 @@ public:
 
              case 'w':
                TEST_EXTRA_ARG(i, 'w');
-               number_width = abs(atoi(argv[i]));
+               number_width = Kumu::xabs(strtol(argv[i], 0, 10));
                break;
 
              case 'Z': j2c_pedantic = false; break;
@@ -376,19 +376,34 @@ read_JP2K_file(CommandOptions& Options)
     {
       result = Reader.ReadFrame(i, FrameBuffer, Context, HMAC);
 
-      if ( ASDCP_SUCCESS(result) )
+      char filename[1024];
+      snprintf(filename, 1024, name_format, Options.file_prefix, i);
+
+      if ( ASDCP_SUCCESS(result) && Options.verbose_flag )
+       {
+         printf("Frame %d, %d bytes", i, FrameBuffer.Size());
+
+         if ( ! Options.no_write_flag )
+           {
+             printf(" -> %s", filename);
+           }
+
+         printf("\n");
+       }
+
+      if ( ASDCP_SUCCESS(result)  && ( ! Options.no_write_flag ) )
        {
          Kumu::FileWriter OutFile;
-         char filename[256];
          ui32_t write_count;
-         snprintf(filename, 256, name_format, Options.file_prefix, i);
          result = OutFile.OpenWrite(filename);
 
          if ( ASDCP_SUCCESS(result) )
            result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count);
 
-         if ( Options.verbose_flag )
-           FrameBuffer.Dump(stderr, Options.fb_dump_size);
+         if ( ASDCP_SUCCESS(result) && Options.verbose_flag )
+           {
+             FrameBuffer.Dump(stderr, Options.fb_dump_size);
+           }
        }
     }
 
@@ -420,43 +435,65 @@ read_PCM_file(CommandOptions& Options)
 
   Result_t result = Reader.OpenRead(Options.input_filename, Options.edit_rate);
 
-  if ( ASDCP_SUCCESS(result) )
+  if ( KM_SUCCESS(result) )
     {
       if ( Options.verbose_flag )
        {
          fprintf(stderr, "Frame Buffer size: %u\n", Options.fb_size);
        }
+      
+      ASDCP::MXF::InterchangeObject* tmp_obj = 0;
 
-      result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor),
-                                                    reinterpret_cast<MXF::InterchangeObject**>(&wave_descriptor));
+      result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_WaveAudioDescriptor), &tmp_obj);
 
       if ( KM_SUCCESS(result) )
        {
-         assert(wave_descriptor);
-         last_frame = wave_descriptor->ContainerDuration;
+         wave_descriptor = dynamic_cast<ASDCP::MXF::WaveAudioDescriptor*>(tmp_obj);
 
+         if ( wave_descriptor == 0 )
+           {
+             fprintf(stderr, "File does not contain an essence descriptor.\n");
+             return RESULT_FAIL;
+           }
+      
          if ( Options.verbose_flag )
            {
              wave_descriptor->Dump();
            }
-       }
-      else
-       {
-         fprintf(stderr, "File does not contain an essence descriptor.\n");
-         last_frame = Reader.AS02IndexReader().GetDuration();
-       }
 
-      if ( last_frame == 0 )
-       {
-         fprintf(stderr, "Unable to determine file duration.\n");
-         return RESULT_FAIL;
-       }
+         if ( wave_descriptor->ContainerDuration.get() == 0 )
+           {
+             fprintf(stderr, "ContainerDuration not set in file descriptor, attempting to use index duration.\n");
+             last_frame = Reader.AS02IndexReader().GetDuration();
+           }
+         else
+           {
+             last_frame = wave_descriptor->ContainerDuration;
+           }
 
-      FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate));
+         if ( last_frame == 0 )
+           {
+             fprintf(stderr, "ContainerDuration not set in index, attempting to use Duration from SourceClip.\n");
+             result = Reader.OP1aHeader().GetMDObjectByType(DefaultCompositeDict().ul(MDD_SourceClip), &tmp_obj);
+             if ( KM_SUCCESS(result))
+               {
+                 ASDCP::MXF::SourceClip *sourceClip = dynamic_cast<ASDCP::MXF::SourceClip*>(tmp_obj);
+                 if ( ! sourceClip->Duration.empty() )
+                   {
+                     last_frame = sourceClip->Duration;
+                   }
+               }
+           }
 
-      if ( Options.verbose_flag )
-       {
-         wave_descriptor->Dump();
+         if ( last_frame == 0 )
+           {
+             fprintf(stderr, "Unable to determine file duration.\n");
+             return RESULT_FAIL;
+           }
+
+         assert(wave_descriptor);
+         FrameBuffer.Capacity(AS_02::MXF::CalcFrameBufferSize(*wave_descriptor, Options.edit_rate));
+         last_frame = AS_02::MXF::CalcFramesFromDurationInSamples(last_frame, *wave_descriptor, Options.edit_rate);
        }
     }
 
@@ -522,7 +559,17 @@ read_PCM_file(CommandOptions& Options)
       if ( ASDCP_SUCCESS(result) )
        {
          if ( Options.verbose_flag )
-           FrameBuffer.Dump(stderr, Options.fb_dump_size);
+           {
+             FrameBuffer.FrameNumber(i);
+             FrameBuffer.Dump(stderr, Options.fb_dump_size);
+           }
+
+         if ( FrameBuffer.Size() != FrameBuffer.Capacity() )
+           {
+             fprintf(stderr, "Last frame is incomplete, padding with zeros.\n");
+             // actually, it has already been zeroed for us, we just need to recognize the appropriate size
+             FrameBuffer.Size(FrameBuffer.Capacity());
+           }
 
          result = OutWave.WriteFrame(FrameBuffer);
        }
@@ -561,17 +608,17 @@ main(int argc, const char** argv)
     {
       switch ( EssenceType )
        {
-       case ESS_JPEG_2000:
+       case ESS_AS02_JPEG_2000:
          result = read_JP2K_file(Options);
          break;
 
-       case ESS_PCM_24b_48k:
-       case ESS_PCM_24b_96k:
+       case ESS_AS02_PCM_24b_48k:
+       case ESS_AS02_PCM_24b_96k:
          result = read_PCM_file(Options);
          break;
 
        default:
-         fprintf(stderr, "%s: Unknown file type, not ASDCP essence.\n", Options.input_filename);
+         fprintf(stderr, "%s: Unknown file type, not AS-02 essence.\n", Options.input_filename);
          return 5;
        }
     }
@@ -580,11 +627,7 @@ main(int argc, const char** argv)
     {
       fputs("Program stopped on error.\n", stderr);
 
-      if ( result == RESULT_SFORMAT )
-       {
-         fputs("Use option '-3' to force stereoscopic mode.\n", stderr);
-       }
-      else if ( result != RESULT_FAIL )
+      if ( result != RESULT_FAIL )
        {
          fputs(result, stderr);
          fputc('\n', stderr);