Split up some files.
authorCarl Hetherington <cth@carlh.net>
Wed, 25 Sep 2013 20:31:10 +0000 (21:31 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 25 Sep 2013 20:31:10 +0000 (21:31 +0100)
28 files changed:
examples/make_dcp.cc
src/cpl.cc
src/mono_picture_asset.cc [new file with mode: 0644]
src/mono_picture_asset.h [new file with mode: 0644]
src/mono_picture_asset_writer.cc [new file with mode: 0644]
src/mono_picture_asset_writer.h [new file with mode: 0644]
src/mono_picture_frame.cc [new file with mode: 0644]
src/mono_picture_frame.h [new file with mode: 0644]
src/picture_asset.cc
src/picture_asset.h
src/picture_asset_writer.cc
src/picture_asset_writer.h
src/picture_asset_writer_common.cc [new file with mode: 0644]
src/picture_frame.cc [deleted file]
src/picture_frame.h [deleted file]
src/stereo_picture_asset.cc [new file with mode: 0644]
src/stereo_picture_asset.h [new file with mode: 0644]
src/stereo_picture_asset_writer.cc [new file with mode: 0644]
src/stereo_picture_asset_writer.h [new file with mode: 0644]
src/stereo_picture_frame.cc [new file with mode: 0644]
src/stereo_picture_frame.h [new file with mode: 0644]
src/wscript
test/dcp_test.cc
test/decryption_test.cc
test/encryption_test.cc
test/error_test.cc
test/recovery_test.cc
test/round_trip_test.cc

index 2cf0a2694cad95755dbf8729912b7fda1542e00b..6aa4268bd4051d49f7706a328efb4ae3e8e25b0c 100644 (file)
 /* If you are using an installed libdcp, these #includes would need to be changed to
 #include <libdcp/dcp.h>
 #include <libdcp/cpl.h>
-#include <libdcp/picture_asset.h>
+#include <libdcp/mono_picture_asset.h>
 ... etc. ...
 */
 
 #include "dcp.h"
 #include "cpl.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
 #include "sound_asset.h"
 #include "reel.h"
 
index 48d08035fb18b8d7e99b194918c2c8b059533a39..74cdd784ddf5ad6a7fcb52577c7c80f415615347 100644 (file)
@@ -22,7 +22,8 @@
 #include "cpl.h"
 #include "parse/cpl.h"
 #include "util.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
+#include "stereo_picture_asset.h"
 #include "sound_asset.h"
 #include "subtitle_asset.h"
 #include "parse/asset_map.h"
diff --git a/src/mono_picture_asset.cc b/src/mono_picture_asset.cc
new file mode 100644 (file)
index 0000000..7830d82
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "mono_picture_asset.h"
+#include "mono_picture_asset_writer.h"
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "exceptions.h"
+#include "mono_picture_frame.h"
+
+using std::string;
+using std::vector;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::lexical_cast;
+using namespace libdcp;
+
+MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name)
+       : PictureAsset (directory, mxf_name)
+{
+
+}
+
+void
+MonoPictureAsset::create (vector<boost::filesystem::path> const & files)
+{
+       create (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files));
+}
+
+void
+MonoPictureAsset::create (boost::function<boost::filesystem::path (int)> get_path)
+{
+       ASDCP::JP2K::CodestreamParser j2k_parser;
+       ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
+       if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (get_path(0).c_str(), frame_buffer))) {
+               boost::throw_exception (FileError ("could not open JPEG2000 file for reading", get_path (0)));
+       }
+       
+       ASDCP::JP2K::PictureDescriptor picture_desc;
+       j2k_parser.FillPictureDescriptor (picture_desc);
+       picture_desc.EditRate = ASDCP::Rational (_edit_rate, 1);
+       
+       ASDCP::WriterInfo writer_info;
+       fill_writer_info (&writer_info, _uuid, _interop, _metadata);
+       
+       ASDCP::JP2K::MXFWriter mxf_writer;
+       if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, picture_desc, 16384, false))) {
+               boost::throw_exception (MXFFileError ("could not open MXF file for writing", path().string()));
+       }
+
+       for (int i = 0; i < _intrinsic_duration; ++i) {
+
+               boost::filesystem::path const path = get_path (i);
+
+               if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (path.c_str(), frame_buffer))) {
+                       boost::throw_exception (FileError ("could not open JPEG2000 file for reading", path));
+               }
+
+               if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, _encryption_context, 0))) {
+                       boost::throw_exception (MXFFileError ("error in writing video MXF", this->path().string()));
+               }
+
+               if (_progress) {
+                       (*_progress) (0.5 * float (i) / _intrinsic_duration);
+               }
+       }
+       
+       if (ASDCP_FAILURE (mxf_writer.Finalize())) {
+               boost::throw_exception (MXFFileError ("error in finalising video MXF", path().string()));
+       }
+}
+
+void
+MonoPictureAsset::read ()
+{
+       ASDCP::JP2K::MXFReader reader;
+       if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
+               boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string()));
+       }
+       
+       ASDCP::JP2K::PictureDescriptor desc;
+       if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) {
+               boost::throw_exception (DCPReadError ("could not read video MXF information"));
+       }
+
+       _size.width = desc.StoredWidth;
+       _size.height = desc.StoredHeight;
+       _edit_rate = desc.EditRate.Numerator;
+       assert (desc.EditRate.Denominator == 1);
+       _intrinsic_duration = desc.ContainerDuration;
+}
+
+boost::filesystem::path
+MonoPictureAsset::path_from_list (int f, vector<boost::filesystem::path> const & files) const
+{
+       return files[f];
+}
+
+shared_ptr<const MonoPictureFrame>
+MonoPictureAsset::get_frame (int n) const
+{
+       return shared_ptr<const MonoPictureFrame> (new MonoPictureFrame (path().string(), n, _decryption_context));
+}
+
+bool
+MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
+{
+       if (!PictureAsset::equals (other, opt, note)) {
+               return false;
+       }
+
+       shared_ptr<const MonoPictureAsset> other_picture = dynamic_pointer_cast<const MonoPictureAsset> (other);
+       assert (other_picture);
+
+       for (int i = 0; i < _intrinsic_duration; ++i) {
+               if (i >= other_picture->intrinsic_duration()) {
+                       return false;
+               }
+               
+               note (PROGRESS, "Comparing video frame " + lexical_cast<string> (i) + " of " + lexical_cast<string> (_intrinsic_duration));
+               shared_ptr<const MonoPictureFrame> frame_A = get_frame (i);
+               shared_ptr<const MonoPictureFrame> frame_B = other_picture->get_frame (i);
+               
+               if (!frame_buffer_equals (
+                           i, opt, note,
+                           frame_A->j2k_data(), frame_A->j2k_size(),
+                           frame_B->j2k_data(), frame_B->j2k_size()
+                           )) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+shared_ptr<PictureAssetWriter>
+MonoPictureAsset::start_write (bool overwrite)
+{
+       /* XXX: can't we use shared_ptr here? */
+       return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this, overwrite));
+}
+
+string
+MonoPictureAsset::cpl_node_name () const
+{
+       return "MainPicture";
+}
+
+int
+MonoPictureAsset::edit_rate_factor () const
+{
+       return 1;
+}
diff --git a/src/mono_picture_asset.h b/src/mono_picture_asset.h
new file mode 100644 (file)
index 0000000..6ade93b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef LIBDCP_MONO_PICTURE_ASSET_H
+#define LIBDCP_MONO_PICTURE_ASSET_H
+
+#include "picture_asset.h"
+
+namespace libdcp {
+
+/** A 2D (monoscopic) picture asset */
+class MonoPictureAsset : public PictureAsset
+{
+public:
+       MonoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
+
+       void read ();
+       void create (std::vector<boost::filesystem::path> const & files);
+       void create (boost::function<boost::filesystem::path (int)> get_path);
+
+       /** Start a progressive write to a MonoPictureAsset */
+       boost::shared_ptr<PictureAssetWriter> start_write (bool);
+
+       boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
+       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
+
+private:
+       boost::filesystem::path path_from_list (int f, std::vector<boost::filesystem::path> const & files) const;
+       void construct (boost::function<boost::filesystem::path (int)>, bool, MXFMetadata const &);
+       std::string cpl_node_name () const;
+       int edit_rate_factor () const;
+};
+
+}      
+
+#endif
diff --git a/src/mono_picture_asset_writer.cc b/src/mono_picture_asset_writer.cc
new file mode 100644 (file)
index 0000000..1f384c2
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "mono_picture_asset_writer.h"
+#include "exceptions.h"
+#include "picture_asset.h"
+
+#include "picture_asset_writer_common.cc"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace libdcp;
+
+struct MonoPictureAssetWriter::ASDCPState : public ASDCPStateBase
+{
+       ASDCP::JP2K::MXFWriter mxf_writer;
+};
+
+/** @param a Asset to write to.  `a' must not be deleted while
+ *  this writer class still exists, or bad things will happen.
+ */
+MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, bool overwrite)
+       : PictureAssetWriter (asset, overwrite)
+       , _state (new MonoPictureAssetWriter::ASDCPState)
+{
+       _state->encryption_context = asset->encryption_context ();
+}
+
+void
+MonoPictureAssetWriter::start (uint8_t* data, int size)
+{
+       libdcp::start (this, _state, _asset, data, size);
+}
+
+FrameInfo
+MonoPictureAssetWriter::write (uint8_t* data, int size)
+{
+       assert (!_finalized);
+
+       if (!_started) {
+               start (data, size);
+       }
+
+       if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
+               boost::throw_exception (MiscError ("could not parse J2K frame"));
+       }
+
+       uint64_t const before_offset = _state->mxf_writer.Tell ();
+
+       string hash;
+       if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0, &hash))) {
+               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
+       }
+
+       ++_frames_written;
+       return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
+}
+
+void
+MonoPictureAssetWriter::fake_write (int size)
+{
+       assert (_started);
+       assert (!_finalized);
+
+       if (ASDCP_FAILURE (_state->mxf_writer.FakeWriteFrame (size))) {
+               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
+       }
+
+       ++_frames_written;
+}
+
+void
+MonoPictureAssetWriter::finalize ()
+{
+       assert (!_finalized);
+       
+       if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
+               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string()));
+       }
+
+       _finalized = true;
+       _asset->set_intrinsic_duration (_frames_written);
+       _asset->set_duration (_frames_written);
+}
+
diff --git a/src/mono_picture_asset_writer.h b/src/mono_picture_asset_writer.h
new file mode 100644 (file)
index 0000000..e392262
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <stdint.h>
+#include <string>
+#include <fstream>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "picture_asset_writer.h"
+
+namespace libdcp {
+
+/** A helper class for writing to MonoPictureAssets progressively (i.e. writing frame-by-frame,
+ *  rather than giving libdcp all the frames in one go).
+ *
+ *  Objects of this class can only be created with MonoPictureAsset::start_write().
+ *
+ *  Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
+ *  (a verbatim .j2c file).  finalize() must be called after the last frame has been written.
+ *  The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
+ *  throw an exception.
+ */
+class MonoPictureAssetWriter : public PictureAssetWriter
+{
+public:
+       FrameInfo write (uint8_t *, int);
+       void fake_write (int size);
+       void finalize ();
+
+private:
+       friend class MonoPictureAsset;
+
+       MonoPictureAssetWriter (PictureAsset *, bool);
+       void start (uint8_t *, int);
+
+       /* do this with an opaque pointer so we don't have to include
+          ASDCP headers
+       */
+          
+       struct ASDCPState;
+       boost::shared_ptr<ASDCPState> _state;
+};
+
+}
diff --git a/src/mono_picture_frame.cc b/src/mono_picture_frame.cc
new file mode 100644 (file)
index 0000000..474b071
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <openjpeg.h>
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "mono_picture_frame.h"
+#include "exceptions.h"
+#include "argb_frame.h"
+#include "lut.h"
+#include "util.h"
+#include "gamma_lut.h"
+#include "rgb_xyz.h"
+
+#define DCI_GAMMA 2.6
+
+using std::string;
+using boost::shared_ptr;
+using namespace libdcp;
+
+/** Make a picture frame from a 2D (monoscopic) asset.
+ *  @param mxf_path Path to the asset's MXF file.
+ *  @param n Frame within the asset, not taking EntryPoint into account.
+ */
+MonoPictureFrame::MonoPictureFrame (string mxf_path, int n, ASDCP::AESDecContext* c)
+{
+       ASDCP::JP2K::MXFReader reader;
+       if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) {
+               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path));
+       }
+
+       /* XXX: unfortunate guesswork on this buffer size */
+       _buffer = new ASDCP::JP2K::FrameBuffer (4 * Kumu::Megabyte);
+
+       if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer, c))) {
+               boost::throw_exception (DCPReadError ("could not read video frame"));
+       }
+}
+
+MonoPictureFrame::~MonoPictureFrame ()
+{
+       delete _buffer;
+}
+
+uint8_t const *
+MonoPictureFrame::j2k_data () const
+{
+       return _buffer->RoData ();
+}
+
+int
+MonoPictureFrame::j2k_size () const
+{
+       return _buffer->Size ();
+}
+
+/** @param reduce a factor by which to reduce the resolution
+ *  of the image, expressed as a power of two (pass 0 for no
+ *  reduction).
+ *
+ *  @return An ARGB representation of this frame.  This is ARGB in the
+ *  Cairo sense, so that each pixel takes up 4 bytes; the first byte
+ *  is blue, second green, third red and fourth alpha (always 255).
+ *
+ */
+shared_ptr<ARGBFrame>
+MonoPictureFrame::argb_frame (int reduce, float srgb_gamma) const
+{
+       return xyz_to_rgb (
+               decompress_j2k (const_cast<uint8_t*> (_buffer->RoData()), _buffer->Size(), reduce),
+               GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma)
+               );
+}
diff --git a/src/mono_picture_frame.h b/src/mono_picture_frame.h
new file mode 100644 (file)
index 0000000..83b80c5
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <string>
+#include <stdint.h>
+#include <boost/shared_ptr.hpp>
+#include "types.h"
+
+namespace ASDCP {
+       namespace JP2K {
+               class FrameBuffer;
+       }
+       class AESDecContext;
+}
+
+namespace libdcp {
+
+class ARGBFrame;
+
+/** A single frame of a 2D (monoscopic) picture asset */       
+class MonoPictureFrame
+{
+public:
+       MonoPictureFrame (std::string mxf_path, int n, ASDCP::AESDecContext *);
+       ~MonoPictureFrame ();
+
+       boost::shared_ptr<ARGBFrame> argb_frame (int reduce = 0, float srgb_gamma = 2.4) const;
+       uint8_t const * j2k_data () const;
+       int j2k_size () const;
+
+private:
+       ASDCP::JP2K::FrameBuffer* _buffer;
+};
+
+}
index 97fce2abf1c497fb0ef0f6a35223c84057507a55..12032328522c20be17c95ba8f50152337f23e8a7 100644 (file)
@@ -35,7 +35,6 @@
 #include "picture_asset.h"
 #include "util.h"
 #include "exceptions.h"
-#include "picture_frame.h"
 #include "xyz_frame.h"
 #include "picture_asset_writer.h"
 
@@ -144,158 +143,6 @@ PictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost:
        return true;
 }
 
-MonoPictureAsset::MonoPictureAsset (boost::filesystem::path directory, string mxf_name)
-       : PictureAsset (directory, mxf_name)
-{
-
-}
-
-void
-MonoPictureAsset::create (vector<boost::filesystem::path> const & files)
-{
-       create (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files));
-}
-
-void
-MonoPictureAsset::create (boost::function<boost::filesystem::path (int)> get_path)
-{
-       ASDCP::JP2K::CodestreamParser j2k_parser;
-       ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte);
-       if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (get_path(0).c_str(), frame_buffer))) {
-               boost::throw_exception (FileError ("could not open JPEG2000 file for reading", get_path (0)));
-       }
-       
-       ASDCP::JP2K::PictureDescriptor picture_desc;
-       j2k_parser.FillPictureDescriptor (picture_desc);
-       picture_desc.EditRate = ASDCP::Rational (_edit_rate, 1);
-       
-       ASDCP::WriterInfo writer_info;
-       fill_writer_info (&writer_info, _uuid, _interop, _metadata);
-       
-       ASDCP::JP2K::MXFWriter mxf_writer;
-       if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, picture_desc, 16384, false))) {
-               boost::throw_exception (MXFFileError ("could not open MXF file for writing", path().string()));
-       }
-
-       for (int i = 0; i < _intrinsic_duration; ++i) {
-
-               boost::filesystem::path const path = get_path (i);
-
-               if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (path.c_str(), frame_buffer))) {
-                       boost::throw_exception (FileError ("could not open JPEG2000 file for reading", path));
-               }
-
-               if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, _encryption_context, 0))) {
-                       boost::throw_exception (MXFFileError ("error in writing video MXF", this->path().string()));
-               }
-
-               if (_progress) {
-                       (*_progress) (0.5 * float (i) / _intrinsic_duration);
-               }
-       }
-       
-       if (ASDCP_FAILURE (mxf_writer.Finalize())) {
-               boost::throw_exception (MXFFileError ("error in finalising video MXF", path().string()));
-       }
-}
-
-void
-MonoPictureAsset::read ()
-{
-       ASDCP::JP2K::MXFReader reader;
-       if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
-               boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string()));
-       }
-       
-       ASDCP::JP2K::PictureDescriptor desc;
-       if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) {
-               boost::throw_exception (DCPReadError ("could not read video MXF information"));
-       }
-
-       _size.width = desc.StoredWidth;
-       _size.height = desc.StoredHeight;
-       _edit_rate = desc.EditRate.Numerator;
-       assert (desc.EditRate.Denominator == 1);
-       _intrinsic_duration = desc.ContainerDuration;
-}
-
-boost::filesystem::path
-MonoPictureAsset::path_from_list (int f, vector<boost::filesystem::path> const & files) const
-{
-       return files[f];
-}
-
-shared_ptr<const MonoPictureFrame>
-MonoPictureAsset::get_frame (int n) const
-{
-       return shared_ptr<const MonoPictureFrame> (new MonoPictureFrame (path().string(), n, _decryption_context));
-}
-
-bool
-MonoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
-{
-       if (!PictureAsset::equals (other, opt, note)) {
-               return false;
-       }
-
-       shared_ptr<const MonoPictureAsset> other_picture = dynamic_pointer_cast<const MonoPictureAsset> (other);
-       assert (other_picture);
-
-       for (int i = 0; i < _intrinsic_duration; ++i) {
-               if (i >= other_picture->intrinsic_duration()) {
-                       return false;
-               }
-               
-               note (PROGRESS, "Comparing video frame " + lexical_cast<string> (i) + " of " + lexical_cast<string> (_intrinsic_duration));
-               shared_ptr<const MonoPictureFrame> frame_A = get_frame (i);
-               shared_ptr<const MonoPictureFrame> frame_B = other_picture->get_frame (i);
-               
-               if (!frame_buffer_equals (
-                           i, opt, note,
-                           frame_A->j2k_data(), frame_A->j2k_size(),
-                           frame_B->j2k_data(), frame_B->j2k_size()
-                           )) {
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-bool
-StereoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
-{
-       if (!PictureAsset::equals (other, opt, note)) {
-               return false;
-       }
-       
-       shared_ptr<const StereoPictureAsset> other_picture = dynamic_pointer_cast<const StereoPictureAsset> (other);
-       assert (other_picture);
-
-       for (int i = 0; i < _intrinsic_duration; ++i) {
-               shared_ptr<const StereoPictureFrame> frame_A = get_frame (i);
-               shared_ptr<const StereoPictureFrame> frame_B = other_picture->get_frame (i);
-               
-               if (!frame_buffer_equals (
-                           i, opt, note,
-                           frame_A->left_j2k_data(), frame_A->left_j2k_size(),
-                           frame_B->left_j2k_data(), frame_B->left_j2k_size()
-                           )) {
-                       return false;
-               }
-               
-               if (!frame_buffer_equals (
-                           i, opt, note,
-                           frame_A->right_j2k_data(), frame_A->right_j2k_size(),
-                           frame_B->right_j2k_data(), frame_B->right_j2k_size()
-                           )) {
-                       return false;
-               }
-       }
-
-       return true;
-}
-
 bool
 PictureAsset::frame_buffer_equals (
        int frame, EqualityOptions opt, boost::function<void (NoteType, string)> note,
@@ -350,100 +197,35 @@ PictureAsset::frame_buffer_equals (
        note (NOTE, "mean difference " + lexical_cast<string> (mean) + ", deviation " + lexical_cast<string> (std_dev));
        
        if (mean > opt.max_mean_pixel_error) {
-               note (ERROR, "mean " + lexical_cast<string>(mean) + " out of range " + lexical_cast<string>(opt.max_mean_pixel_error) + " in frame " + lexical_cast<string>(frame));
+               note (
+                       ERROR,
+                       "mean " + lexical_cast<string>(mean) +
+                       " out of range " + lexical_cast<string>(opt.max_mean_pixel_error) +
+                       " in frame " + lexical_cast<string>(frame)
+                       );
+               
                return false;
        }
 
        if (std_dev > opt.max_std_dev_pixel_error) {
-               note (ERROR, "standard deviation " + lexical_cast<string>(std_dev) + " out of range " + lexical_cast<string>(opt.max_std_dev_pixel_error) + " in frame " + lexical_cast<string>(frame));
+               note (
+                       ERROR,
+                       "standard deviation " + lexical_cast<string>(std_dev) +
+                       " out of range " + lexical_cast<string>(opt.max_std_dev_pixel_error) +
+                       " in frame " + lexical_cast<string>(frame)
+                       );
+               
                return false;
        }
 
        return true;
 }
 
-
-StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, string mxf_name)
-       : PictureAsset (directory, mxf_name)
-{
-       
-}
-
-void
-StereoPictureAsset::read ()
-{
-       ASDCP::JP2K::MXFSReader reader;
-       if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
-               boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string()));
-       }
-       
-       ASDCP::JP2K::PictureDescriptor desc;
-       if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) {
-               boost::throw_exception (DCPReadError ("could not read video MXF information"));
-       }
-
-       _size.width = desc.StoredWidth;
-       _size.height = desc.StoredHeight;
-}
-
-shared_ptr<const StereoPictureFrame>
-StereoPictureAsset::get_frame (int n) const
-{
-       return shared_ptr<const StereoPictureFrame> (new StereoPictureFrame (path().string(), n));
-}
-
-shared_ptr<PictureAssetWriter>
-MonoPictureAsset::start_write (bool overwrite)
-{
-       /* XXX: can't we use shared_ptr here? */
-       return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this, overwrite));
-}
-
 string
 PictureAsset::key_type () const
 {
        return "MDIK";
 }
 
-shared_ptr<PictureAssetWriter>
-StereoPictureAsset::start_write (bool overwrite)
-{
-       return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, overwrite));
-}
-
-string
-MonoPictureAsset::cpl_node_name () const
-{
-       return "MainPicture";
-}
-
-int
-MonoPictureAsset::edit_rate_factor () const
-{
-       return 1;
-}
-
-string
-StereoPictureAsset::cpl_node_name () const
-{
-       return "msp-cpl:MainStereoscopicPicture";
-}
 
-pair<string, string>
-StereoPictureAsset::cpl_node_attribute (bool interop) const
-{
-       if (interop) {
-               return make_pair ("xmlns:msp-cpl", "http://www.digicine.com/schemas/437-Y/2007/Main-Stereo-Picture-CPL");
-       } else {
-               return make_pair ("xmlns:msp-cpl", "http://www.smpte-ra.org/schemas/429-10/2008/Main-Stereo-Picture-CPL");
-       }
-
-       return make_pair ("", "");
-}
-
-int
-StereoPictureAsset::edit_rate_factor () const
-{
-       return 2;
-}
 
index d1b097fab6d49b9e757a77a46f9b5729445c6e0b..53231418ace0c90558898e8a51484db1fc9c8d1e 100644 (file)
@@ -41,7 +41,6 @@ class PictureAsset : public MXFAsset
 {
 public:
        /** Construct a PictureAsset.
-        *  This class will not write anything to disk in this constructor, but subclasses may.
         *  
         *  @param directory Directory where MXF file is.
         *  @param mxf_name Name of MXF file.
@@ -84,49 +83,6 @@ private:
        std::string key_type () const;
        virtual int edit_rate_factor () const = 0;
 };
-
-/** A 2D (monoscopic) picture asset */
-class MonoPictureAsset : public PictureAsset
-{
-public:
-       MonoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
-
-       void read ();
-       void create (std::vector<boost::filesystem::path> const & files);
-       void create (boost::function<boost::filesystem::path (int)> get_path);
-
-       /** Start a progressive write to a MonoPictureAsset */
-       boost::shared_ptr<PictureAssetWriter> start_write (bool);
-
-       boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
-       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
-
-private:
-       boost::filesystem::path path_from_list (int f, std::vector<boost::filesystem::path> const & files) const;
-       void construct (boost::function<boost::filesystem::path (int)>, bool, MXFMetadata const &);
-       std::string cpl_node_name () const;
-       int edit_rate_factor () const;
-};
-
-/** A 3D (stereoscopic) picture asset */       
-class StereoPictureAsset : public PictureAsset
-{
-public:
-       StereoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
-
-       void read ();
-       
-       /** Start a progressive write to a StereoPictureAsset */
-       boost::shared_ptr<PictureAssetWriter> start_write (bool);
-
-       boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
-       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
-
-private:
-       std::string cpl_node_name () const;
-       std::pair<std::string, std::string> cpl_node_attribute (bool) const;
-       int edit_rate_factor () const;
-};
        
 
 }
index ca5a3e961605e1b43df84d437967af442d5ba110..67883e31f1afcd729c83eb131059717d7cf5aa60 100644 (file)
@@ -61,198 +61,3 @@ PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, bool overwrite)
 {
 
 }
-
-struct ASDCPStateBase
-{
-       ASDCPStateBase ()
-               : frame_buffer (4 * Kumu::Megabyte)
-       {}
-       
-       ASDCP::JP2K::CodestreamParser j2k_parser;
-       ASDCP::JP2K::FrameBuffer frame_buffer;
-       ASDCP::WriterInfo writer_info;
-       ASDCP::JP2K::PictureDescriptor picture_descriptor;
-       ASDCP::AESEncContext* encryption_context;
-};
-
-struct MonoPictureAssetWriter::ASDCPState : public ASDCPStateBase
-{
-       ASDCP::JP2K::MXFWriter mxf_writer;
-};
-
-struct StereoPictureAssetWriter::ASDCPState : public ASDCPStateBase
-{
-       ASDCP::JP2K::MXFSWriter mxf_writer;
-};
-
-/** @param a Asset to write to.  `a' must not be deleted while
- *  this writer class still exists, or bad things will happen.
- */
-MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, bool overwrite)
-       : PictureAssetWriter (asset, overwrite)
-       , _state (new MonoPictureAssetWriter::ASDCPState)
-{
-       _state->encryption_context = asset->encryption_context ();
-}
-
-StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool overwrite)
-       : PictureAssetWriter (asset, overwrite)
-       , _state (new StereoPictureAssetWriter::ASDCPState)
-       , _next_eye (EYE_LEFT)
-{
-       _state->encryption_context = asset->encryption_context ();
-}
-
-template <class P, class Q>
-void libdcp::start (PictureAssetWriter* writer, shared_ptr<P> state, Q* asset, uint8_t* data, int size)
-{
-       if (ASDCP_FAILURE (state->j2k_parser.OpenReadFrame (data, size, state->frame_buffer))) {
-               boost::throw_exception (MiscError ("could not parse J2K frame"));
-       }
-
-       state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
-       state->picture_descriptor.EditRate = ASDCP::Rational (asset->edit_rate(), 1);
-       
-       asset->fill_writer_info (&state->writer_info, asset->uuid(), writer->_asset->interop(), writer->_asset->metadata());
-       
-       if (ASDCP_FAILURE (state->mxf_writer.OpenWrite (
-                                  asset->path().string().c_str(),
-                                  state->writer_info,
-                                  state->picture_descriptor,
-                                  16384,
-                                  writer->_overwrite)
-                   )) {
-               
-               boost::throw_exception (MXFFileError ("could not open MXF file for writing", asset->path().string()));
-       }
-
-       writer->_started = true;
-}
-
-void
-MonoPictureAssetWriter::start (uint8_t* data, int size)
-{
-       libdcp::start (this, _state, _asset, data, size);
-}
-
-void
-StereoPictureAssetWriter::start (uint8_t* data, int size)
-{
-       libdcp::start (this, _state, _asset, data, size);
-}
-
-FrameInfo
-MonoPictureAssetWriter::write (uint8_t* data, int size)
-{
-       assert (!_finalized);
-
-       if (!_started) {
-               start (data, size);
-       }
-
-       if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
-               boost::throw_exception (MiscError ("could not parse J2K frame"));
-       }
-
-       uint64_t const before_offset = _state->mxf_writer.Tell ();
-
-       string hash;
-       if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0, &hash))) {
-               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
-       }
-
-       ++_frames_written;
-       return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
-}
-
-/** Write a frame for one eye.  Frames must be written left, then right, then left etc.
- *  @param data JPEG2000 data.
- *  @param size Size of data.
- */
-FrameInfo
-StereoPictureAssetWriter::write (uint8_t* data, int size)
-{
-       assert (!_finalized);
-
-       if (!_started) {
-               start (data, size);
-       }
-
-       if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
-               boost::throw_exception (MiscError ("could not parse J2K frame"));
-       }
-
-       uint64_t const before_offset = _state->mxf_writer.Tell ();
-
-       string hash;
-       if (ASDCP_FAILURE (
-                   _state->mxf_writer.WriteFrame (
-                           _state->frame_buffer,
-                           _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT,
-                           _state->encryption_context,
-                           0,
-                           &hash)
-                   )) {
-               
-               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
-       }
-
-       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
-
-       return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
-}
-
-void
-MonoPictureAssetWriter::fake_write (int size)
-{
-       assert (_started);
-       assert (!_finalized);
-
-       if (ASDCP_FAILURE (_state->mxf_writer.FakeWriteFrame (size))) {
-               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
-       }
-
-       ++_frames_written;
-}
-
-void
-StereoPictureAssetWriter::fake_write (int size)
-{
-       assert (_started);
-       assert (!_finalized);
-
-       if (ASDCP_FAILURE (_state->mxf_writer.FakeWriteFrame (size))) {
-               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
-       }
-
-       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
-       ++_frames_written;
-}
-
-void
-MonoPictureAssetWriter::finalize ()
-{
-       assert (!_finalized);
-       
-       if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
-               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string()));
-       }
-
-       _finalized = true;
-       _asset->set_intrinsic_duration (_frames_written);
-       _asset->set_duration (_frames_written);
-}
-
-void
-StereoPictureAssetWriter::finalize ()
-{
-       assert (!_finalized);
-       
-       if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
-               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string()));
-       }
-
-       _finalized = true;
-       _asset->set_intrinsic_duration (_frames_written / 2);
-       _asset->set_duration (_frames_written / 2);
-}
index fd4f81eee7507285d59b4101ac2741e870c016f9..bc2f65e50fb1e397e3ef10b5aa048452235f8662 100644 (file)
@@ -73,68 +73,4 @@ protected:
        bool _overwrite;
 };
 
-/** A helper class for writing to MonoPictureAssets progressively (i.e. writing frame-by-frame,
- *  rather than giving libdcp all the frames in one go).
- *
- *  Objects of this class can only be created with MonoPictureAsset::start_write().
- *
- *  Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
- *  (a verbatim .j2c file).  finalize() must be called after the last frame has been written.
- *  The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
- *  throw an exception.
- */
-class MonoPictureAssetWriter : public PictureAssetWriter
-{
-public:
-       FrameInfo write (uint8_t *, int);
-       void fake_write (int size);
-       void finalize ();
-
-private:
-       friend class MonoPictureAsset;
-
-       MonoPictureAssetWriter (PictureAsset *, bool);
-       void start (uint8_t *, int);
-
-       /* do this with an opaque pointer so we don't have to include
-          ASDCP headers
-       */
-          
-       struct ASDCPState;
-       boost::shared_ptr<ASDCPState> _state;
-};
-
-/** A helper class for writing to StereoPictureAssets progressively (i.e. writing frame-by-frame,
- *  rather than giving libdcp all the frames in one go).
- *
- *  Objects of this class can only be created with StereoPictureAsset::start_write().
- *
- *  Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
- *  (a verbatim .j2c file).  finalize() must be called after the last frame has been written.
- *  The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
- *  throw an exception.
- */
-class StereoPictureAssetWriter : public PictureAssetWriter
-{
-public:
-       FrameInfo write (uint8_t *, int);
-       void fake_write (int size);
-       void finalize ();
-
-private:
-       friend class StereoPictureAsset;
-
-       StereoPictureAssetWriter (PictureAsset *, bool);
-       void start (uint8_t *, int);
-
-       /* do this with an opaque pointer so we don't have to include
-          ASDCP headers
-       */
-          
-       struct ASDCPState;
-       boost::shared_ptr<ASDCPState> _state;
-
-       libdcp::Eye _next_eye;
-};
-
 }
diff --git a/src/picture_asset_writer_common.cc b/src/picture_asset_writer_common.cc
new file mode 100644 (file)
index 0000000..9499913
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+using boost::shared_ptr;
+
+struct ASDCPStateBase
+{
+       ASDCPStateBase ()
+               : frame_buffer (4 * Kumu::Megabyte)
+       {}
+       
+       ASDCP::JP2K::CodestreamParser j2k_parser;
+       ASDCP::JP2K::FrameBuffer frame_buffer;
+       ASDCP::WriterInfo writer_info;
+       ASDCP::JP2K::PictureDescriptor picture_descriptor;
+       ASDCP::AESEncContext* encryption_context;
+};
+
+template <class P, class Q>
+void libdcp::start (PictureAssetWriter* writer, shared_ptr<P> state, Q* asset, uint8_t* data, int size)
+{
+       if (ASDCP_FAILURE (state->j2k_parser.OpenReadFrame (data, size, state->frame_buffer))) {
+               boost::throw_exception (MiscError ("could not parse J2K frame"));
+       }
+
+       state->j2k_parser.FillPictureDescriptor (state->picture_descriptor);
+       state->picture_descriptor.EditRate = ASDCP::Rational (asset->edit_rate(), 1);
+       
+       asset->fill_writer_info (&state->writer_info, asset->uuid(), writer->_asset->interop(), writer->_asset->metadata());
+       
+       if (ASDCP_FAILURE (state->mxf_writer.OpenWrite (
+                                  asset->path().string().c_str(),
+                                  state->writer_info,
+                                  state->picture_descriptor,
+                                  16384,
+                                  writer->_overwrite)
+                   )) {
+               
+               boost::throw_exception (MXFFileError ("could not open MXF file for writing", asset->path().string()));
+       }
+
+       writer->_started = true;
+}
diff --git a/src/picture_frame.cc b/src/picture_frame.cc
deleted file mode 100644 (file)
index 07a2b07..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <openjpeg.h>
-#include "AS_DCP.h"
-#include "KM_fileio.h"
-#include "picture_frame.h"
-#include "exceptions.h"
-#include "argb_frame.h"
-#include "lut.h"
-#include "util.h"
-#include "gamma_lut.h"
-#include "rgb_xyz.h"
-
-#define DCI_GAMMA 2.6
-
-using std::string;
-using boost::shared_ptr;
-using namespace libdcp;
-
-/** Make a picture frame from a 2D (monoscopic) asset.
- *  @param mxf_path Path to the asset's MXF file.
- *  @param n Frame within the asset, not taking EntryPoint into account.
- */
-MonoPictureFrame::MonoPictureFrame (string mxf_path, int n, ASDCP::AESDecContext* c)
-{
-       ASDCP::JP2K::MXFReader reader;
-       if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) {
-               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path));
-       }
-
-       /* XXX: unfortunate guesswork on this buffer size */
-       _buffer = new ASDCP::JP2K::FrameBuffer (4 * Kumu::Megabyte);
-
-       if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer, c))) {
-               boost::throw_exception (DCPReadError ("could not read video frame"));
-       }
-}
-
-MonoPictureFrame::~MonoPictureFrame ()
-{
-       delete _buffer;
-}
-
-uint8_t const *
-MonoPictureFrame::j2k_data () const
-{
-       return _buffer->RoData ();
-}
-
-int
-MonoPictureFrame::j2k_size () const
-{
-       return _buffer->Size ();
-}
-
-/** @param reduce a factor by which to reduce the resolution
- *  of the image, expressed as a power of two (pass 0 for no
- *  reduction).
- *
- *  @return An ARGB representation of this frame.  This is ARGB in the
- *  Cairo sense, so that each pixel takes up 4 bytes; the first byte
- *  is blue, second green, third red and fourth alpha (always 255).
- *
- */
-shared_ptr<ARGBFrame>
-MonoPictureFrame::argb_frame (int reduce, float srgb_gamma) const
-{
-       return xyz_to_rgb (
-               decompress_j2k (const_cast<uint8_t*> (_buffer->RoData()), _buffer->Size(), reduce),
-               GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma)
-               );
-}
-
-/** Make a picture frame from a 3D (stereoscopic) asset.
- *  @param mxf_path Path to the asset's MXF file.
- *  @param n Frame within the asset, not taking EntryPoint into account.
- */
-StereoPictureFrame::StereoPictureFrame (string mxf_path, int n)
-{
-       ASDCP::JP2K::MXFSReader reader;
-       if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) {
-               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path));
-       }
-
-       /* XXX: unfortunate guesswork on this buffer size */
-       _buffer = new ASDCP::JP2K::SFrameBuffer (4 * Kumu::Megabyte);
-
-       if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer))) {
-               boost::throw_exception (DCPReadError ("could not read video frame"));
-       }
-}
-
-StereoPictureFrame::~StereoPictureFrame ()
-{
-       delete _buffer;
-}
-
-/** @param reduce a factor by which to reduce the resolution
- *  of the image, expressed as a power of two (pass 0 for no
- *  reduction).
- *
- *  @param eye Eye to return (EYE_LEFT or EYE_RIGHT).
- *
- *  @return An ARGB representation of one of the eyes (left or right)
- *  of this frame.  This is ARGB in the Cairo sense, so that each
- *  pixel takes up 4 bytes; the first byte is blue, second green,
- *  third red and fourth alpha (always 255).
- *
- */
-shared_ptr<ARGBFrame>
-StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const
-{
-       shared_ptr<XYZFrame> xyz_frame;
-       switch (eye) {
-       case LEFT:
-               xyz_frame = decompress_j2k (const_cast<uint8_t*> (_buffer->Left.RoData()), _buffer->Left.Size(), reduce);
-               break;
-       case RIGHT:
-               xyz_frame = decompress_j2k (const_cast<uint8_t*> (_buffer->Right.RoData()), _buffer->Right.Size(), reduce);
-               break;
-       }
-       
-       return xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma));
-}
-
-uint8_t const *
-StereoPictureFrame::left_j2k_data () const
-{
-       return _buffer->Left.RoData ();
-}
-
-int
-StereoPictureFrame::left_j2k_size () const
-{
-       return _buffer->Left.Size ();
-}
-
-uint8_t const *
-StereoPictureFrame::right_j2k_data () const
-{
-       return _buffer->Right.RoData ();
-}
-
-int
-StereoPictureFrame::right_j2k_size () const
-{
-       return _buffer->Right.Size ();
-}
diff --git a/src/picture_frame.h b/src/picture_frame.h
deleted file mode 100644 (file)
index 1c17e50..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <string>
-#include <stdint.h>
-#include <boost/shared_ptr.hpp>
-#include "types.h"
-
-namespace ASDCP {
-       namespace JP2K {
-               class FrameBuffer;
-               class SFrameBuffer;
-       }
-       class AESDecContext;
-}
-
-namespace libdcp {
-
-class ARGBFrame;
-
-/** A single frame of a 2D (monoscopic) picture asset */       
-class MonoPictureFrame
-{
-public:
-       MonoPictureFrame (std::string mxf_path, int n, ASDCP::AESDecContext *);
-       ~MonoPictureFrame ();
-
-       boost::shared_ptr<ARGBFrame> argb_frame (int reduce = 0, float srgb_gamma = 2.4) const;
-       uint8_t const * j2k_data () const;
-       int j2k_size () const;
-
-private:
-       ASDCP::JP2K::FrameBuffer* _buffer;
-};
-
-/** A single frame of a 3D (stereoscopic) picture asset */     
-class StereoPictureFrame
-{
-public:
-       StereoPictureFrame (std::string mxf_path, int n);
-       ~StereoPictureFrame ();
-
-       boost::shared_ptr<ARGBFrame> argb_frame (Eye eye, int reduce = 0, float srgb_gamma = 2.4) const;
-       uint8_t const * left_j2k_data () const;
-       int left_j2k_size () const;
-       uint8_t const * right_j2k_data () const;
-       int right_j2k_size () const;
-
-private:
-       ASDCP::JP2K::SFrameBuffer* _buffer;
-};
-
-}
diff --git a/src/stereo_picture_asset.cc b/src/stereo_picture_asset.cc
new file mode 100644 (file)
index 0000000..433659f
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "AS_DCP.h"
+#include "stereo_picture_asset.h"
+#include "stereo_picture_frame.h"
+#include "exceptions.h"
+#include "stereo_picture_asset_writer.h"
+
+using std::string;
+using std::pair;
+using std::make_pair;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using namespace libdcp;
+
+bool
+StereoPictureAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, string)> note) const
+{
+       if (!PictureAsset::equals (other, opt, note)) {
+               return false;
+       }
+       
+       shared_ptr<const StereoPictureAsset> other_picture = dynamic_pointer_cast<const StereoPictureAsset> (other);
+       assert (other_picture);
+
+       for (int i = 0; i < _intrinsic_duration; ++i) {
+               shared_ptr<const StereoPictureFrame> frame_A = get_frame (i);
+               shared_ptr<const StereoPictureFrame> frame_B = other_picture->get_frame (i);
+               
+               if (!frame_buffer_equals (
+                           i, opt, note,
+                           frame_A->left_j2k_data(), frame_A->left_j2k_size(),
+                           frame_B->left_j2k_data(), frame_B->left_j2k_size()
+                           )) {
+                       return false;
+               }
+               
+               if (!frame_buffer_equals (
+                           i, opt, note,
+                           frame_A->right_j2k_data(), frame_A->right_j2k_size(),
+                           frame_B->right_j2k_data(), frame_B->right_j2k_size()
+                           )) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+StereoPictureAsset::StereoPictureAsset (boost::filesystem::path directory, string mxf_name)
+       : PictureAsset (directory, mxf_name)
+{
+       
+}
+
+void
+StereoPictureAsset::read ()
+{
+       ASDCP::JP2K::MXFSReader reader;
+       if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
+               boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string()));
+       }
+       
+       ASDCP::JP2K::PictureDescriptor desc;
+       if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) {
+               boost::throw_exception (DCPReadError ("could not read video MXF information"));
+       }
+
+       _size.width = desc.StoredWidth;
+       _size.height = desc.StoredHeight;
+}
+
+shared_ptr<const StereoPictureFrame>
+StereoPictureAsset::get_frame (int n) const
+{
+       return shared_ptr<const StereoPictureFrame> (new StereoPictureFrame (path().string(), n));
+}
+
+shared_ptr<PictureAssetWriter>
+StereoPictureAsset::start_write (bool overwrite)
+{
+       return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, overwrite));
+}
+
+string
+StereoPictureAsset::cpl_node_name () const
+{
+       return "msp-cpl:MainStereoscopicPicture";
+}
+
+pair<string, string>
+StereoPictureAsset::cpl_node_attribute (bool interop) const
+{
+       if (interop) {
+               return make_pair ("xmlns:msp-cpl", "http://www.digicine.com/schemas/437-Y/2007/Main-Stereo-Picture-CPL");
+       } else {
+               return make_pair ("xmlns:msp-cpl", "http://www.smpte-ra.org/schemas/429-10/2008/Main-Stereo-Picture-CPL");
+       }
+
+       return make_pair ("", "");
+}
+
+int
+StereoPictureAsset::edit_rate_factor () const
+{
+       return 2;
+}
diff --git a/src/stereo_picture_asset.h b/src/stereo_picture_asset.h
new file mode 100644 (file)
index 0000000..c901961
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "picture_asset.h"
+
+namespace libdcp {
+       
+/** A 3D (stereoscopic) picture asset */       
+class StereoPictureAsset : public PictureAsset
+{
+public:
+       StereoPictureAsset (boost::filesystem::path directory, std::string mxf_name);
+
+       void read ();
+       
+       /** Start a progressive write to a StereoPictureAsset */
+       boost::shared_ptr<PictureAssetWriter> start_write (bool);
+
+       boost::shared_ptr<const StereoPictureFrame> get_frame (int n) const;
+       bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
+
+private:
+       std::string cpl_node_name () const;
+       std::pair<std::string, std::string> cpl_node_attribute (bool) const;
+       int edit_rate_factor () const;
+};
+
+}
diff --git a/src/stereo_picture_asset_writer.cc b/src/stereo_picture_asset_writer.cc
new file mode 100644 (file)
index 0000000..fc7290a
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "stereo_picture_asset_writer.h"
+#include "exceptions.h"
+#include "picture_asset.h"
+
+#include "picture_asset_writer_common.cc"
+
+using std::istream;
+using std::ostream;
+using std::string;
+using boost::shared_ptr;
+using namespace libdcp;
+
+struct StereoPictureAssetWriter::ASDCPState : public ASDCPStateBase
+{
+       ASDCP::JP2K::MXFSWriter mxf_writer;
+};
+
+StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool overwrite)
+       : PictureAssetWriter (asset, overwrite)
+       , _state (new StereoPictureAssetWriter::ASDCPState)
+       , _next_eye (EYE_LEFT)
+{
+       _state->encryption_context = asset->encryption_context ();
+}
+
+void
+StereoPictureAssetWriter::start (uint8_t* data, int size)
+{
+       libdcp::start (this, _state, _asset, data, size);
+}
+
+/** Write a frame for one eye.  Frames must be written left, then right, then left etc.
+ *  @param data JPEG2000 data.
+ *  @param size Size of data.
+ */
+FrameInfo
+StereoPictureAssetWriter::write (uint8_t* data, int size)
+{
+       assert (!_finalized);
+
+       if (!_started) {
+               start (data, size);
+       }
+
+       if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) {
+               boost::throw_exception (MiscError ("could not parse J2K frame"));
+       }
+
+       uint64_t const before_offset = _state->mxf_writer.Tell ();
+
+       string hash;
+       if (ASDCP_FAILURE (
+                   _state->mxf_writer.WriteFrame (
+                           _state->frame_buffer,
+                           _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT,
+                           _state->encryption_context,
+                           0,
+                           &hash)
+                   )) {
+               
+               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
+       }
+
+       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
+
+       return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash);
+}
+
+void
+StereoPictureAssetWriter::fake_write (int size)
+{
+       assert (_started);
+       assert (!_finalized);
+
+       if (ASDCP_FAILURE (_state->mxf_writer.FakeWriteFrame (size))) {
+               boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
+       }
+
+       _next_eye = _next_eye == EYE_LEFT ? EYE_RIGHT : EYE_LEFT;
+       ++_frames_written;
+}
+
+void
+StereoPictureAssetWriter::finalize ()
+{
+       assert (!_finalized);
+       
+       if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) {
+               boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string()));
+       }
+
+       _finalized = true;
+       _asset->set_intrinsic_duration (_frames_written / 2);
+       _asset->set_duration (_frames_written / 2);
+}
diff --git a/src/stereo_picture_asset_writer.h b/src/stereo_picture_asset_writer.h
new file mode 100644 (file)
index 0000000..771524c
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <stdint.h>
+#include <string>
+#include <fstream>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include "picture_asset_writer.h"
+
+namespace libdcp {
+
+/** A helper class for writing to StereoPictureAssets progressively (i.e. writing frame-by-frame,
+ *  rather than giving libdcp all the frames in one go).
+ *
+ *  Objects of this class can only be created with StereoPictureAsset::start_write().
+ *
+ *  Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
+ *  (a verbatim .j2c file).  finalize() must be called after the last frame has been written.
+ *  The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
+ *  throw an exception.
+ */
+class StereoPictureAssetWriter : public PictureAssetWriter
+{
+public:
+       FrameInfo write (uint8_t *, int);
+       void fake_write (int size);
+       void finalize ();
+
+private:
+       friend class StereoPictureAsset;
+
+       StereoPictureAssetWriter (PictureAsset *, bool);
+       void start (uint8_t *, int);
+
+       /* do this with an opaque pointer so we don't have to include
+          ASDCP headers
+       */
+          
+       struct ASDCPState;
+       boost::shared_ptr<ASDCPState> _state;
+
+       libdcp::Eye _next_eye;
+};
+
+}
diff --git a/src/stereo_picture_frame.cc b/src/stereo_picture_frame.cc
new file mode 100644 (file)
index 0000000..279fe7a
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <openjpeg.h>
+#include "AS_DCP.h"
+#include "KM_fileio.h"
+#include "stereo_picture_frame.h"
+#include "exceptions.h"
+#include "argb_frame.h"
+#include "lut.h"
+#include "util.h"
+#include "gamma_lut.h"
+#include "rgb_xyz.h"
+
+#define DCI_GAMMA 2.6
+
+using std::string;
+using boost::shared_ptr;
+using namespace libdcp;
+
+/** Make a picture frame from a 3D (stereoscopic) asset.
+ *  @param mxf_path Path to the asset's MXF file.
+ *  @param n Frame within the asset, not taking EntryPoint into account.
+ */
+StereoPictureFrame::StereoPictureFrame (string mxf_path, int n)
+{
+       ASDCP::JP2K::MXFSReader reader;
+       if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) {
+               boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path));
+       }
+
+       /* XXX: unfortunate guesswork on this buffer size */
+       _buffer = new ASDCP::JP2K::SFrameBuffer (4 * Kumu::Megabyte);
+
+       if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer))) {
+               boost::throw_exception (DCPReadError ("could not read video frame"));
+       }
+}
+
+StereoPictureFrame::~StereoPictureFrame ()
+{
+       delete _buffer;
+}
+
+/** @param reduce a factor by which to reduce the resolution
+ *  of the image, expressed as a power of two (pass 0 for no
+ *  reduction).
+ *
+ *  @param eye Eye to return (EYE_LEFT or EYE_RIGHT).
+ *
+ *  @return An ARGB representation of one of the eyes (left or right)
+ *  of this frame.  This is ARGB in the Cairo sense, so that each
+ *  pixel takes up 4 bytes; the first byte is blue, second green,
+ *  third red and fourth alpha (always 255).
+ *
+ */
+shared_ptr<ARGBFrame>
+StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const
+{
+       shared_ptr<XYZFrame> xyz_frame;
+       switch (eye) {
+       case LEFT:
+               xyz_frame = decompress_j2k (const_cast<uint8_t*> (_buffer->Left.RoData()), _buffer->Left.Size(), reduce);
+               break;
+       case RIGHT:
+               xyz_frame = decompress_j2k (const_cast<uint8_t*> (_buffer->Right.RoData()), _buffer->Right.Size(), reduce);
+               break;
+       }
+       
+       return xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma));
+}
+
+uint8_t const *
+StereoPictureFrame::left_j2k_data () const
+{
+       return _buffer->Left.RoData ();
+}
+
+int
+StereoPictureFrame::left_j2k_size () const
+{
+       return _buffer->Left.Size ();
+}
+
+uint8_t const *
+StereoPictureFrame::right_j2k_data () const
+{
+       return _buffer->Right.RoData ();
+}
+
+int
+StereoPictureFrame::right_j2k_size () const
+{
+       return _buffer->Right.Size ();
+}
diff --git a/src/stereo_picture_frame.h b/src/stereo_picture_frame.h
new file mode 100644 (file)
index 0000000..b72eabc
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <string>
+#include <stdint.h>
+#include <boost/shared_ptr.hpp>
+#include "types.h"
+
+namespace ASDCP {
+       namespace JP2K {
+               class SFrameBuffer;
+       }
+       class AESDecContext;
+}
+
+namespace libdcp {
+
+class ARGBFrame;
+
+/** A single frame of a 3D (stereoscopic) picture asset */     
+class StereoPictureFrame
+{
+public:
+       StereoPictureFrame (std::string mxf_path, int n);
+       ~StereoPictureFrame ();
+
+       boost::shared_ptr<ARGBFrame> argb_frame (Eye eye, int reduce = 0, float srgb_gamma = 2.4) const;
+       uint8_t const * left_j2k_data () const;
+       int left_j2k_size () const;
+       uint8_t const * right_j2k_data () const;
+       int right_j2k_size () const;
+
+private:
+       ASDCP::JP2K::SFrameBuffer* _buffer;
+};
+
+}
index 030cde3b26bd14aa22f8e8f55cbea6b2d3dcc4bd..d7e118c794f22099e52805f5b6b18a68493795fb 100644 (file)
@@ -24,10 +24,12 @@ def build(bld):
                  kdm.cc
                  key.cc
                  metadata.cc
+                 mono_picture_asset.cc
+                 mono_picture_asset_writer.cc
+                 mono_picture_frame.cc
                  mxf_asset.cc
                  picture_asset.cc
                  picture_asset_writer.cc
-                 picture_frame.cc
                  rec709_linearised_gamma_lut.cc
                  reel.cc
                  rgb_xyz.cc
@@ -36,6 +38,9 @@ def build(bld):
                  sound_asset.cc
                  sound_frame.cc
                  srgb_linearised_gamma_lut.cc
+                 stereo_picture_asset.cc
+                 stereo_picture_asset_writer.cc
+                 stereo_picture_frame.cc
                  subtitle_asset.cc
                  types.cc
                  util.cc
@@ -62,10 +67,10 @@ def build(bld):
               lut.h
               lut_cache.h
               metadata.h
+              mono_picture_frame.h
               mxf_asset.h
               picture_asset.h
               picture_asset_writer.h
-              picture_frame.h
               rgb_xyz.h
               rec709_linearised_gamma_lut.h
               reel.h
@@ -75,6 +80,7 @@ def build(bld):
               sound_asset.h
               sound_frame.h
               srgb_linearised_gamma_lut.h
+              stereo_picture_frame.h
               subtitle_asset.h
               types.h
               util.h
index b9c94bd8383d3e23dbda9668ad757d6796a684ab..f70c6ce88ec4686040d42e277a8b067f3a5a103d 100644 (file)
@@ -21,7 +21,7 @@
 #include "dcp.h"
 #include "metadata.h"
 #include "cpl.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
 #include "sound_asset.h"
 #include "reel.h"
 #include "test.h"
index 73dc9b972537e9ef75039260e45dcb6dd03303db..0f5a4ef0c394953c623de5668e04619c4b861195 100644 (file)
 #include <boost/test/unit_test.hpp>
 #include "kdm.h"
 #include "dcp.h"
-#include "picture_frame.h"
+#include "mono_picture_frame.h"
 #include "cpl.h"
 #include "argb_frame.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
 #include "reel.h"
 #include "test.h"
 
index aa83d3ec04c4ac26e59dcc5d6179e43ce4698b76..e2bf9698129cf26e6ba8fac1952218b7b5fc1f69 100644 (file)
@@ -25,7 +25,7 @@
 #include "dcp.h"
 #include "signer.h"
 #include "cpl.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
 #include "sound_asset.h"
 #include "reel.h"
 #include "test.h"
index f01fbdd06a0d7e294e28d76c778c35f91430edce..eeff4f419d15aafefd84edcc25352a62aee7646a 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <boost/test/unit_test.hpp>
 #include "dcp.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
 #include "sound_asset.h"
 #include "util.h"
 #include "exceptions.h"
index 206fe200347840a4fe9a7dc12fbd6b953399da6d..42697c37b5806ed2fa304fe164fd305ad2258ba2 100644 (file)
@@ -19,8 +19,8 @@
 
 #include <boost/test/unit_test.hpp>
 #include <boost/filesystem.hpp>
-#include "picture_asset_writer.h"
-#include "picture_asset.h"
+#include "mono_picture_asset_writer.h"
+#include "mono_picture_asset.h"
 #include "KM_util.h"
 
 using std::string;
index 82f6223cd12c2b301e419727efaecca51e6618da..2747a71fb840aa89c0b5bfad64995e3f5d2271e0 100644 (file)
 #include "certificates.h"
 #include "kdm.h"
 #include "signer.h"
-#include "picture_asset.h"
+#include "mono_picture_asset.h"
 #include "sound_asset.h"
 #include "reel.h"
 #include "test.h"
 #include "cpl.h"
-#include "picture_frame.h"
+#include "mono_picture_frame.h"
 #include "argb_frame.h"
 #include "signer_chain.h"