From ceaf7bc52712cb60708ed5eb5c62c5e463dd8e89 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Jan 2021 04:15:26 +0100 Subject: [PATCH] Tidying. --- src/array_data.cc | 6 +- src/array_data.h | 2 +- src/asset_reader.h | 42 +++++--- src/asset_writer.cc | 3 +- src/asset_writer.h | 4 +- src/atmos_asset.cc | 9 +- src/atmos_asset.h | 10 +- src/atmos_asset_reader.h | 11 +- src/atmos_asset_writer.cc | 6 ++ src/atmos_frame.h | 11 +- src/bitstream.cc | 7 +- src/bitstream.h | 9 +- src/certificate.cc | 2 +- src/certificate.h | 3 +- src/chromaticity.cc | 10 +- src/chromaticity.h | 22 ++-- src/colour_conversion.cc | 32 ++++-- src/colour_conversion.h | 13 ++- src/combine.cc | 17 +-- src/combine.h | 8 ++ src/cpl.cc | 29 +++-- src/cpl.h | 21 +++- src/crypto_context.h | 24 +++-- src/data.cc | 14 ++- src/data.h | 6 ++ src/dcp.cc | 6 +- src/dcp.h | 2 +- src/dcp_assert.h | 9 +- src/dcp_time.cc | 49 +++++---- src/dcp_time.h | 50 +++++++-- src/decrypted_kdm.cc | 33 ++++-- src/decrypted_kdm.h | 25 ++++- src/decrypted_kdm_key.cc | 10 +- src/decrypted_kdm_key.h | 12 ++- src/encrypted_kdm.cc | 49 ++++++++- src/encrypted_kdm.h | 18 +++- src/exceptions.cc | 18 +++- src/font_asset.cc | 10 +- src/font_asset.h | 9 +- src/frame.h | 7 +- src/fsk.cc | 11 +- src/fsk.h | 14 ++- src/gamma_transfer_function.cc | 2 +- src/identity_transfer_function.cc | 13 ++- src/identity_transfer_function.h | 9 +- src/interop_load_font_node.cc | 17 ++- src/interop_load_font_node.h | 14 ++- src/interop_subtitle_asset.cc | 36 +++++-- src/interop_subtitle_asset.h | 14 ++- src/j2k.cc | 85 ++++++++------- src/j2k.h | 25 ++++- src/language_tag.cc | 25 +++-- src/language_tag.h | 8 ++ src/load_font_node.h | 10 +- src/local_time.cc | 63 ++++++----- src/local_time.h | 53 ++++++--- src/locale_convert.cc | 35 +++++- src/locale_convert.h | 13 ++- src/metadata.cc | 10 +- src/metadata.h | 15 ++- src/modified_gamma_transfer_function.cc | 26 +++-- src/modified_gamma_transfer_function.h | 9 +- src/mono_picture_asset.cc | 19 +++- src/mono_picture_asset.h | 12 ++- src/mono_picture_asset_reader.h | 13 ++- src/mono_picture_asset_writer.cc | 30 ++++-- src/mono_picture_asset_writer.h | 13 ++- src/mono_picture_frame.cc | 48 ++++----- src/mono_picture_frame.h | 28 +++-- src/mxf.cc | 19 ++-- src/mxf.h | 24 ++++- src/name_format.cc | 21 ++-- src/name_format.h | 21 +++- src/openjpeg_image.cc | 32 +++--- src/openjpeg_image.h | 31 +++++- src/picture_asset.cc | 28 +++-- src/picture_asset.h | 26 +++-- src/picture_asset_writer.cc | 10 +- src/picture_asset_writer.h | 22 ++-- src/picture_asset_writer_common.cc | 20 +++- src/pkl.cc | 5 + src/pkl.h | 7 ++ src/raw_convert.cc | 33 +++++- src/raw_convert.h | 13 ++- src/reel.cc | 5 + src/reel.h | 5 + src/reel_asset.cc | 27 ++--- src/reel_asset.h | 20 +++- src/reel_atmos_asset.cc | 19 +++- src/reel_atmos_asset.h | 16 ++- src/reel_closed_caption_asset.cc | 16 ++- src/reel_closed_caption_asset.h | 13 ++- src/reel_markers_asset.cc | 21 ++-- src/reel_markers_asset.h | 6 +- src/reel_mono_picture_asset.cc | 10 +- src/reel_mono_picture_asset.h | 14 ++- src/reel_picture_asset.cc | 18 +++- src/reel_picture_asset.h | 11 +- src/reel_sound_asset.cc | 15 ++- src/reel_sound_asset.h | 11 +- src/reel_stereo_picture_asset.cc | 15 ++- src/reel_stereo_picture_asset.h | 14 ++- src/reel_subtitle_asset.cc | 15 ++- src/reel_subtitle_asset.h | 13 ++- src/rgb_xyz.cc | 66 ++++-------- src/rgb_xyz.h | 42 +++++++- src/s_gamut3_transfer_function.cc | 15 ++- src/s_gamut3_transfer_function.h | 7 +- src/smpte_load_font_node.cc | 13 ++- src/smpte_load_font_node.h | 11 +- src/smpte_subtitle_asset.cc | 61 ++++++----- src/smpte_subtitle_asset.h | 28 +++-- src/sound_asset.cc | 62 ++++++----- src/sound_asset.h | 16 ++- src/sound_asset_reader.h | 11 +- src/sound_asset_writer.cc | 41 +++---- src/sound_asset_writer.h | 20 ++-- src/sound_frame.cc | 13 ++- src/sound_frame.h | 13 ++- src/stereo_picture_asset.cc | 44 +++++--- src/stereo_picture_asset.h | 17 ++- src/stereo_picture_asset_reader.h | 13 ++- src/stereo_picture_asset_writer.cc | 35 +++--- src/stereo_picture_asset_writer.h | 15 ++- src/subtitle.cc | 10 +- src/subtitle.h | 17 ++- src/subtitle_asset.cc | 137 ++++++++++++++---------- src/subtitle_asset.h | 21 +++- src/subtitle_asset_internal.cc | 44 ++++++-- src/subtitle_asset_internal.h | 22 +++- 130 files changed, 1930 insertions(+), 758 deletions(-) diff --git a/src/array_data.cc b/src/array_data.cc index 61e79395..2df53830 100644 --- a/src/array_data.cc +++ b/src/array_data.cc @@ -32,6 +32,11 @@ */ +/** @file src/array_data.cc + * @brief ArrayData class + */ + + #include "array_data.h" #include "util.h" #include "exceptions.h" @@ -44,7 +49,6 @@ using namespace dcp; ArrayData::ArrayData () - : _size (0) { } diff --git a/src/array_data.h b/src/array_data.h index 8c2f6d55..69962bf2 100644 --- a/src/array_data.h +++ b/src/array_data.h @@ -94,7 +94,7 @@ public: private: boost::shared_array _data; /** amount of `valid' data in _data; the array may be larger */ - int _size; + int _size = 0; }; diff --git a/src/asset_reader.h b/src/asset_reader.h index 859c88f3..2da67bd8 100644 --- a/src/asset_reader.h +++ b/src/asset_reader.h @@ -32,6 +32,11 @@ */ +/** @file src/asset_reader.h + * @brief AssetReader class + */ + + #ifndef LIBDCP_ASSET_READER_H #define LIBDCP_ASSET_READER_H @@ -46,22 +51,16 @@ namespace dcp { +class AtmosAsset; +class MonoPictureAsset; +class SoundAsset; +class StereoPictureAsset; + + template class AssetReader { public: - explicit AssetReader (Asset const * asset, boost::optional key, Standard standard) - : _crypto_context (new DecryptionContext(key, standard)) - { - _reader = new R (); - DCP_ASSERT (asset->file()); - auto const r = _reader->OpenRead (asset->file()->string().c_str()); - if (ASDCP_FAILURE(r)) { - delete _reader; - boost::throw_exception (FileError("could not open MXF file for reading", asset->file().get(), r)); - } - } - AssetReader (AssetReader const&) = delete; AssetReader& operator== (AssetReader const&) = delete; @@ -72,6 +71,7 @@ public: std::shared_ptr get_frame (int n) const { + /* Can't use make_shared here as the constructor is private */ return std::shared_ptr (new F(_reader, n, _crypto_context)); } @@ -82,6 +82,24 @@ public: protected: R* _reader = nullptr; std::shared_ptr _crypto_context; + +private: + friend class AtmosAsset; + friend class MonoPictureAsset; + friend class SoundAsset; + friend class StereoPictureAsset; + + explicit AssetReader (Asset const * asset, boost::optional key, Standard standard) + : _crypto_context (new DecryptionContext(key, standard)) + { + _reader = new R (); + DCP_ASSERT (asset->file()); + auto const r = _reader->OpenRead (asset->file()->string().c_str()); + if (ASDCP_FAILURE(r)) { + delete _reader; + boost::throw_exception (FileError("could not open MXF file for reading", asset->file().get(), r)); + } + } }; diff --git a/src/asset_writer.cc b/src/asset_writer.cc index 73fc2046..05d0aa23 100644 --- a/src/asset_writer.cc +++ b/src/asset_writer.cc @@ -33,7 +33,7 @@ /** @file src/asset_writer.h - * @brief AssetWriter class. + * @brief AssetWriter class */ @@ -61,7 +61,6 @@ AssetWriter::AssetWriter (MXF* mxf, boost::filesystem::path file) } -/** @return true if anything was written by this writer */ bool AssetWriter::finalize () { diff --git a/src/asset_writer.h b/src/asset_writer.h index 7eecc03f..c1fc1900 100644 --- a/src/asset_writer.h +++ b/src/asset_writer.h @@ -33,7 +33,7 @@ /** @file src/asset_writer.h - * @brief AssetWriter class. + * @brief AssetWriter class */ @@ -65,6 +65,8 @@ public: AssetWriter& operator= (AssetWriter const&) = delete; virtual ~AssetWriter () {} + + /** @return true if anything was written by this writer */ virtual bool finalize (); int64_t frames_written () const { diff --git a/src/atmos_asset.cc b/src/atmos_asset.cc index b8743092..ae381737 100644 --- a/src/atmos_asset.cc +++ b/src/atmos_asset.cc @@ -32,6 +32,11 @@ */ +/** @file src/atmos_asset.cc + * @brief AtmosAsset class + */ + + #include "atmos_asset.h" #include "atmos_asset_reader.h" #include "atmos_asset_writer.h" @@ -48,7 +53,6 @@ using namespace dcp; AtmosAsset::AtmosAsset (Fraction edit_rate, int first_frame, int max_channel_count, int max_object_count, int atmos_version) : MXF (Standard::SMPTE) , _edit_rate (edit_rate) - , _intrinsic_duration (0) , _first_frame (first_frame) , _max_channel_count (max_channel_count) , _max_object_count (max_object_count) @@ -105,7 +109,8 @@ AtmosAsset::static_pkl_type (Standard) shared_ptr AtmosAsset::start_read () const { - return make_shared(this, key(), Standard::SMPTE); + /* Can't use make_shared here since the constructor is protected */ + return shared_ptr(new AtmosAssetReader(this, key(), Standard::SMPTE)); } diff --git a/src/atmos_asset.h b/src/atmos_asset.h index 817bc975..7ee55d92 100644 --- a/src/atmos_asset.h +++ b/src/atmos_asset.h @@ -104,12 +104,12 @@ private: friend class AtmosAssetWriter; Fraction _edit_rate; - int64_t _intrinsic_duration; - int _first_frame; - int _max_channel_count; - int _max_object_count; + int64_t _intrinsic_duration = 0; + int _first_frame = 0; + int _max_channel_count = 0; + int _max_object_count = 0; std::string _atmos_id; - int _atmos_version; + int _atmos_version = 0; }; diff --git a/src/atmos_asset_reader.h b/src/atmos_asset_reader.h index 14806261..2a24b832 100644 --- a/src/atmos_asset_reader.h +++ b/src/atmos_asset_reader.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,11 +31,20 @@ files in the program, then also delete it here. */ + +/** @file src/atmos_asset_reader.h + * @brief AtmosAssetReader typedef + */ + + #include "asset_reader.h" #include "atmos_frame.h" + namespace dcp { + typedef AssetReader AtmosAssetReader; + } diff --git a/src/atmos_asset_writer.cc b/src/atmos_asset_writer.cc index 891a8c01..957bd4cb 100644 --- a/src/atmos_asset_writer.cc +++ b/src/atmos_asset_writer.cc @@ -32,6 +32,11 @@ */ +/** @file src/atmos_asset_writer.cc + * @brief AtmosAssetWriter class + */ + + #include "atmos_asset_writer.h" #include "atmos_asset.h" #include "exceptions.h" @@ -110,6 +115,7 @@ AtmosAssetWriter::write (uint8_t const * data, int size) ++_frames_written; } + bool AtmosAssetWriter::finalize () { diff --git a/src/atmos_frame.h b/src/atmos_frame.h index 763875bd..0ea60c23 100644 --- a/src/atmos_frame.h +++ b/src/atmos_frame.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,19 +31,26 @@ files in the program, then also delete it here. */ + /** @file src/atmos_frame.h - * @brief AtmosFrame class. + * @brief AtmosFrame typedef */ + #ifndef LIBDCP_ATMOS_FRAME_H #define LIBDCP_ATMOS_FRAME_H + #include "frame.h" + namespace dcp { + typedef Frame AtmosFrame; + } + #endif diff --git a/src/bitstream.cc b/src/bitstream.cc index 13d5ae4b..8b7988dd 100644 --- a/src/bitstream.cc +++ b/src/bitstream.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of libdcp. @@ -32,6 +32,11 @@ */ +/** @file src/bitstream.cc + * @brief Bitstream class + */ + + #include "bitstream.h" #include "dcp_assert.h" #include diff --git a/src/bitstream.h b/src/bitstream.h index 1295f79e..2dc7c20e 100644 --- a/src/bitstream.h +++ b/src/bitstream.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of libdcp. @@ -32,6 +32,11 @@ */ +/** @file src/bitstream.h + * @brief Bitstream class + */ + + #include #include #include @@ -40,6 +45,7 @@ namespace dcp { + class Bitstream { public: @@ -58,4 +64,5 @@ private: boost::optional > _crc; }; + } diff --git a/src/certificate.cc b/src/certificate.cc index b285df5f..93f271ef 100644 --- a/src/certificate.cc +++ b/src/certificate.cc @@ -33,7 +33,7 @@ /** @file src/certificate.cc - * @brief Certificate class. + * @brief Certificate class */ diff --git a/src/certificate.h b/src/certificate.h index 7a8c2a44..1b8188c7 100644 --- a/src/certificate.h +++ b/src/certificate.h @@ -33,7 +33,7 @@ /** @file src/certificate.h - * @brief Certificate class. + * @brief Certificate class */ @@ -139,4 +139,5 @@ std::ostream& operator<< (std::ostream&s, Certificate const & c); } + #endif diff --git a/src/chromaticity.cc b/src/chromaticity.cc index 9d67d72f..ca96c011 100644 --- a/src/chromaticity.cc +++ b/src/chromaticity.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,18 @@ files in the program, then also delete it here. */ + +/** file src/chromaticity.cc + * brief Chromaticity class + */ + + #include "chromaticity.h" + using namespace dcp; + Chromaticity Chromaticity::D65 () { diff --git a/src/chromaticity.h b/src/chromaticity.h index c62731f7..41bb8fda 100644 --- a/src/chromaticity.h +++ b/src/chromaticity.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of libdcp. @@ -31,35 +31,37 @@ files in the program, then also delete it here. */ + /** @file src/chromaticity.h - * @brief Chromaticity class. + * @brief Chromaticity class */ + #ifndef DCP_CHROMATICITY_H #define DCP_CHROMATICITY_H + #include + namespace dcp { + /** @class Chromaticity * @brief A representation of a x,y,z chromaticity, where z = 1 - x - y */ class Chromaticity { public: - Chromaticity () - : x (0) - , y (0) - {} + Chromaticity () {} Chromaticity (double x_, double y_) : x (x_) , y (y_) {} - double x; - double y; + double x = 0; + double y = 0; double z () const { return 1 - x - y; @@ -67,12 +69,14 @@ public: /** @return true if this Chromaticity's x and y are within epsilon of other */ bool about_equal (Chromaticity const & other, float epsilon) const { - return std::fabs (x - other.x) < epsilon && std::fabs (y - other.y) < epsilon; + return std::fabs(x - other.x) < epsilon && std::fabs(y - other.y) < epsilon; } static Chromaticity D65 (); }; + } + #endif diff --git a/src/colour_conversion.cc b/src/colour_conversion.cc index 1251d94f..84218d87 100644 --- a/src/colour_conversion.cc +++ b/src/colour_conversion.cc @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/colour_conversion.cc + * @brief ColourConversion class + */ + + #include "colour_conversion.h" #include "gamma_transfer_function.h" #include "modified_gamma_transfer_function.h" @@ -41,15 +47,17 @@ #include #include + using std::shared_ptr; using std::make_shared; using boost::optional; using namespace dcp; + ColourConversion const & ColourConversion::srgb_to_xyz () { - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(2.4, 0.04045, 0.055, 12.92), YUVToRGB::REC601, Chromaticity (0.64, 0.33), @@ -65,7 +73,7 @@ ColourConversion::srgb_to_xyz () ColourConversion const & ColourConversion::rec601_to_xyz () { - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(2.2), YUVToRGB::REC601, Chromaticity (0.64, 0.33), @@ -81,7 +89,7 @@ ColourConversion::rec601_to_xyz () ColourConversion const & ColourConversion::rec709_to_xyz () { - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(2.2), YUVToRGB::REC709, Chromaticity (0.64, 0.33), @@ -97,7 +105,7 @@ ColourConversion::rec709_to_xyz () ColourConversion const & ColourConversion::p3_to_xyz () { - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(2.6), YUVToRGB::REC709, Chromaticity (0.68, 0.32), @@ -116,7 +124,7 @@ ColourConversion::rec1886_to_xyz () /* According to Olivier on DCP-o-matic bug #832, Rec. 1886 is Rec. 709 with 2.4 gamma, so here goes ... */ - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(2.4), YUVToRGB::REC709, Chromaticity (0.64, 0.33), @@ -132,7 +140,7 @@ ColourConversion::rec1886_to_xyz () ColourConversion const & ColourConversion::rec2020_to_xyz () { - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(2.4), YUVToRGB::REC709, Chromaticity (0.708, 0.292), @@ -149,7 +157,7 @@ ColourConversion::rec2020_to_xyz () ColourConversion const & ColourConversion::s_gamut3_to_xyz () { - static ColourConversion* c = new ColourConversion ( + static auto c = new ColourConversion ( make_shared(), YUVToRGB::REC709, Chromaticity (0.73, 0.280), @@ -186,6 +194,7 @@ ColourConversion::ColourConversion ( } + bool ColourConversion::about_equal (ColourConversion const & other, float epsilon) const { @@ -217,6 +226,7 @@ ColourConversion::about_equal (ColourConversion const & other, float epsilon) co return false; } + boost::numeric::ublas::matrix ColourConversion::rgb_to_xyz () const { @@ -240,13 +250,14 @@ ColourConversion::rgb_to_xyz () const return C; } + boost::numeric::ublas::matrix ColourConversion::xyz_to_rgb () const { - boost::numeric::ublas::matrix A (rgb_to_xyz ()); + boost::numeric::ublas::matrix A (rgb_to_xyz()); /* permutation matrix for the LU-factorization */ - boost::numeric::ublas::permutation_matrix pm (A.size1 ()); + boost::numeric::ublas::permutation_matrix pm (A.size1()); /* perform LU-factorization */ int const r = lu_factorize (A, pm); @@ -254,7 +265,7 @@ ColourConversion::xyz_to_rgb () const /* create identity matrix of inverse */ boost::numeric::ublas::matrix xyz_to_rgb (3, 3); - xyz_to_rgb.assign (boost::numeric::ublas::identity_matrix (A.size1 ())); + xyz_to_rgb.assign (boost::numeric::ublas::identity_matrix (A.size1())); /* backsubstitute to get the inverse */ lu_substitute (A, pm, xyz_to_rgb); @@ -262,6 +273,7 @@ ColourConversion::xyz_to_rgb () const return xyz_to_rgb; } + boost::numeric::ublas::matrix ColourConversion::bradford () const { diff --git a/src/colour_conversion.h b/src/colour_conversion.h index d613c143..83ba3ad3 100644 --- a/src/colour_conversion.h +++ b/src/colour_conversion.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2015 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,16 @@ files in the program, then also delete it here. */ + /** @file src/colour_conversion.h * @brief ColourConversion class. */ + #ifndef DCP_COLOUR_CONVERSION_H #define DCP_COLOUR_CONVERSION_H + #include "chromaticity.h" #include #if BOOST_VERSION >= 106400 @@ -46,19 +49,23 @@ #include #include + namespace dcp { + class TransferFunction; + enum class YUVToRGB { REC601, REC709, COUNT }; + /** @class ColourConversion * @brief A representation of all the parameters involved the colourspace conversion - * of a YUV image to XYZ (via RGB). + * of a YUV image to XYZ (via RGB) */ class ColourConversion { @@ -175,6 +182,8 @@ protected: std::shared_ptr _out; }; + } + #endif diff --git a/src/combine.cc b/src/combine.cc index c2cae547..dd8a145c 100644 --- a/src/combine.cc +++ b/src/combine.cc @@ -32,6 +32,11 @@ */ +/** @file src/combine.cc + * @brief Method to combine DCPs + */ + + #include "asset.h" #include "combine.h" #include "cpl.h" @@ -135,27 +140,27 @@ dcp::combine ( continue; } - optional file = j->file(); + auto file = j->file(); DCP_ASSERT (file); path new_path = make_unique(output / file->filename()); - shared_ptr sub = dynamic_pointer_cast(j); + auto sub = dynamic_pointer_cast(j); if (sub) { /* Interop fonts are really fiddly. The font files are assets (in the ASSETMAP) * and also linked from the font XML by filename. We have to fix both these things, * and re-write the font XML file since the font URI might have changed if it's a duplicate * with another DCP. */ - map fonts = sub->font_filenames (); - for (map::const_iterator k = fonts.begin(); k != fonts.end(); ++k) { - sub->set_font_file (k->first, make_unique(output / k->second.filename())); + auto fonts = sub->font_filenames (); + for (auto const& k: fonts) { + sub->set_font_file (k.first, make_unique(output / k.second.filename())); } sub->write (new_path); } else if (!dynamic_pointer_cast(j)) { /* Take care of everything else that's not a Interop subtitle asset, Interop font file * or CPL. */ - optional file = j->file(); + auto file = j->file(); DCP_ASSERT (file); path new_path = make_unique(output / file->filename()); create_hard_link_or_copy (*file, new_path); diff --git a/src/combine.h b/src/combine.h index 21acbb04..dd992f1b 100644 --- a/src/combine.h +++ b/src/combine.h @@ -32,6 +32,11 @@ */ +/** @file src/combine.h + * @brief Method to combine DCPs + */ + + #include "compose.hpp" #include "version.h" #include @@ -39,8 +44,10 @@ namespace dcp { + class CertificateChain; + void combine ( std::vector inputs, boost::filesystem::path output, @@ -51,5 +58,6 @@ void combine ( std::shared_ptr signer = std::shared_ptr() ); + } diff --git a/src/cpl.cc b/src/cpl.cc index e932c678..5f8d8955 100644 --- a/src/cpl.cc +++ b/src/cpl.cc @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/cpl.cc + * @brief CPL class + */ + + #include "cpl.h" #include "util.h" #include "reel.h" @@ -51,6 +57,7 @@ #include #include + using std::string; using std::list; using std::pair; @@ -86,7 +93,7 @@ CPL::CPL (string annotation_text, ContentKind content_kind) _content_versions.push_back (cv); } -/** Construct a CPL object from a XML file */ + CPL::CPL (boost::filesystem::path file) : Asset (file) , _content_kind (ContentKind::FEATURE) @@ -143,7 +150,6 @@ CPL::CPL (boost::filesystem::path file) } } - f.ignore_child ("Issuer"); f.ignore_child ("Signer"); f.ignore_child ("Signature"); @@ -151,21 +157,14 @@ CPL::CPL (boost::filesystem::path file) f.done (); } -/** Add a reel to this CPL. - * @param reel Reel to add. - */ + void CPL::add (std::shared_ptr reel) { _reels.push_back (reel); } -/** Write an CompositonPlaylist XML file. - * - * @param file Filename to write. - * @param standard INTEROP or SMPTE. - * @param signer Signer to sign the CPL, or 0 to add no signature. - */ + void CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptr signer) const { @@ -544,6 +543,7 @@ CPL::reel_mxfs () const return c; } + bool CPL::equals (shared_ptr other, EqualityOptions opt, NoteHandler note) const { @@ -582,7 +582,7 @@ CPL::equals (shared_ptr other, EqualityOptions opt, NoteHandler not return true; } -/** @return true if we have any encrypted content */ + bool CPL::any_encrypted () const { @@ -596,7 +596,6 @@ CPL::any_encrypted () const } -/** @return true if we have all our encryptable content is encrypted */ bool CPL::all_encrypted () const { @@ -610,10 +609,6 @@ CPL::all_encrypted () const } -/** Add a KDM to this CPL. If the KDM is for any of this CPLs assets it will be used - * to decrypt those assets. - * @param kdm KDM. - */ void CPL::add (DecryptedKDM const & kdm) { diff --git a/src/cpl.h b/src/cpl.h index aa2daf2f..78d3d907 100644 --- a/src/cpl.h +++ b/src/cpl.h @@ -67,12 +67,14 @@ class DecryptedKDM; /** @class CPL - * @brief A Composition Playlist. + * @brief A Composition Playlist */ class CPL : public Asset { public: CPL (std::string annotation_text, ContentKind content_kind); + + /** Construct a CPL object from a XML file */ explicit CPL (boost::filesystem::path file); bool equals ( @@ -81,7 +83,15 @@ public: NoteHandler note ) const; + /** Add a reel to this CPL + * @param reel Reel to add + */ void add (std::shared_ptr reel); + + /** Add a KDM to this CPL. If the KDM is for any of this CPLs assets it will be used + * to decrypt those assets. + * @param kdm KDM. + */ void add (DecryptedKDM const &); /** @return the reels in this CPL */ @@ -93,9 +103,18 @@ public: std::vector> reel_mxfs () const; std::vector> reel_mxfs (); + /** @return true if we have any encrypted content */ bool any_encrypted () const; + + /** @return true if we have all our encryptable content is encrypted */ bool all_encrypted () const; + /** Write an CompositonPlaylist XML file + * + * @param file Filename to write + * @param standard INTEROP or SMPTE + * @param signer Signer to sign the CPL, or 0 to add no signature + */ void write_xml ( boost::filesystem::path file, Standard standard, diff --git a/src/crypto_context.h b/src/crypto_context.h index 263121bf..6020ea88 100644 --- a/src/crypto_context.h +++ b/src/crypto_context.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2018 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,9 +31,16 @@ files in the program, then also delete it here. */ + +/** @file src/crypto_context.h + * @class CryptoContext class + */ + + #ifndef LIBDCP_CRYPTO_CONTEXT_H #define LIBDCP_CRYPTO_CONTEXT_H + #include "key.h" #include "types.h" #include "exceptions.h" @@ -41,22 +48,24 @@ #include #include + namespace dcp { + template class CryptoContext { public: CryptoContext (boost::optional key, Standard standard) - : _context (0) - , _hmac (0) + : _context (nullptr) + , _hmac (nullptr) { if (!key) { return; } - _context = new T; - if (ASDCP_FAILURE (_context->InitKey (key->value ()))) { + _context = new T (); + if (ASDCP_FAILURE (_context->InitKey(key->value()))) { throw MiscError ("could not set up crypto context"); } @@ -76,7 +85,7 @@ public: type = ASDCP::LS_MXF_SMPTE; } - if (ASDCP_FAILURE (_hmac->InitKey (key->value(), type))) { + if (ASDCP_FAILURE (_hmac->InitKey(key->value(), type))) { throw MiscError ("could not set up HMAC context"); } } @@ -100,9 +109,12 @@ private: ASDCP::HMACContext* _hmac; }; + typedef CryptoContext EncryptionContext; typedef CryptoContext DecryptionContext; + } + #endif diff --git a/src/data.cc b/src/data.cc index 23e62573..79f58f93 100644 --- a/src/data.cc +++ b/src/data.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015-2020 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of libdcp. @@ -32,9 +32,14 @@ */ +/** @file src/data.cc + * @brief Data class + */ + + #include "data.h" -#include "util.h" #include "exceptions.h" +#include "util.h" #include #include @@ -45,16 +50,15 @@ using namespace dcp; void Data::write (boost::filesystem::path file) const { - FILE* f = fopen_boost (file, "wb"); + auto f = fopen_boost (file, "wb"); if (!f) { throw FileError ("could not write to file", file, errno); } size_t const r = fwrite (data(), 1, size(), f); + fclose (f); if (r != size_t(size())) { - fclose (f); throw FileError ("could not write to file", file, errno); } - fclose (f); } diff --git a/src/data.h b/src/data.h index 1c35def8..96ed4bb5 100644 --- a/src/data.h +++ b/src/data.h @@ -32,6 +32,11 @@ */ +/** @file src/data.h + * @brief Data class + */ + + #ifndef LIBDCP_DATA_H #define LIBDCP_DATA_H @@ -63,4 +68,5 @@ bool operator!=(Data const & a, Data const & b); } + #endif diff --git a/src/dcp.cc b/src/dcp.cc index 47abd65e..9ccc6eef 100644 --- a/src/dcp.cc +++ b/src/dcp.cc @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/dcp.cc - * @brief DCP class. + * @brief DCP class */ + #include "raw_convert.h" #include "dcp.h" #include "sound_asset.h" @@ -307,7 +309,7 @@ DCP::equals (DCP const & other, EqualityOptions opt, NoteHandler note) const void -DCP::add (std::shared_ptr cpl) +DCP::add (shared_ptr cpl) { _cpls.push_back (cpl); } diff --git a/src/dcp.h b/src/dcp.h index 1a8f2b3e..403eea9e 100644 --- a/src/dcp.h +++ b/src/dcp.h @@ -33,7 +33,7 @@ /** @file src/dcp.h - * @brief DCP class. + * @brief DCP class */ diff --git a/src/dcp_assert.h b/src/dcp_assert.h index d8bf20e6..773739b7 100644 --- a/src/dcp_assert.h +++ b/src/dcp_assert.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,6 +31,13 @@ files in the program, then also delete it here. */ + +/** @file src/dcp_assert.h + * @brief DCP_ASSERT macro + */ + + #include "exceptions.h" + #define DCP_ASSERT(x) if (!(x)) throw dcp::ProgrammingError (__FILE__, __LINE__); diff --git a/src/dcp_time.cc b/src/dcp_time.cc index 7a4a67d6..2895cd37 100644 --- a/src/dcp_time.cc +++ b/src/dcp_time.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/dcp_time.cc - * @brief Time class. + * @brief Time class */ + #include "raw_convert.h" #include "dcp_time.h" #include "exceptions.h" @@ -46,25 +48,24 @@ #include #include + using namespace std; using namespace boost; using namespace dcp; + Time::Time (int frame, double frames_per_second, int tcr_) { set (double (frame) / frames_per_second, tcr_); } -/** Construct a Time from a number of seconds and a timecode rate. - * - * @param seconds A number of seconds. - * @param tcr_ Timecode rate. - */ + Time::Time (double seconds, int tcr_) { set (seconds, tcr_); } + /** Construct a Time with specified timecode rate and using the supplied * number of seconds. * @@ -94,14 +95,7 @@ Time::set (double seconds, int tcr_) } } -/** @param time String of the form - * HH:MM:SS:EE for SMPTE - * HH:MM:SS:E[E[E]] or HH:MM:SS.s[s[s]] for Interop - * where HH are hours, MM minutes, SS seconds, EE editable units and - * sss millseconds. - * - * @param tcr_ Timecode rate if this is a SMPTE time, otherwise empty for an Interop time. - */ + Time::Time (string time, optional tcr_) { vector b; @@ -170,30 +164,35 @@ Time::Time (string time, optional tcr_) } } + bool dcp::operator== (Time const & a, Time const & b) { return (a.h == b.h && a.m == b.m && a.s == b.s && (a.e * b.tcr) == (b.e * a.tcr)); } + bool dcp::operator!= (Time const & a, Time const & b) { return !(a == b); } + bool dcp::operator<= (Time const & a, Time const & b) { return a < b || a == b; } + bool dcp::operator>= (Time const & a, Time const & b) { return a > b || a == b; } + bool dcp::operator< (Time const & a, Time const & b) { @@ -212,6 +211,7 @@ dcp::operator< (Time const & a, Time const & b) return (a.e * b.tcr) < (b.e * a.tcr); } + bool dcp::operator> (Time const & a, Time const & b) { @@ -230,6 +230,7 @@ dcp::operator> (Time const & a, Time const & b) return (a.e * b.tcr) > (b.e * a.tcr); } + ostream & dcp::operator<< (ostream& s, Time const & t) { @@ -237,6 +238,7 @@ dcp::operator<< (ostream& s, Time const & t) return s; } + dcp::Time dcp::operator+ (Time a, Time b) { @@ -274,6 +276,7 @@ dcp::operator+ (Time a, Time b) return r; } + dcp::Time dcp::operator- (Time a, Time b) { @@ -311,6 +314,7 @@ dcp::operator- (Time a, Time b) return r; } + float dcp::operator/ (Time a, Time const & b) { @@ -319,7 +323,7 @@ dcp::operator/ (Time a, Time const & b) return float (at) / bt; } -/** @return A string of the form h:m:s:e padded as in 00:00:00:000 (for Interop) or 00:00:00:00 (for SMPTE) */ + string Time::as_string (Standard standard) const { @@ -334,26 +338,21 @@ Time::as_string (Standard standard) const return buffer; } -/** @param tcr_ Timecode rate with which the return value should be counted. - * @return the total number of editable units that this time consists of at the specified timecode rate, rounded up - * to the nearest editable unit. For example, as_editable_units (24) returns the total time in frames at 24fps. - */ + int64_t Time::as_editable_units (int tcr_) const { - return ceil (int64_t(e) * double (tcr_) / tcr) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_; + return ceil(int64_t(e) * double(tcr_) / tcr) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_; } -/** @return the total number of seconds that this time consists of */ + double Time::as_seconds () const { return h * 3600 + m * 60 + s + double(e) / tcr; } -/** @param tcr_ New timecode rate. - * @return A new Time which is this time at the spcified new timecode rate. - */ + Time Time::rebase (int tcr_) const { diff --git a/src/dcp_time.h b/src/dcp_time.h index 9320d8ba..997b8d13 100644 --- a/src/dcp_time.h +++ b/src/dcp_time.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,23 +31,29 @@ files in the program, then also delete it here. */ + /** @file src/dcp_time.h - * @brief Time class. + * @brief Time class */ + #ifndef LIBDCP_TIME_H #define LIBDCP_TIME_H + #include "types.h" #include #include #include #include + namespace dcp { + class Time; + extern bool operator== (Time const & a, Time const & b); extern bool operator!= (Time const & a, Time const & b); extern bool operator<= (Time const & a, Time const & b); @@ -59,6 +65,7 @@ extern Time operator+ (Time a, Time b); extern Time operator- (Time a, Time b); extern float operator/ (Time a, Time const & b); + /** @class Time * @brief A representation of time within a DCP. */ @@ -66,7 +73,7 @@ class Time { public: /** Construct a zero Time */ - Time () : h (0), m (0), s (0), e (0), tcr (1) {} + Time () {} /** Construct a Time. * @param frame Frame index (starting from 0). @@ -90,19 +97,44 @@ public: , tcr (tcr_) {} + /** Construct a Time from a number of seconds and a timecode rate + * + * @param seconds A number of seconds + * @param tcr_ Timecode rate + */ Time (double seconds, int tcr); + /** @param time String of the form + * HH:MM:SS:EE for SMPTE + * HH:MM:SS:E[E[E]] or HH:MM:SS.s[s[s]] for Interop + * where HH are hours, MM minutes, SS seconds, EE editable units and + * sss millseconds. + * + * @param tcr_ Timecode rate if this is a SMPTE time, otherwise empty for an Interop time + */ Time (std::string time, boost::optional tcr); - int h; ///< hours - int m; ///< minutes - int s; ///< seconds - int e; ///< editable units (where 1 editable unit is 1 / tcr_ seconds) - int tcr; ///< timecode rate: the number of editable units per second. + int h = 0; ///< hours + int m = 0; ///< minutes + int s = 0; ///< seconds + int e = 0; ///< editable units (where 1 editable unit is 1 / tcr_ seconds) + int tcr = 1; ///< timecode rate: the number of editable units per second. + /** @return A string of the form h:m:s:e padded as in 00:00:00:000 (for Interop) or 00:00:00:00 (for SMPTE) */ std::string as_string (Standard standard) const; + + /** @return the total number of seconds that this time consists of */ double as_seconds () const; + + /** @param tcr_ Timecode rate with which the return value should be counted + * @return the total number of editable units that this time consists of at the specified timecode rate, rounded up + * to the nearest editable unit. For example, as_editable_units (24) returns the total time in frames at 24fps. + */ int64_t as_editable_units (int tcr_) const; + + /** @param tcr_ New timecode rate + * @return A new Time which is this time at the spcified new timecode rate + */ Time rebase (int tcr_) const; Time& operator+= (Time const & o) { @@ -114,6 +146,8 @@ private: void set (double seconds, int tcr); }; + } + #endif diff --git a/src/decrypted_kdm.cc b/src/decrypted_kdm.cc index 0a3eeabd..174efb1b 100644 --- a/src/decrypted_kdm.cc +++ b/src/decrypted_kdm.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2017 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/decrypted_kdm.cc + * @brief DecryptedKDM class + */ + + #include "decrypted_kdm.h" #include "decrypted_kdm_key.h" #include "encrypted_kdm.h" @@ -48,6 +54,7 @@ #include #include + using std::list; using std::vector; using std::string; @@ -60,9 +67,11 @@ using std::shared_ptr; using boost::optional; using namespace dcp; + /* Magic value specified by SMPTE S430-1-2006 */ static uint8_t smpte_structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab }; + static void put (uint8_t ** d, string s) { @@ -70,6 +79,7 @@ put (uint8_t ** d, string s) (*d) += s.length(); } + static void put (uint8_t ** d, uint8_t const * s, int N) { @@ -77,6 +87,7 @@ put (uint8_t ** d, uint8_t const * s, int N) (*d) += N; } + void DecryptedKDM::put_uuid (uint8_t ** d, string id) { @@ -96,6 +107,7 @@ DecryptedKDM::put_uuid (uint8_t ** d, string id) *d += 16; } + string DecryptedKDM::get_uuid (unsigned char ** p) { @@ -114,6 +126,7 @@ DecryptedKDM::get_uuid (unsigned char ** p) return buffer; } + static string get (uint8_t ** p, int N) { @@ -126,16 +139,17 @@ get (uint8_t ** p, int N) return g; } + DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) { /* Read the private key */ - BIO* bio = BIO_new_mem_buf (const_cast (private_key.c_str ()), -1); + auto bio = BIO_new_mem_buf (const_cast(private_key.c_str()), -1); if (!bio) { throw MiscError ("could not create memory BIO"); } - RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0); + auto rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0); if (!rsa) { throw FileError ("could not read RSA private key file", private_key, errno); } @@ -148,7 +162,7 @@ DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) int const cipher_value_len = base64_decode (i, cipher_value, sizeof (cipher_value)); /* Decrypt it */ - unsigned char * decrypted = new unsigned char[RSA_size(rsa)]; + auto decrypted = new unsigned char[RSA_size(rsa)]; int const decrypted_len = RSA_private_decrypt (cipher_value_len, cipher_value, decrypted, rsa, RSA_PKCS1_OAEP_PADDING); if (decrypted_len == -1) { delete[] decrypted; @@ -217,6 +231,7 @@ DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) _issue_date = kdm.issue_date (); } + DecryptedKDM::DecryptedKDM ( LocalTime not_valid_before, LocalTime not_valid_after, @@ -233,6 +248,7 @@ DecryptedKDM::DecryptedKDM ( } + DecryptedKDM::DecryptedKDM ( string cpl_id, map, Key> keys, @@ -253,6 +269,7 @@ DecryptedKDM::DecryptedKDM ( } } + DecryptedKDM::DecryptedKDM ( shared_ptr cpl, Key key, @@ -282,23 +299,21 @@ DecryptedKDM::DecryptedKDM ( } } -/** @param type (MDIK, MDAK etc.) - * @param key_id Key ID. - * @param key The actual symmetric key. - * @param cpl_id ID of CPL that the key is for. - */ + void DecryptedKDM::add_key (optional type, string key_id, Key key, string cpl_id, Standard standard) { _keys.push_back (DecryptedKDMKey (type, key_id, key, cpl_id, standard)); } + void DecryptedKDM::add_key (DecryptedKDMKey key) { _keys.push_back (key); } + EncryptedKDM DecryptedKDM::encrypt ( shared_ptr signer, diff --git a/src/decrypted_kdm.h b/src/decrypted_kdm.h index 867e97ff..7bc9a217 100644 --- a/src/decrypted_kdm.h +++ b/src/decrypted_kdm.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2018 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,16 @@ files in the program, then also delete it here. */ -#ifndef LIBDCP_DECRYPTED_KDM_H -#define LIBDCP_DECRYPTED_KDM_H /** @file src/decrypted_kdm.h - * @brief DecryptedKDM class. + * @brief DecryptedKDM class */ + +#ifndef LIBDCP_DECRYPTED_KDM_H +#define LIBDCP_DECRYPTED_KDM_H + + #include "key.h" #include "local_time.h" #include "decrypted_kdm_key.h" @@ -46,18 +49,22 @@ #include #include + class decrypted_kdm_test; + namespace dcp { + class DecryptedKDMKey; class EncryptedKDM; class CertificateChain; class CPL; class ReelMXF; + /** @class DecryptedKDM - * @brief A decrypted KDM. + * @brief A decrypted KDM * * This is a KDM that has either been decrypted by a target private key, or one which * has been created (by some other means) ready for encryption later. @@ -138,7 +145,13 @@ public: boost::optional disable_forensic_marking_audio ) const; + /** @param type (MDIK, MDAK etc.) + * @param key_id Key ID + * @param key The actual symmetric key + * @param cpl_id ID of CPL that the key is for + */ void add_key (boost::optional type, std::string key_id, Key key, std::string cpl_id, Standard standard); + void add_key (DecryptedKDMKey key); /** @return This KDM's (decrypted) keys, which could be used to decrypt assets. */ @@ -173,6 +186,8 @@ private: std::vector _keys; }; + } + #endif diff --git a/src/decrypted_kdm_key.cc b/src/decrypted_kdm_key.cc index e5adc3c6..5d8140ae 100644 --- a/src/decrypted_kdm_key.cc +++ b/src/decrypted_kdm_key.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,18 @@ files in the program, then also delete it here. */ + +/** @file src/decrypted_kdm_key.cc + * @brief DecryptedKDMKey class + */ + + #include "decrypted_kdm_key.h" + using namespace dcp; + bool dcp::operator== (dcp::DecryptedKDMKey const & a, dcp::DecryptedKDMKey const & b) { diff --git a/src/decrypted_kdm_key.h b/src/decrypted_kdm_key.h index 3fee9a68..f1218d3f 100644 --- a/src/decrypted_kdm_key.h +++ b/src/decrypted_kdm_key.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,21 +31,26 @@ files in the program, then also delete it here. */ + /** @file src/decrypted_kdm_key.h * @brief DecryptedKDMKey class */ + #ifndef LIBDCP_DECRYPTED_KDM_KEY_H #define LIBDCP_DECRYPTED_KDM_KEY_H + #include "key.h" #include "types.h" #include + namespace dcp { + /** @class DecryptedKDMKey - * @brief An un- or de-crypted key from a KDM. + * @brief An un- or de-crypted key from a KDM */ class DecryptedKDMKey { @@ -86,8 +91,11 @@ private: Standard _standard; }; + bool operator== (DecryptedKDMKey const &, DecryptedKDMKey const &); + } + #endif diff --git a/src/encrypted_kdm.cc b/src/encrypted_kdm.cc index d7326e89..dec2efcd 100644 --- a/src/encrypted_kdm.cc +++ b/src/encrypted_kdm.cc @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/encrypted_kdm.cc + * @brief EncryptedKDM class + */ + + #include "encrypted_kdm.h" #include "util.h" #include "certificate_chain.h" @@ -44,6 +50,7 @@ #include #include + using std::list; using std::vector; using std::string; @@ -55,11 +62,14 @@ using boost::optional; using boost::starts_with; using namespace dcp; + namespace dcp { + /** Namespace for classes used to hold our data; they are internal to this .cc file */ namespace data { + class Signer { public: @@ -82,6 +92,7 @@ public: string x509_serial_number; }; + class X509Data { public: @@ -104,6 +115,7 @@ public: std::string x509_certificate; }; + class Reference { public: @@ -131,6 +143,7 @@ public: string digest_value; }; + class SignedInfo { public: @@ -171,6 +184,7 @@ private: Reference authenticated_private; }; + class Signature { public: @@ -201,6 +215,7 @@ public: vector x509_data; }; + class AuthenticatedPrivate { public: @@ -235,6 +250,7 @@ public: vector encrypted_key; }; + class TypedKeyId { public: @@ -254,7 +270,7 @@ public: void as_xml (xmlpp::Element* node) const { - xmlpp::Element* type = node->add_child("KeyType"); + auto type = node->add_child("KeyType"); type->add_child_text (key_type); node->add_child("KeyId")->add_child_text ("urn:uuid:" + key_id); /* XXX: this feels like a bit of a hack */ @@ -269,6 +285,7 @@ public: string key_id; }; + class KeyIdList { public: @@ -291,6 +308,7 @@ public: vector typed_key_id; }; + class AuthorizedDeviceInfo { public: @@ -323,6 +341,7 @@ public: std::vector certificate_thumbprints; }; + class X509IssuerSerial { public: @@ -345,6 +364,7 @@ public: string x509_serial_number; }; + class Recipient { public: @@ -367,6 +387,7 @@ public: string x509_subject_name; }; + class KDMRequiredExtensions { public: @@ -450,9 +471,11 @@ private: static const string audio_disable; }; + const string KDMRequiredExtensions::picture_disable = "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-picture-disable"; const string KDMRequiredExtensions::audio_disable = "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-audio-disable"; + class RequiredExtensions { public: @@ -472,6 +495,7 @@ public: KDMRequiredExtensions kdm_required_extensions; }; + class AuthenticatedPublic { public: @@ -516,6 +540,7 @@ public: RequiredExtensions required_extensions; }; + /** Class to describe our data. We use a class hierarchy as it's a bit nicer * for XML data than a flat description. */ @@ -559,9 +584,11 @@ public: Signature signature; }; + } } + EncryptedKDM::EncryptedKDM (string s) { try { @@ -573,7 +600,7 @@ EncryptedKDM::EncryptedKDM (string s) } } -/** @param trusted_devices Trusted device thumbprints */ + EncryptedKDM::EncryptedKDM ( shared_ptr signer, Certificate recipient, @@ -602,7 +629,7 @@ EncryptedKDM::EncryptedKDM ( * DCI_SPECIFIC as specified Yes */ - data::AuthenticatedPublic& aup = _data->authenticated_public; + auto& aup = _data->authenticated_public; aup.signer.x509_issuer_name = signer->leaf().issuer (); aup.signer.x509_serial_number = signer->leaf().serial (); aup.annotation_text = annotation_text; @@ -675,12 +702,14 @@ EncryptedKDM::EncryptedKDM ( _data->signature = data::Signature (signed_doc->node_child ("Signature")); } + EncryptedKDM::EncryptedKDM (EncryptedKDM const & other) : _data (new data::EncryptedKDMData (*other._data)) { } + EncryptedKDM & EncryptedKDM::operator= (EncryptedKDM const & other) { @@ -693,11 +722,13 @@ EncryptedKDM::operator= (EncryptedKDM const & other) return *this; } + EncryptedKDM::~EncryptedKDM () { delete _data; } + void EncryptedKDM::as_xml (boost::filesystem::path path) const { @@ -713,66 +744,77 @@ EncryptedKDM::as_xml (boost::filesystem::path path) const } } + string EncryptedKDM::as_xml () const { return _data->as_xml()->write_to_string ("UTF-8"); } + vector EncryptedKDM::keys () const { return _data->authenticated_private.encrypted_key; } + string EncryptedKDM::id () const { return _data->authenticated_public.message_id; } + optional EncryptedKDM::annotation_text () const { return _data->authenticated_public.annotation_text; } + string EncryptedKDM::content_title_text () const { return _data->authenticated_public.required_extensions.kdm_required_extensions.content_title_text; } + string EncryptedKDM::cpl_id () const { return _data->authenticated_public.required_extensions.kdm_required_extensions.composition_playlist_id; } + string EncryptedKDM::issue_date () const { return _data->authenticated_public.issue_date; } + LocalTime EncryptedKDM::not_valid_before () const { return _data->authenticated_public.required_extensions.kdm_required_extensions.not_valid_before; } + LocalTime EncryptedKDM::not_valid_after () const { return _data->authenticated_public.required_extensions.kdm_required_extensions.not_valid_after; } + string EncryptedKDM::recipient_x509_subject_name () const { return _data->authenticated_public.required_extensions.kdm_required_extensions.recipient.x509_subject_name; } + CertificateChain EncryptedKDM::signer_certificate_chain () const { @@ -784,6 +826,7 @@ EncryptedKDM::signer_certificate_chain () const return chain; } + bool dcp::operator== (EncryptedKDM const & a, EncryptedKDM const & b) { diff --git a/src/encrypted_kdm.h b/src/encrypted_kdm.h index 342bedca..e74dde69 100644 --- a/src/encrypted_kdm.h +++ b/src/encrypted_kdm.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2016 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,34 +31,42 @@ files in the program, then also delete it here. */ + /** @file src/encrypted_kdm.h - * @brief EncryptedKDM class. + * @brief EncryptedKDM class */ + #ifndef LIBDCP_ENCRYPTED_KDM_H #define LIBDCP_ENCRYPTED_KDM_H + #include "local_time.h" #include "types.h" #include #include #include + namespace cxml { class Node; } + namespace dcp { + namespace data { class EncryptedKDMData; } + class CertificateChain; class Certificate; + /** @class EncryptedKDM - * @brief An encrypted KDM. + * @brief An encrypted KDM * * This is a KDM whose keys are encrypted using the target projector's private key. * An EncryptedKDM object can be initialised from a KDM XML file, or created from @@ -117,11 +125,13 @@ private: std::vector keys ); - data::EncryptedKDMData* _data; + data::EncryptedKDMData* _data = nullptr; }; + extern bool operator== (EncryptedKDM const & a, EncryptedKDM const & b); } + #endif diff --git a/src/exceptions.cc b/src/exceptions.cc index 37e699e6..30d11a68 100644 --- a/src/exceptions.cc +++ b/src/exceptions.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2020 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,18 +31,22 @@ files in the program, then also delete it here. */ + /** @file src/exceptions.cc - * @brief Exceptions thrown by libdcp. + * @brief Exceptions thrown by libdcp */ + #include "exceptions.h" #include "compose.hpp" + using std::string; using std::runtime_error; using boost::optional; using namespace dcp; + FileError::FileError (string message, boost::filesystem::path filename, int number) : runtime_error (String::compose ("%1 (%2) (error %3)", message, filename.string(), number)) , _filename (filename) @@ -51,24 +55,28 @@ FileError::FileError (string message, boost::filesystem::path filename, int numb } + UnresolvedRefError::UnresolvedRefError (string id) : runtime_error (String::compose ("Unresolved reference to asset id %1", id)) { } + TimeFormatError::TimeFormatError (string bad_time) : runtime_error (String::compose ("Bad time string %1", bad_time)) { } + BadContentKindError::BadContentKindError (string content_kind) : ReadError (String::compose("Bad content kind '%1'", content_kind)) { } + NotEncryptedError::NotEncryptedError (string const & what) : runtime_error (String::compose ("%1 is not encrypted", what)) { @@ -82,24 +90,28 @@ ProgrammingError::ProgrammingError (string file, int line) } + KDMDecryptionError::KDMDecryptionError (std::string message, int cipher_length, int modulus_dmax) : runtime_error (String::compose ("Could not decrypt KDM (%1) (%2/%3)", message, cipher_length, modulus_dmax)) { } + KDMFormatError::KDMFormatError (std::string message) : runtime_error (String::compose ("Could not parse KDM (%1)", message)) { } + CertificateChainError::CertificateChainError (string message) : runtime_error (message) { } + ReadError::ReadError (string message, string detail) : runtime_error(String::compose("%1 (%2)", message, detail)) , _message(message) @@ -108,12 +120,14 @@ ReadError::ReadError (string message, string detail) } + MissingSubtitleImageError::MissingSubtitleImageError (string id) : runtime_error (String::compose("Could not load image for subtitle %1", id)) { } + BadKDMDateError::BadKDMDateError (bool starts_too_early) : runtime_error ( starts_too_early ? diff --git a/src/font_asset.cc b/src/font_asset.cc index f201d649..a72dc6cb 100644 --- a/src/font_asset.cc +++ b/src/font_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of libdcp. @@ -31,22 +31,26 @@ files in the program, then also delete it here. */ + /** @file src/font_asset.cc - * @brief FontAsset class. + * @brief FontAsset class */ + #include "font_asset.h" -using std::string; +using std::string; using namespace dcp; + FontAsset::FontAsset (string id, boost::filesystem::path file) : Asset (id, file) { } + string FontAsset::static_pkl_type (Standard) { diff --git a/src/font_asset.h b/src/font_asset.h index 1d412619..d39a6b24 100644 --- a/src/font_asset.h +++ b/src/font_asset.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,18 @@ files in the program, then also delete it here. */ + /** @file src/font_asset.h - * @brief FontAsset class. + * @brief FontAsset class */ + #include "asset.h" + namespace dcp { + /** @class FontAsset * @brief A (truetype) font asset for subtitles in an Interop DCP. */ @@ -55,4 +59,5 @@ private: } }; + } diff --git a/src/frame.h b/src/frame.h index 328b22b8..74bd616f 100644 --- a/src/frame.h +++ b/src/frame.h @@ -32,6 +32,11 @@ */ +/** @file src/frame.h + * @brief Frame class + */ + + #ifndef LIBDCP_FRAME_H #define LIBDCP_FRAME_H @@ -52,7 +57,7 @@ public: Frame (R* reader, int n, std::shared_ptr c) { /* XXX: unfortunate guesswork on this buffer size */ - _buffer.reset(new B(Kumu::Megabyte)); + _buffer = std::make_shared(Kumu::Megabyte); if (ASDCP_FAILURE(reader->ReadFrame(n, *_buffer, c->context(), c->hmac()))) { boost::throw_exception (ReadError ("could not read frame")); diff --git a/src/fsk.cc b/src/fsk.cc index 4755e560..b0cfd3ab 100644 --- a/src/fsk.cc +++ b/src/fsk.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of libdcp. @@ -32,6 +32,11 @@ */ +/** @file src/fsk.cc + * @brief FSK class + */ + + #include "fsk.h" #include @@ -42,10 +47,6 @@ using namespace dcp; FSK::FSK () - : _data_position (0) - , _sample_position (0) - , _last_polarity (false) - , _last_bit (false) { } diff --git a/src/fsk.h b/src/fsk.h index c73eb177..0f18141d 100644 --- a/src/fsk.h +++ b/src/fsk.h @@ -32,6 +32,11 @@ */ +/** @file src/fsk.h + * @brief FSK class + */ + + #include #include @@ -60,15 +65,16 @@ public: private: std::vector _data; /** current offset into _data */ - int _data_position; + int _data_position = 0; /** current sample number of the current bit (0-3) */ - int _sample_position; + int _sample_position = 0; /** polarity of the last bit to be written (false for -ve, true for +ve) */ - bool _last_polarity; + bool _last_polarity = false; /** value of the last bit to be written */ - bool _last_bit; + bool _last_bit = false; }; + } diff --git a/src/gamma_transfer_function.cc b/src/gamma_transfer_function.cc index 34501d98..1875221e 100644 --- a/src/gamma_transfer_function.cc +++ b/src/gamma_transfer_function.cc @@ -58,7 +58,7 @@ double * GammaTransferFunction::make_lut (int bit_depth, bool inverse) const { int const bit_length = int(std::pow(2.0f, bit_depth)); - double* lut = new double[bit_length]; + auto lut = new double[bit_length]; double const gamma = inverse ? (1 / _gamma) : _gamma; for (int i = 0; i < bit_length; ++i) { lut[i] = pow(double(i) / (bit_length - 1), gamma); diff --git a/src/identity_transfer_function.cc b/src/identity_transfer_function.cc index ef18825b..c01e6698 100644 --- a/src/identity_transfer_function.cc +++ b/src/identity_transfer_function.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,23 +31,27 @@ files in the program, then also delete it here. */ + /** @file src/identity_transfer_function.cc - * @brief IdentityTransferFunction class. + * @brief IdentityTransferFunction class */ + #include "identity_transfer_function.h" #include + using std::pow; using std::shared_ptr; using std::dynamic_pointer_cast; using namespace dcp; + double * IdentityTransferFunction::make_lut (int bit_depth, bool) const { int const bit_length = int(std::pow(2.0f, bit_depth)); - double* lut = new double[bit_length]; + auto lut = new double[bit_length]; for (int i = 0; i < bit_length; ++i) { lut[i] = double(i) / (bit_length - 1); } @@ -55,9 +59,10 @@ IdentityTransferFunction::make_lut (int bit_depth, bool) const return lut; } + bool IdentityTransferFunction::about_equal (shared_ptr other, double) const { - shared_ptr o = dynamic_pointer_cast (other); + auto o = dynamic_pointer_cast(other); return static_cast(o); } diff --git a/src/identity_transfer_function.h b/src/identity_transfer_function.h index f2313c10..ff6814eb 100644 --- a/src/identity_transfer_function.h +++ b/src/identity_transfer_function.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,18 @@ files in the program, then also delete it here. */ + /** @file src/identity_transfer_function.h - * @brief IdentityTransferFunction class. + * @brief IdentityTransferFunction class */ + #include "transfer_function.h" + namespace dcp { + class IdentityTransferFunction : public TransferFunction { public: @@ -48,4 +52,5 @@ protected: double * make_lut (int bit_depth, bool inverse) const; }; + } diff --git a/src/interop_load_font_node.cc b/src/interop_load_font_node.cc index a5bc1428..40f12dde 100644 --- a/src/interop_load_font_node.cc +++ b/src/interop_load_font_node.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,22 @@ files in the program, then also delete it here. */ + +/** @file src/interop_load_font_node.cc + * @brief InteropLoadFontNode class + */ + + #include "interop_load_font_node.h" #include + using std::string; using std::shared_ptr; using boost::optional; using namespace dcp; + InteropLoadFontNode::InteropLoadFontNode (string id_, string uri_) : LoadFontNode (id_) , uri (uri_) @@ -46,23 +54,26 @@ InteropLoadFontNode::InteropLoadFontNode (string id_, string uri_) } + InteropLoadFontNode::InteropLoadFontNode (cxml::ConstNodePtr node) { - optional x = node->optional_string_attribute ("Id"); + auto x = node->optional_string_attribute("Id"); if (!x) { - x = node->optional_string_attribute ("ID"); + x = node->optional_string_attribute("ID"); } id = x.get_value_or (""); uri = node->string_attribute ("URI"); } + bool dcp::operator== (InteropLoadFontNode const & a, InteropLoadFontNode const & b) { return a.id == b.id && a.uri == b.uri; } + bool dcp::operator!= (InteropLoadFontNode const & a, InteropLoadFontNode const & b) { diff --git a/src/interop_load_font_node.h b/src/interop_load_font_node.h index 17ce1893..6fe3fb1c 100644 --- a/src/interop_load_font_node.h +++ b/src/interop_load_font_node.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,21 @@ files in the program, then also delete it here. */ + +/** @file src/interop_load_font_node.h + * @brief InteropLoadFontNode class + */ + + #include "load_font_node.h" #include -#include #include +#include + namespace dcp { + class InteropLoadFontNode : public LoadFontNode { public: @@ -48,7 +56,9 @@ public: std::string uri; }; + bool operator== (InteropLoadFontNode const & a, InteropLoadFontNode const & b); bool operator!= (InteropLoadFontNode const & a, InteropLoadFontNode const & b); + } diff --git a/src/interop_subtitle_asset.cc b/src/interop_subtitle_asset.cc index 9c977b44..938c028e 100644 --- a/src/interop_subtitle_asset.cc +++ b/src/interop_subtitle_asset.cc @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/interop_subtitle_asset.cc + * @brief InteropSubtitleAsset class + */ + + #include "interop_subtitle_asset.h" #include "interop_load_font_node.h" #include "subtitle_asset_internal.h" @@ -46,6 +52,7 @@ #include #include + using std::list; using std::string; using std::cout; @@ -59,12 +66,13 @@ using boost::shared_array; using boost::optional; using namespace dcp; + InteropSubtitleAsset::InteropSubtitleAsset (boost::filesystem::path file) : SubtitleAsset (file) { _raw_xml = dcp::file_to_string (file); - shared_ptr xml (new cxml::Document ("DCSubtitle")); + auto xml = make_shared("DCSubtitle"); xml->read_file (file); _id = xml->string_child ("SubtitleID"); _reel_number = xml->string_child ("ReelNumber"); @@ -75,9 +83,8 @@ InteropSubtitleAsset::InteropSubtitleAsset (boost::filesystem::path file) /* Now we need to drop down to xmlpp */ vector ps; - xmlpp::Node::NodeList c = xml->node()->get_children (); - for (xmlpp::Node::NodeList::const_iterator i = c.begin(); i != c.end(); ++i) { - xmlpp::Element const * e = dynamic_cast (*i); + for (auto i: xml->node()->get_children()) { + auto e = dynamic_cast(i); if (e && (e->get_name() == "Font" || e->get_name() == "Subtitle")) { parse_subtitles (e, ps, optional(), Standard::INTEROP); } @@ -91,16 +98,18 @@ InteropSubtitleAsset::InteropSubtitleAsset (boost::filesystem::path file) } } + InteropSubtitleAsset::InteropSubtitleAsset () { } + string InteropSubtitleAsset::xml_as_string () const { xmlpp::Document doc; - xmlpp::Element* root = doc.create_root_node ("DCSubtitle"); + auto root = doc.create_root_node ("DCSubtitle"); root->set_attribute ("Version", "1.0"); root->add_child("SubtitleID")->add_child_text (_id); @@ -119,14 +128,16 @@ InteropSubtitleAsset::xml_as_string () const return doc.write_to_string ("UTF-8"); } + void InteropSubtitleAsset::add_font (string load_id, dcp::ArrayData data) { _fonts.push_back (Font(load_id, make_uuid(), data)); - string const uri = String::compose("font_%1.ttf", _load_font_nodes.size()); + auto const uri = String::compose("font_%1.ttf", _load_font_nodes.size()); _load_font_nodes.push_back (shared_ptr(new InteropLoadFontNode(load_id, uri))); } + bool InteropSubtitleAsset::equals (shared_ptr other_asset, EqualityOptions options, NoteHandler note) const { @@ -134,7 +145,7 @@ InteropSubtitleAsset::equals (shared_ptr other_asset, EqualityOptio return false; } - shared_ptr other = dynamic_pointer_cast (other_asset); + auto other = dynamic_pointer_cast (other_asset); if (!other) { return false; } @@ -167,6 +178,7 @@ InteropSubtitleAsset::equals (shared_ptr other_asset, EqualityOptio return true; } + vector> InteropSubtitleAsset::load_font_nodes () const { @@ -175,16 +187,16 @@ InteropSubtitleAsset::load_font_nodes () const return lf; } -/** Write this content to an XML file with its fonts alongside */ + void InteropSubtitleAsset::write (boost::filesystem::path p) const { - FILE* f = fopen_boost (p, "w"); + auto f = fopen_boost (p, "w"); if (!f) { throw FileError ("Could not open file for writing", p, -1); } - string const s = xml_as_string (); + auto const s = xml_as_string (); /* length() here gives bytes not characters */ fwrite (s.c_str(), 1, s.length(), f); fclose (f); @@ -213,6 +225,7 @@ InteropSubtitleAsset::write (boost::filesystem::path p) const } } + /** Look at a supplied list of assets and find the fonts. Then match these * fonts up with anything requested by a so that _fonts contains * a list of font ID, load ID and data. @@ -242,6 +255,7 @@ InteropSubtitleAsset::resolve_fonts (vector> assets) } } + void InteropSubtitleAsset::add_font_assets (vector>& assets) { @@ -251,6 +265,7 @@ InteropSubtitleAsset::add_font_assets (vector>& assets) } } + void InteropSubtitleAsset::write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const { @@ -265,6 +280,7 @@ InteropSubtitleAsset::write_to_assetmap (xmlpp::Node* node, boost::filesystem::p } } + void InteropSubtitleAsset::add_to_pkl (shared_ptr pkl, boost::filesystem::path root) const { diff --git a/src/interop_subtitle_asset.h b/src/interop_subtitle_asset.h index 41e04f97..07bfeadf 100644 --- a/src/interop_subtitle_asset.h +++ b/src/interop_subtitle_asset.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,19 +31,24 @@ files in the program, then also delete it here. */ + /** @file src/interop_subtitle_asset.h - * @brief InteropSubtitleAsset class. + * @brief InteropSubtitleAsset class */ + #include "subtitle_asset.h" #include + namespace dcp { + class InteropLoadFontNode; + /** @class InteropSubtitleAsset - * @brief A set of subtitles to be read and/or written in the Inter-Op format. + * @brief A set of subtitles to be read and/or written in the Inter-Op format * * Inter-Op subtitles are sometimes known as CineCanvas. */ @@ -67,7 +72,10 @@ public: void add_font (std::string load_id, dcp::ArrayData data); std::string xml_as_string () const; + + /** Write this content to an XML file with its fonts alongside */ void write (boost::filesystem::path path) const; + void resolve_fonts (std::vector> assets); void add_font_assets (std::vector>& assets); void set_font_file (std::string load_id, boost::filesystem::path file); diff --git a/src/j2k.cc b/src/j2k.cc index 654146ca..c07bdccd 100644 --- a/src/j2k.cc +++ b/src/j2k.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -32,6 +32,11 @@ */ +/** @file src/j2k.cc + * @brief Methods to encode and decode JPEG2000 + */ + + #include "array_data.h" #include "j2k.h" #include "exceptions.h" @@ -42,6 +47,7 @@ #include #include + using std::min; using std::pow; using std::string; @@ -49,12 +55,14 @@ using std::shared_ptr; using boost::shared_array; using namespace dcp; + shared_ptr dcp::decompress_j2k (ArrayData data, int reduce) { return dcp::decompress_j2k (data.data(), data.size(), reduce); } + #ifdef LIBDCP_OPENJPEG2 class ReadBuffer @@ -80,12 +88,14 @@ private: OPJ_SIZE_T _offset; }; + static OPJ_SIZE_T read_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data) { return reinterpret_cast(data)->read (buffer, nb_bytes); } + static void read_free_function (void* data) { @@ -106,15 +116,7 @@ compress_error_callback (char const * msg, void *) throw MiscError (msg); } -/** Decompress a JPEG2000 image to a bitmap. - * @param data JPEG2000 data. - * @param size Size of data in bytes. - * @param reduce A power of 2 by which to reduce the size of the decoded image; - * e.g. 0 reduces by (2^0 == 1), ie keeping the same size. - * 1 reduces by (2^1 == 2), ie halving the size of the image. - * This is useful for scaling 4K DCP images down to 2K. - * @return OpenJPEGImage. - */ + shared_ptr dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) { @@ -131,12 +133,12 @@ dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) 0x20 }; - OPJ_CODEC_FORMAT format = OPJ_CODEC_J2K; + auto format = OPJ_CODEC_J2K; if (size >= int (sizeof (jp2_magic)) && memcmp (data, jp2_magic, sizeof (jp2_magic)) == 0) { format = OPJ_CODEC_JP2; } - opj_codec_t* decoder = opj_create_decompress (format); + auto decoder = opj_create_decompress (format); if (!decoder) { boost::throw_exception (ReadError ("could not create JPEG2000 decompresser")); } @@ -145,7 +147,7 @@ dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) parameters.cp_reduce = reduce; opj_setup_decoder (decoder, ¶meters); - opj_stream_t* stream = opj_stream_default_create (OPJ_TRUE); + auto stream = opj_stream_default_create (OPJ_TRUE); if (!stream) { throw MiscError ("could not create JPEG2000 stream"); } @@ -153,7 +155,7 @@ dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) opj_set_error_handler(decoder, decompress_error_callback, 00); opj_stream_set_read_function (stream, read_function); - ReadBuffer* buffer = new ReadBuffer (data, size); + auto buffer = new ReadBuffer (data, size); opj_stream_set_user_data (stream, buffer, read_free_function); opj_stream_set_user_data_length (stream, size); @@ -176,28 +178,22 @@ dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) image->y1 = rint (float(image->y1) / pow (2.0f, reduce)); return shared_ptr (new OpenJPEGImage (image)); } + #endif + #ifdef LIBDCP_OPENJPEG1 -/** Decompress a JPEG2000 image to a bitmap. - * @param data JPEG2000 data. - * @param size Size of data in bytes. - * @param reduce A power of 2 by which to reduce the size of the decoded image; - * e.g. 0 reduces by (2^0 == 1), ie keeping the same size. - * 1 reduces by (2^1 == 2), ie halving the size of the image. - * This is useful for scaling 4K DCP images down to 2K. - * @return XYZ image. - */ + shared_ptr dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) { - opj_dinfo_t* decoder = opj_create_decompress (CODEC_J2K); + auto decoder = opj_create_decompress (CODEC_J2K); opj_dparameters_t parameters; opj_set_default_decoder_parameters (¶meters); parameters.cp_reduce = reduce; opj_setup_decoder (decoder, ¶meters); - opj_cio_t* cio = opj_cio_open ((opj_common_ptr) decoder, data, size); - opj_image_t* image = opj_decode (decoder, cio); + auto cio = opj_cio_open ((opj_common_ptr) decoder, data, size); + auto image = opj_decode (decoder, cio); if (!image) { opj_destroy_decompress (decoder); opj_cio_close (cio); @@ -213,14 +209,16 @@ dcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) } #endif + #ifdef LIBDCP_OPENJPEG2 + class WriteBuffer { public: /* XXX: is there a better strategy for this? */ #define MAX_J2K_SIZE (1024 * 1024 * 2) WriteBuffer () - : _data (shared_array (new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE) + : _data (shared_array(new uint8_t[MAX_J2K_SIZE]), MAX_J2K_SIZE) , _offset (0) { _data.set_size (0); @@ -231,7 +229,7 @@ public: DCP_ASSERT ((_offset + nb_bytes) < MAX_J2K_SIZE); memcpy (_data.data() + _offset, buffer, nb_bytes); _offset += nb_bytes; - if (_offset > OPJ_SIZE_T (_data.size())) { + if (_offset > OPJ_SIZE_T(_data.size())) { _data.set_size (_offset); } return nb_bytes; @@ -253,33 +251,35 @@ private: OPJ_SIZE_T _offset; }; + static OPJ_SIZE_T write_function (void* buffer, OPJ_SIZE_T nb_bytes, void* data) { - return reinterpret_cast(data)->write (buffer, nb_bytes); + return reinterpret_cast(data)->write(buffer, nb_bytes); } + static void write_free_function (void* data) { delete reinterpret_cast(data); } + static OPJ_BOOL seek_function (OPJ_OFF_T nb_bytes, void* data) { - return reinterpret_cast(data)->seek (nb_bytes); + return reinterpret_cast(data)->seek(nb_bytes); + } -/** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used - * after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data. - */ + ArrayData dcp::compress_j2k (shared_ptr xyz, int bandwidth, int frames_per_second, bool threed, bool fourk, string comment) { /* get a J2K compressor handle */ - opj_codec_t* encoder = opj_create_compress (OPJ_CODEC_J2K); - if (encoder == 0) { + auto encoder = opj_create_compress (OPJ_CODEC_J2K); + if (encoder == nullptr) { throw MiscError ("could not create JPEG2000 encoder"); } @@ -312,7 +312,7 @@ dcp::compress_j2k (shared_ptr xyz, int bandwidth, int frame /* Setup the encoder parameters using the current image and user parameters */ opj_setup_encoder (encoder, ¶meters, xyz->opj_image()); - opj_stream_t* stream = opj_stream_default_create (OPJ_FALSE); + auto stream = opj_stream_default_create (OPJ_FALSE); if (!stream) { opj_destroy_codec (encoder); free (parameters.cp_comment); @@ -358,9 +358,12 @@ dcp::compress_j2k (shared_ptr xyz, int bandwidth, int frame return enc; } + #endif + #ifdef LIBDCP_OPENJPEG1 + ArrayData dcp::compress_j2k (shared_ptr xyz, int bandwidth, int frames_per_second, bool threed, bool fourk) { @@ -373,8 +376,8 @@ dcp::compress_j2k (shared_ptr xyz, int bandwidth, int frame int const max_comp_size = max_cs_len / 1.25; /* get a J2K compressor handle */ - opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K); - if (cinfo == 0) { + auto cinfo = opj_create_compress (CODEC_J2K); + if (cinfo == nullptr) { throw MiscError ("could not create JPEG2000 encoder"); } @@ -453,10 +456,10 @@ dcp::compress_j2k (shared_ptr xyz, int bandwidth, int frame cinfo->event_mgr = 0; /* Setup the encoder parameters using the current image and user parameters */ - opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ()); + opj_setup_encoder (cinfo, ¶meters, xyz->opj_image()); - opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0); - if (cio == 0) { + auto cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0); + if (cio == nullptr) { opj_destroy_compress (cinfo); throw MiscError ("could not open JPEG2000 stream"); } diff --git a/src/j2k.h b/src/j2k.h index a5b41f3c..a4c4f0bd 100644 --- a/src/j2k.h +++ b/src/j2k.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -32,16 +32,39 @@ */ +/** @file src/j2k.h + * @brief Methods to encode and decode JPEG2000 + */ + + #include "array_data.h" #include #include + namespace dcp { + class OpenJPEGImage; + extern std::shared_ptr decompress_j2k (uint8_t* data, int64_t size, int reduce); + +/** Decompress a JPEG2000 image to a bitmap + * @param data JPEG2000 data + * @param size Size of data in bytes + * @param reduce A power of 2 by which to reduce the size of the decoded image; + * e.g. 0 reduces by (2^0 == 1), ie keeping the same size. + * 1 reduces by (2^1 == 2), ie halving the size of the image. + * This is useful for scaling 4K DCP images down to 2K. + * @return OpenJPEGImage + */ extern std::shared_ptr decompress_j2k (ArrayData data, int reduce); + +/** @xyz Picture to compress. Parts of xyz's data WILL BE OVERWRITTEN by libopenjpeg so xyz cannot be re-used + * after this call; see opj_j2k_encode where if l_reuse_data is false it will set l_tilec->data = l_img_comp->data. + */ extern ArrayData compress_j2k (std::shared_ptr, int bandwith, int frames_per_second, bool threed, bool fourk, std::string comment = "libdcp"); + } diff --git a/src/language_tag.cc b/src/language_tag.cc index 07e95564..c2e81869 100644 --- a/src/language_tag.cc +++ b/src/language_tag.cc @@ -32,6 +32,11 @@ */ +/** @file src/language_tag.cc + * @brief LanguageTag class + */ + + #include "compose.hpp" #include "dcp_assert.h" #include "exceptions.h" @@ -67,7 +72,7 @@ find_in_list (vector const& list, string subtag) } } - return optional(); + return {}; } @@ -147,7 +152,7 @@ LanguageTag::to_string () const throw LanguageTagError("No language set up"); } - string s = _language->subtag(); + auto s = _language->subtag(); if (_script) { s += "-" + _script->subtag(); @@ -264,19 +269,19 @@ LanguageTag::description () const d += language->description; if (_script) { - optional script = get_subtag_data (SubtagType::SCRIPT, _script->subtag()); + auto script = get_subtag_data (SubtagType::SCRIPT, _script->subtag()); DCP_ASSERT (script); d += " written using the " + script->description + " script"; } if (_region) { - optional region = get_subtag_data (SubtagType::REGION, _region->subtag()); + auto region = get_subtag_data (SubtagType::REGION, _region->subtag()); DCP_ASSERT (region); d += " for " + region->description; } for (auto const& i: _extlangs) { - optional extlang = get_subtag_data (SubtagType::EXTLANG, i.subtag()); + auto extlang = get_subtag_data (SubtagType::EXTLANG, i.subtag()); DCP_ASSERT (extlang); d += ", " + extlang->description; } @@ -321,7 +326,7 @@ LanguageTag::subtag_type_name (SubtagType type) return "Extended"; } - return ""; + return {}; } bool @@ -412,16 +417,16 @@ LanguageTag::get_subtag_data (LanguageTag::SubtagType type, string subtag) return find_in_list(extlang_list, subtag); } - return optional(); + return {}; } optional LanguageTag::get_subtag_description (LanguageTag::SubtagType type, string subtag) { - optional data = get_subtag_data (type, subtag); + auto data = get_subtag_data (type, subtag); if (!data) { - return optional(); + return {}; } return data->description; @@ -431,7 +436,7 @@ LanguageTag::get_subtag_description (LanguageTag::SubtagType type, string subtag void load_language_tag_list (boost::filesystem::path tags_directory, string name, vector& list) { - FILE* f = fopen_boost (tags_directory / name, "r"); + auto f = fopen_boost (tags_directory / name, "r"); if (!f) { throw FileError ("Could not open tags file", tags_directory / name, errno); } diff --git a/src/language_tag.h b/src/language_tag.h index 06134b03..3b0b6ac9 100644 --- a/src/language_tag.h +++ b/src/language_tag.h @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/language_tag.cc + * @brief LanguageTag class + */ + + #ifndef LIBDCP_LANGUAGE_TAG_H #define LIBDCP_LANGUAGE_TAG_H @@ -232,12 +238,14 @@ private: std::vector _extlangs; }; + extern bool operator==(dcp::LanguageTag const& a, dcp::LanguageTag const& b); extern std::ostream& operator<<(std::ostream& os, dcp::LanguageTag const& tag); extern void load_language_tag_lists (boost::filesystem::path tags_directory); + } #endif diff --git a/src/load_font_node.h b/src/load_font_node.h index 068f7d21..b57eb3c4 100644 --- a/src/load_font_node.h +++ b/src/load_font_node.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,16 +31,20 @@ files in the program, then also delete it here. */ + /** @file src/load_font_node.h - * @brief LoadFontNode class. + * @brief LoadFontNode class */ + #include + namespace dcp { + /** @class LoadFontNode - * @brief Parser for LoadFont nodes from subtitle XML. + * @brief Parser for LoadFont nodes from subtitle XML */ class LoadFontNode { diff --git a/src/local_time.cc b/src/local_time.cc index 6a8579ff..892ffba4 100644 --- a/src/local_time.cc +++ b/src/local_time.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2020 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/local_time.cc - * @brief LocalTime class. + * @brief LocalTime class */ + #include "local_time.h" #include "exceptions.h" #include "dcp_assert.h" @@ -44,26 +46,29 @@ #include #include + using std::string; using std::ostream; using boost::lexical_cast; using namespace dcp; -/** Construct a LocalTime from the current time */ + LocalTime::LocalTime () { - time_t now = time (0); - struct tm* tm = localtime (&now); + auto now = time (0); + auto tm = localtime (&now); set (tm); set_local_time_zone (); } + LocalTime::LocalTime (struct tm t) { set (&t); set_local_time_zone (); } + void LocalTime::set (struct tm const * tm) { @@ -76,15 +81,14 @@ LocalTime::set (struct tm const * tm) _millisecond = 0; } -/** Construct a LocalTime from a boost::posix_time::ptime using the local - * time zone. - */ + LocalTime::LocalTime (boost::posix_time::ptime t) { set (t); set_local_time_zone (); } + void LocalTime::set (boost::posix_time::ptime t) { @@ -98,10 +102,7 @@ LocalTime::set (boost::posix_time::ptime t) DCP_ASSERT (_millisecond < 1000); } -/** Construct a LocalTime from a boost::posix_time::ptime and a time zone offset. - * @param tz_minute Offset from UTC in minutes; if the timezone is behind UTC this may be negative, - * e.g. -04:30 would have tz_hour=-1 and tz_minute=-30. - */ + LocalTime::LocalTime (boost::posix_time::ptime t, int tz_hour, int tz_minute) { set (t); @@ -109,19 +110,20 @@ LocalTime::LocalTime (boost::posix_time::ptime t, int tz_hour, int tz_minute) _tz_minute = tz_minute; } + /** Set our UTC offset to be according to the local time zone */ void LocalTime::set_local_time_zone () { - boost::posix_time::ptime const utc_now = boost::posix_time::second_clock::universal_time (); - boost::posix_time::ptime const now = boost::date_time::c_local_adjustor::utc_to_local (utc_now); - boost::posix_time::time_duration offset = now - utc_now; + auto const utc_now = boost::posix_time::second_clock::universal_time (); + auto const now = boost::date_time::c_local_adjustor::utc_to_local (utc_now); + auto offset = now - utc_now; _tz_hour = offset.hours (); _tz_minute = offset.minutes (); } -/** @param s A string of the form 2013-01-05T18:06:59[.123][+04:00] */ + LocalTime::LocalTime (string s) { /* 2013-01-05T18:06:59 or 2013-01-05T18:06:59.123 or 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */ @@ -163,15 +165,15 @@ LocalTime::LocalTime (string s) throw TimeFormatError (s); } - _year = lexical_cast (s.substr (0, 4)); - _month = lexical_cast (s.substr (5, 2)); - _day = lexical_cast (s.substr (8, 2)); - _hour = lexical_cast (s.substr (11, 2)); - _minute = lexical_cast (s.substr (14, 2)); - _second = lexical_cast (s.substr (17, 2)); - _millisecond = with_millisecond ? lexical_cast (s.substr (20, 3)) : 0; - _tz_hour = with_tz ? lexical_cast (s.substr (tz_pos + 1, 2)) : 0; - _tz_minute = with_tz ? lexical_cast (s.substr (tz_pos + 4, 2)) : 0; + _year = lexical_cast(s.substr(0, 4)); + _month = lexical_cast(s.substr(5, 2)); + _day = lexical_cast(s.substr(8, 2)); + _hour = lexical_cast(s.substr(11, 2)); + _minute = lexical_cast(s.substr(14, 2)); + _second = lexical_cast(s.substr(17, 2)); + _millisecond = with_millisecond ? lexical_cast(s.substr(20, 3)) : 0; + _tz_hour = with_tz ? lexical_cast(s.substr(tz_pos + 1, 2)) : 0; + _tz_minute = with_tz ? lexical_cast(s.substr(tz_pos + 4, 2)) : 0; if (with_tz && s[tz_pos] == '-') { _tz_hour = -_tz_hour; @@ -179,7 +181,7 @@ LocalTime::LocalTime (string s) } } -/** @return A string of the form 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */ + string LocalTime::as_string (bool with_millisecond) const { @@ -192,7 +194,7 @@ LocalTime::as_string (bool with_millisecond) const return buffer; } -/** @return The date in the form YYYY-MM-DD */ + string LocalTime::date () const { @@ -201,7 +203,7 @@ LocalTime::date () const return buffer; } -/** @return The time in the form HH:MM:SS or HH:MM:SS.mmm */ + string LocalTime::time_of_day (bool with_second, bool with_millisecond) const { @@ -249,6 +251,7 @@ LocalTime::add_months (int m) set (posix_time::ptime(d, posix_time::time_duration(_hour, _minute, _second, _millisecond * 1000))); } + void LocalTime::add_minutes (int m) { @@ -259,6 +262,7 @@ LocalTime::add_minutes (int m) set (t); } + bool LocalTime::operator== (LocalTime const & other) const { @@ -267,6 +271,7 @@ LocalTime::operator== (LocalTime const & other) const _tz_hour == other._tz_hour && _tz_minute == other._tz_minute; } + bool LocalTime::operator< (LocalTime const & other) const { @@ -288,12 +293,14 @@ LocalTime::operator< (LocalTime const & other) const return _millisecond < other._millisecond; } + bool LocalTime::operator!= (LocalTime const & other) const { return !(*this == other); } + ostream& dcp::operator<< (ostream& s, LocalTime const & t) { diff --git a/src/local_time.h b/src/local_time.h index e818ba6e..a5a479cd 100644 --- a/src/local_time.h +++ b/src/local_time.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2020 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,20 +31,26 @@ files in the program, then also delete it here. */ + /** @file src/local_time.h - * @brief LocalTime class. + * @brief LocalTime class */ + #ifndef LIBDCP_LOCAL_TIME_H #define LIBDCP_LOCAL_TIME_H + #include #include + class local_time_basic_test; + namespace dcp { + /** @class LocalTime * @brief A representation of a local time (down to the second), including its offset * from GMT (equivalent to xs:dateTime). @@ -57,14 +63,32 @@ namespace dcp { class LocalTime { public: + /** Construct a LocalTime from the current time */ LocalTime (); + explicit LocalTime (struct tm tm); + + /** Construct a LocalTime from a boost::posix_time::ptime using the local + * time zone + */ explicit LocalTime (boost::posix_time::ptime); + + /** Construct a LocalTime from a boost::posix_time::ptime and a time zone offset + * @param tz_minute Offset from UTC in minutes; if the timezone is behind UTC this may be negative, + * e.g. -04:30 would have tz_hour=-1 and tz_minute=-30. + */ LocalTime (boost::posix_time::ptime, int tz_hour, int tz_minute); - explicit LocalTime (std::string); + /** @param s A string of the form 2013-01-05T18:06:59[.123][+04:00] */ + explicit LocalTime (std::string s); + + /** @return A string of the form 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */ std::string as_string (bool with_millisecond = false) const; + + /** @return The date in the form YYYY-MM-DD */ std::string date () const; + + /** @return The time in the form HH:MM:SS or HH:MM:SS.mmm */ std::string time_of_day (bool with_second, bool with_millisecond) const; int day () const { @@ -99,24 +123,27 @@ private: void set_local_time_zone (); /* Local time */ - int _year; ///< year - int _month; ///< month number of the year (1-12) - int _day; ///< day number of the month (1-31) - int _hour; ///< hour number of the day (0-23) - int _minute; ///< minute number of the hour (0-59) - int _second; ///< second number of the minute (0-59) - int _millisecond; ///< millisecond number of the second (0-999) - - int _tz_hour; ///< hours by which this time is offset from UTC; can be negative + int _year = 0; ///< year + int _month = 0; ///< month number of the year (1-12) + int _day = 0; ///< day number of the month (1-31) + int _hour = 0; ///< hour number of the day (0-23) + int _minute = 0; ///< minute number of the hour (0-59) + int _second = 0; ///< second number of the minute (0-59) + int _millisecond = 0; ///< millisecond number of the second (0-999) + + int _tz_hour = 0; ///< hours by which this time is offset from UTC; can be negative /** Minutes by which this time is offset from UTC; if _tz_hour is negative * this will be either 0 or negative. */ - int _tz_minute; + int _tz_minute = 0; }; + std::ostream& operator<< (std::ostream& s, LocalTime const & t); + } + #endif diff --git a/src/locale_convert.cc b/src/locale_convert.cc index 915cac82..2c7c74ef 100644 --- a/src/locale_convert.cc +++ b/src/locale_convert.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,21 @@ files in the program, then also delete it here. */ + +/** @file src/locale_convert.cc + * @brief Methods to convert to/from string using the current locale + */ + + #include "locale_convert.h" #include #include + using std::string; using std::wstring; + template<> string dcp::locale_convert (unsigned char x, int, bool) @@ -47,6 +55,7 @@ dcp::locale_convert (unsigned char x, int, bool) return buffer; } + template<> string dcp::locale_convert (unsigned short int x, int, bool) @@ -56,6 +65,7 @@ dcp::locale_convert (unsigned short int x, int, bool) return buffer; } + template<> string dcp::locale_convert (int x, int, bool) @@ -65,6 +75,7 @@ dcp::locale_convert (int x, int, bool) return buffer; } + template<> string dcp::locale_convert (unsigned int x, int, bool) @@ -74,6 +85,7 @@ dcp::locale_convert (unsigned int x, int, bool) return buffer; } + template<> string dcp::locale_convert (long int x, int, bool) @@ -87,6 +99,7 @@ dcp::locale_convert (long int x, int, bool) return buffer; } + template<> string dcp::locale_convert (unsigned long int x, int, bool) @@ -96,6 +109,7 @@ dcp::locale_convert (unsigned long int x, int, bool) return buffer; } + template<> string dcp::locale_convert (long long int x, int, bool) @@ -109,6 +123,7 @@ dcp::locale_convert (long long int x, int, bool) return buffer; } + template<> string dcp::locale_convert (unsigned long long int x, int, bool) @@ -122,6 +137,7 @@ dcp::locale_convert (unsigned long long int x, int, bool) return buffer; } + template<> string dcp::locale_convert (float x, int precision, bool fixed) @@ -137,6 +153,7 @@ dcp::locale_convert (float x, int precision, bool fixed) return buffer; } + template<> string dcp::locale_convert (double x, int precision, bool fixed) @@ -152,6 +169,7 @@ dcp::locale_convert (double x, int precision, bool fixed) return buffer; } + template<> string dcp::locale_convert (string x, int, bool) @@ -159,6 +177,7 @@ dcp::locale_convert (string x, int, bool) return x; } + template<> string dcp::locale_convert (char* x, int, bool) @@ -166,6 +185,7 @@ dcp::locale_convert (char* x, int, bool) return x; } + template<> string dcp::locale_convert (char const * x, int, bool) @@ -173,6 +193,7 @@ dcp::locale_convert (char const * x, int, bool) return x; } + template<> string dcp::locale_convert (wchar_t const * x, int, bool) @@ -181,6 +202,7 @@ dcp::locale_convert (wchar_t const * x, int, bool) return string (s.begin(), s.end()); } + template<> string dcp::locale_convert (char x, int, bool) @@ -190,6 +212,7 @@ dcp::locale_convert (char x, int, bool) return s; } + template<> string dcp::locale_convert (boost::filesystem::path x, int, bool) @@ -197,6 +220,7 @@ dcp::locale_convert (boost::filesystem::path x, int, bool) return x.string(); } + template<> unsigned char dcp::locale_convert (string x, int, bool) @@ -206,6 +230,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> unsigned short int dcp::locale_convert (string x, int, bool) @@ -215,6 +240,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> unsigned int dcp::locale_convert (string x, int, bool) @@ -224,6 +250,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> int dcp::locale_convert (string x, int, bool) @@ -233,6 +260,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> long dcp::locale_convert (string x, int, bool) @@ -242,6 +270,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> unsigned long dcp::locale_convert (string x, int, bool) @@ -255,6 +284,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> long long dcp::locale_convert (string x, int, bool) @@ -268,6 +298,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> unsigned long long dcp::locale_convert (string x, int, bool) @@ -281,6 +312,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> float dcp::locale_convert (string x, int, bool) @@ -290,6 +322,7 @@ dcp::locale_convert (string x, int, bool) return y; } + template<> double dcp::locale_convert (string x, int, bool) diff --git a/src/locale_convert.h b/src/locale_convert.h index ab1984e4..9b1b432c 100644 --- a/src/locale_convert.h +++ b/src/locale_convert.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,17 +31,26 @@ files in the program, then also delete it here. */ + +/** @file src/locale_convert.cc + * @brief Methods to convert to/from string using the current locale. + */ + + #ifndef LIBDCP_LOCALE_CONVERT_H #define LIBDCP_LOCALE_CONVERT_H + #include "util.h" #include #include #include #include + namespace dcp { + template P locale_convert (Q, int precision = 16, bool fixed = false) @@ -158,6 +167,8 @@ template <> double locale_convert (std::string x, int, bool); + } + #endif diff --git a/src/metadata.cc b/src/metadata.cc index 6fedc61e..750143d1 100644 --- a/src/metadata.cc +++ b/src/metadata.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/metadata.cc - * @brief MXFMetadata class. + * @brief MXFMetadata class */ + #include "metadata.h" #include "util.h" #include "local_time.h" @@ -42,9 +44,10 @@ #include #include -using namespace std; + using namespace dcp; + MXFMetadata::MXFMetadata () : company_name ("libdcp") , product_name ("libdcp") @@ -53,6 +56,7 @@ MXFMetadata::MXFMetadata () } + void MXFMetadata::read (ASDCP::WriterInfo const & info) { diff --git a/src/metadata.h b/src/metadata.h index b24265f3..364cb388 100644 --- a/src/metadata.h +++ b/src/metadata.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,24 +31,31 @@ files in the program, then also delete it here. */ -#ifndef LIBDCP_METADATA_H -#define LIBDCP_METADATA_H /** @file src/metadata.h * @brief MXFMetadata class. */ + +#ifndef LIBDCP_METADATA_H +#define LIBDCP_METADATA_H + + #include + class utc_offset_to_string_test; + namespace ASDCP { struct WriterInfo; } + namespace dcp { + /** @class MXFMetadata * @brief Metadata that is written to a MXF file's header */ @@ -69,6 +76,8 @@ public: std::string product_version; }; + } + #endif diff --git a/src/modified_gamma_transfer_function.cc b/src/modified_gamma_transfer_function.cc index bb388689..039e9284 100644 --- a/src/modified_gamma_transfer_function.cc +++ b/src/modified_gamma_transfer_function.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,22 @@ files in the program, then also delete it here. */ + +/** @file src/modified_gamma_transfer_function.cc + * @brief ModifiedGammaTransferFunction class + */ + + #include "modified_gamma_transfer_function.h" #include + using std::pow; using std::shared_ptr; using std::dynamic_pointer_cast; using namespace dcp; + ModifiedGammaTransferFunction::ModifiedGammaTransferFunction (double power, double threshold, double A, double B) : _power (power) , _threshold (threshold) @@ -48,6 +56,7 @@ ModifiedGammaTransferFunction::ModifiedGammaTransferFunction (double power, doub } + double * ModifiedGammaTransferFunction::make_lut (int bit_depth, bool inverse) const { @@ -56,7 +65,7 @@ ModifiedGammaTransferFunction::make_lut (int bit_depth, bool inverse) const if (inverse) { double const threshold = _threshold / _B; for (int i = 0; i < bit_length; ++i) { - double const p = static_cast (i) / (bit_length - 1); + double const p = static_cast(i) / (bit_length - 1); if (p > threshold) { lut[i] = (1 + _A) * pow (p, 1 / _power) - _A; } else { @@ -65,7 +74,7 @@ ModifiedGammaTransferFunction::make_lut (int bit_depth, bool inverse) const } } else { for (int i = 0; i < bit_length; ++i) { - double const p = static_cast (i) / (bit_length - 1); + double const p = static_cast(i) / (bit_length - 1); if (p > _threshold) { lut[i] = pow ((p + _A) / (1 + _A), _power); } else { @@ -77,18 +86,19 @@ ModifiedGammaTransferFunction::make_lut (int bit_depth, bool inverse) const return lut; } + bool ModifiedGammaTransferFunction::about_equal (shared_ptr other, double epsilon) const { - shared_ptr o = dynamic_pointer_cast (other); + auto o = dynamic_pointer_cast(other); if (!o) { return false; } return ( - fabs (_power - o->_power) < epsilon && - fabs (_threshold - o->_threshold) < epsilon && - fabs (_A - o->_A) < epsilon && - fabs (_B - o->_B) < epsilon + fabs(_power - o->_power) < epsilon && + fabs(_threshold - o->_threshold) < epsilon && + fabs(_A - o->_A) < epsilon && + fabs(_B - o->_B) < epsilon ); } diff --git a/src/modified_gamma_transfer_function.h b/src/modified_gamma_transfer_function.h index b38a16b0..70018cbf 100644 --- a/src/modified_gamma_transfer_function.h +++ b/src/modified_gamma_transfer_function.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,18 @@ files in the program, then also delete it here. */ + /** @file src/modified_gamma_transfer_function.h - * @brief ModifiedGammaTransferFunction class. + * @brief ModifiedGammaTransferFunction class */ + #include "transfer_function.h" + namespace dcp { + /** A transfer function which for an input x gives a linear output y where * * y = x / B for x <= threshold @@ -82,4 +86,5 @@ private: double _B; }; + } diff --git a/src/mono_picture_asset.cc b/src/mono_picture_asset.cc index 89661061..78ab8709 100644 --- a/src/mono_picture_asset.cc +++ b/src/mono_picture_asset.cc @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/mono_picture_asset.cc + * @brief MonoPictureAsset class + */ + + #include "mono_picture_asset.h" #include "mono_picture_asset_writer.h" #include "mono_picture_asset_reader.h" @@ -41,6 +47,7 @@ #include #include + using std::string; using std::vector; using std::list; @@ -53,6 +60,7 @@ using namespace boost::placeholders; #endif using namespace dcp; + MonoPictureAsset::MonoPictureAsset (boost::filesystem::path file) : PictureAsset (file) { @@ -77,18 +85,21 @@ MonoPictureAsset::MonoPictureAsset (boost::filesystem::path file) _id = read_writer_info (info); } + MonoPictureAsset::MonoPictureAsset (Fraction edit_rate, Standard standard) : PictureAsset (edit_rate, standard) { } + static void storing_note_handler (list >& notes, NoteType t, string s) { notes.push_back (make_pair (t, s)); } + bool MonoPictureAsset::equals (shared_ptr other, EqualityOptions opt, NoteHandler note) const { @@ -170,16 +181,20 @@ MonoPictureAsset::equals (shared_ptr other, EqualityOptions opt, No return result; } + shared_ptr MonoPictureAsset::start_write (boost::filesystem::path file, bool overwrite) { - return make_shared(this, file, overwrite); + /* Can't use make_shared here as the MonoPictureAssetWriter constructor is private */ + return shared_ptr(new MonoPictureAssetWriter(this, file, overwrite)); } shared_ptr MonoPictureAsset::start_read () const { - return make_shared(this, key(), standard()); + /* Can't use make_shared here as the MonoPictureAssetReader constructor is private */ + return shared_ptr(new MonoPictureAssetReader(this, key(), standard())); + } string diff --git a/src/mono_picture_asset.h b/src/mono_picture_asset.h index 28913f61..8c152146 100644 --- a/src/mono_picture_asset.h +++ b/src/mono_picture_asset.h @@ -31,18 +31,28 @@ files in the program, then also delete it here. */ + +/** @file src/mono_picture_asset.cc + * @brief MonoPictureAsset class + */ + + #ifndef LIBDCP_MONO_PICTURE_ASSET_H #define LIBDCP_MONO_PICTURE_ASSET_H + #include "picture_asset.h" #include "mono_picture_asset_reader.h" + namespace dcp { + class MonoPictureAssetWriter; + /** @class MonoPictureAsset - * @brief A 2D (monoscopic) picture asset. + * @brief A 2D (monoscopic) picture asset */ class MonoPictureAsset : public PictureAsset { diff --git a/src/mono_picture_asset_reader.h b/src/mono_picture_asset_reader.h index 4caf80f9..5bead791 100644 --- a/src/mono_picture_asset_reader.h +++ b/src/mono_picture_asset_reader.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,16 +31,27 @@ files in the program, then also delete it here. */ + +/** @file src/mono_picture_asset_reader.h + * @brief MonoPictureAssetReader typedef + */ + + #ifndef LIBDCP_MONO_PICTURE_ASSET_READER_H #define LIBDCP_MONO_PICTURE_ASSET_READER_H + #include "asset_reader.h" #include "mono_picture_frame.h" + namespace dcp { + typedef AssetReader MonoPictureAssetReader; + } + #endif diff --git a/src/mono_picture_asset_writer.cc b/src/mono_picture_asset_writer.cc index 01fb11f0..dec120cb 100644 --- a/src/mono_picture_asset_writer.cc +++ b/src/mono_picture_asset_writer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/mono_picture_asset_writer.cc * @brief MonoPictureAssetWriter class */ + #include "mono_picture_asset_writer.h" #include "exceptions.h" #include "picture_asset.h" @@ -43,17 +45,21 @@ #include #include + #include "picture_asset_writer_common.cc" + using std::string; using std::shared_ptr; using namespace dcp; + 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. */ @@ -64,6 +70,7 @@ MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, boost::file } + void MonoPictureAssetWriter::start (uint8_t const * data, int size) { @@ -71,6 +78,7 @@ MonoPictureAssetWriter::start (uint8_t const * data, int size) _picture_asset->set_frame_rate (_picture_asset->edit_rate()); } + FrameInfo MonoPictureAssetWriter::write (uint8_t const * data, int size) { @@ -80,15 +88,15 @@ MonoPictureAssetWriter::write (uint8_t const * data, int size) start (data, size); } - if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) { + 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; - ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _crypto_context->context(), _crypto_context->hmac(), &hash); - if (ASDCP_FAILURE (r)) { + auto const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _crypto_context->context(), _crypto_context->hmac(), &hash); + if (ASDCP_FAILURE(r)) { boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r)); } @@ -96,27 +104,29 @@ MonoPictureAssetWriter::write (uint8_t const * data, int size) return FrameInfo (before_offset, _state->mxf_writer.Tell() - before_offset, hash); } + void MonoPictureAssetWriter::fake_write (int size) { DCP_ASSERT (_started); DCP_ASSERT (!_finalized); - Kumu::Result_t r = _state->mxf_writer.FakeWriteFrame (size); - if (ASDCP_FAILURE (r)) { - boost::throw_exception (MXFFileError ("error in writing video MXF", _file.string(), r)); + auto r = _state->mxf_writer.FakeWriteFrame (size); + if (ASDCP_FAILURE(r)) { + boost::throw_exception (MXFFileError("error in writing video MXF", _file.string(), r)); } ++_frames_written; } + bool MonoPictureAssetWriter::finalize () { if (_started) { - Kumu::Result_t r = _state->mxf_writer.Finalize(); - if (ASDCP_FAILURE (r)) { - boost::throw_exception (MXFFileError ("error in finalizing video MXF", _file.string(), r)); + auto r = _state->mxf_writer.Finalize(); + if (ASDCP_FAILURE(r)) { + boost::throw_exception (MXFFileError("error in finalizing video MXF", _file.string(), r)); } } diff --git a/src/mono_picture_asset_writer.h b/src/mono_picture_asset_writer.h index a5799d27..9dffaa24 100644 --- a/src/mono_picture_asset_writer.h +++ b/src/mono_picture_asset_writer.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,21 +31,26 @@ files in the program, then also delete it here. */ + /** @file src/mono_picture_asset_writer.h * @brief MonoPictureAssetWriter class */ + #ifndef LIBDCP_MONO_PICTURE_ASSET_WRITER_H #define LIBDCP_MONO_PICTURE_ASSET_WRITER_H + #include "picture_asset_writer.h" #include #include #include #include + namespace dcp { + /** @class MonoPictureAssetWriter * @brief A helper class for writing to MonoPictureAssets * @@ -59,8 +64,6 @@ namespace dcp { class MonoPictureAssetWriter : public PictureAssetWriter { public: - MonoPictureAssetWriter (PictureAsset *, boost::filesystem::path file, bool); - FrameInfo write (uint8_t const *, int); void fake_write (int size); bool finalize (); @@ -68,6 +71,8 @@ public: private: friend class MonoPictureAsset; + MonoPictureAssetWriter (PictureAsset* a, boost::filesystem::path file, bool); + void start (uint8_t const *, int); /* do this with an opaque pointer so we don't have to include @@ -77,6 +82,8 @@ private: std::shared_ptr _state; }; + } + #endif diff --git a/src/mono_picture_frame.cc b/src/mono_picture_frame.cc index 7420193e..3e27bed7 100644 --- a/src/mono_picture_frame.cc +++ b/src/mono_picture_frame.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/mono_picture_frame.cc - * @brief MonoPictureFrame class. + * @brief MonoPictureFrame class */ + #include "mono_picture_frame.h" #include "exceptions.h" #include "util.h" @@ -46,33 +48,34 @@ #include #include + +using std::make_shared; using std::string; using std::shared_ptr; using boost::optional; using namespace dcp; -/** Make a picture frame from a JPEG2000 file. - * @param path Path to JPEG2000 file. - */ + MonoPictureFrame::MonoPictureFrame (boost::filesystem::path path) { - boost::uintmax_t const size = boost::filesystem::file_size (path); + auto const size = boost::filesystem::file_size (path); _buffer.reset(new ASDCP::JP2K::FrameBuffer(size)); - FILE* f = fopen_boost (path, "rb"); + auto f = fopen_boost (path, "rb"); if (!f) { - boost::throw_exception (FileError ("could not open JPEG2000 file", path, errno)); + boost::throw_exception (FileError("could not open JPEG2000 file", path, errno)); } size_t n = fread (data(), 1, size, f); + fclose (f); + if (n != size) { - boost::throw_exception (FileError ("could not read from JPEG2000 file", path, errno)); + boost::throw_exception (FileError("could not read from JPEG2000 file", path, errno)); } - fclose (f); - _buffer->Size (size); } + /** Make a picture frame from a 2D (monoscopic) asset. * @param reader Reader for the asset's MXF file. * @param n Frame within the asset, not taking EntryPoint into account. @@ -81,50 +84,47 @@ MonoPictureFrame::MonoPictureFrame (boost::filesystem::path path) MonoPictureFrame::MonoPictureFrame (ASDCP::JP2K::MXFReader* reader, int n, shared_ptr c) { /* XXX: unfortunate guesswork on this buffer size */ - _buffer.reset(new ASDCP::JP2K::FrameBuffer(4 * Kumu::Megabyte)); + _buffer = make_shared(4 * Kumu::Megabyte); - ASDCP::Result_t const r = reader->ReadFrame (n, *_buffer, c->context(), c->hmac()); + auto const r = reader->ReadFrame (n, *_buffer, c->context(), c->hmac()); - if (ASDCP_FAILURE (r)) { - boost::throw_exception (ReadError (String::compose ("could not read video frame %1 (%2)", n, static_cast(r)))); + if (ASDCP_FAILURE(r)) { + boost::throw_exception (ReadError(String::compose ("could not read video frame %1 (%2)", n, static_cast(r)))); } } + MonoPictureFrame::MonoPictureFrame (uint8_t const * data, int size) { - _buffer.reset(new ASDCP::JP2K::FrameBuffer(size)); + _buffer = make_shared(size); _buffer->Size (size); memcpy (_buffer->Data(), data, size); } -/** @return Pointer to JPEG2000 data */ uint8_t const * MonoPictureFrame::data () const { return _buffer->RoData (); } -/** @return Pointer to JPEG2000 data */ + uint8_t * MonoPictureFrame::data () { return _buffer->Data (); } -/** @return Size of JPEG2000 data in bytes */ + int MonoPictureFrame::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). - */ + shared_ptr MonoPictureFrame::xyz_image (int reduce) const { - return decompress_j2k (const_cast (_buffer->RoData()), _buffer->Size(), reduce); + return decompress_j2k (const_cast(_buffer->RoData()), _buffer->Size(), reduce); } diff --git a/src/mono_picture_frame.h b/src/mono_picture_frame.h index d6774aef..52cf7965 100644 --- a/src/mono_picture_frame.h +++ b/src/mono_picture_frame.h @@ -32,22 +32,22 @@ */ -#ifndef LIBDCP_MONO_PICTURE_FRAME_H -#define LIBDCP_MONO_PICTURE_FRAME_H - - /** @file src/mono_picture_frame.h * @brief MonoPictureFrame class */ -#include "types.h" +#ifndef LIBDCP_MONO_PICTURE_FRAME_H +#define LIBDCP_MONO_PICTURE_FRAME_H + + #include "asset_reader.h" -#include +#include "types.h" #include #include -#include +#include #include +#include namespace ASDCP { @@ -66,21 +66,33 @@ class OpenJPEGImage; /** @class MonoPictureFrame - * @brief A single frame of a 2D (monoscopic) picture asset. + * @brief A single frame of a 2D (monoscopic) picture asset */ class MonoPictureFrame : public Data { public: + /** Make a picture frame from a JPEG2000 file. + * @param path Path to JPEG2000 file. + */ explicit MonoPictureFrame (boost::filesystem::path path); MonoPictureFrame (uint8_t const * data, int size); MonoPictureFrame (MonoPictureFrame const&) = delete; MonoPictureFrame& operator= (MonoPictureFrame const&) = delete; + /** @param reduce a factor by which to reduce the resolution + * of the image, expressed as a power of two (pass 0 for no + * reduction). + */ std::shared_ptr xyz_image (int reduce = 0) const; + /** @return Pointer to JPEG2000 data */ uint8_t const * data () const; + + /** @return Pointer to JPEG2000 data */ uint8_t* data (); + + /** @return Size of JPEG2000 data in bytes */ int size () const; private: diff --git a/src/mxf.cc b/src/mxf.cc index 20cfbaed..1154b80d 100644 --- a/src/mxf.cc +++ b/src/mxf.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ -/** @file src/asset.cc - * @brief Parent class for assets of DCPs made up of MXF files. + +/** @file src/mxf.cc + * @brief MXF class */ + #include "raw_convert.h" #include "mxf.h" #include "util.h" @@ -49,6 +51,7 @@ #include #include + using std::string; using std::cout; using std::list; @@ -57,6 +60,7 @@ using std::shared_ptr; using std::dynamic_pointer_cast; using namespace dcp; + MXF::MXF () : _context_id (make_uuid ()) { @@ -65,6 +69,7 @@ MXF::MXF () */ } + MXF::MXF (Standard standard) : _context_id (make_uuid ()) , _standard (standard) @@ -72,6 +77,7 @@ MXF::MXF (Standard standard) } + void MXF::fill_writer_info (ASDCP::WriterInfo* writer_info, string id) const { @@ -101,11 +107,7 @@ MXF::fill_writer_info (ASDCP::WriterInfo* writer_info, string id) const } } -/** Set the (private) key that will be used to encrypt or decrypt this MXF's content. - * This is the top-secret key that is distributed (itself encrypted) to cinemas - * via Key Delivery Messages (KDMs). - * @param key Key to use. - */ + void MXF::set_key (Key key) { @@ -117,6 +119,7 @@ MXF::set_key (Key key) } } + string MXF::read_writer_info (ASDCP::WriterInfo const & info) { diff --git a/src/mxf.h b/src/mxf.h index 9b9f28af..82c86e8e 100644 --- a/src/mxf.h +++ b/src/mxf.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,33 +31,44 @@ files in the program, then also delete it here. */ + +/** @file src/mxf.h + * @brief MXF class + */ + + #ifndef LIBDCP_MXF_H #define LIBDCP_MXF_H + #include "asset.h" #include "key.h" #include "metadata.h" #include "dcp_assert.h" - #include + namespace ASDCP { class AESDecContext; struct WriterInfo; } + /* Undefine some stuff that the OS X 10.5 SDK defines */ #undef Key #undef set_key + namespace dcp { + class MXFMetadata; class PictureAssetWriter; + /** @class MXF - * @brief Parent for classes which represent MXF files. + * @brief Parent for classes which represent MXF files */ class MXF { @@ -82,6 +93,11 @@ public: return _key_id; } + /** Set the (private) key that will be used to encrypt or decrypt this MXF's content + * This is the top-secret key that is distributed (itself encrypted) to cinemas + * via Key Delivery Messages (KDMs) + * @param key Key to use + */ virtual void set_key (Key); /** @return encryption/decryption key, if one has been set */ @@ -139,6 +155,8 @@ protected: boost::optional _standard; }; + } + #endif diff --git a/src/name_format.cc b/src/name_format.cc index 11b68e19..e5c6556e 100644 --- a/src/name_format.cc +++ b/src/name_format.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,22 @@ files in the program, then also delete it here. */ + +/** @file src/name_format.cc + * @brief NameFormat class + */ + + #include "name_format.h" #include + using std::string; using std::map; using boost::optional; using namespace dcp; + static char filter (char c) { @@ -51,6 +59,7 @@ filter (char c) return c; } + static string filter (string c) { @@ -64,13 +73,6 @@ filter (string c) } -/** @param values Values to replace our specifications with; e.g. - * if the specification contains %c it will be be replaced with the - * value corresponding to the key 'c'. - * @param suffix Suffix to add on after processing the specification. - * @param ignore Any specification characters in this string will not - * be replaced, but left as-is. - */ string NameFormat::get (Map values, string suffix, string ignore) const { @@ -79,7 +81,7 @@ NameFormat::get (Map values, string suffix, string ignore) const bool done = false; if (_specification[i] == '%' && (i < _specification.length() - 1)) { char const key = _specification[i + 1]; - Map::const_iterator j = values.find(key); + auto j = values.find(key); if (j != values.end() && ignore.find(key) == string::npos) { result += filter (j->second); ++i; @@ -95,6 +97,7 @@ NameFormat::get (Map values, string suffix, string ignore) const return result + suffix; } + bool dcp::operator== (NameFormat const & a, NameFormat const & b) { diff --git a/src/name_format.h b/src/name_format.h index e6fc9d72..6401fe82 100644 --- a/src/name_format.h +++ b/src/name_format.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,16 +31,25 @@ files in the program, then also delete it here. */ + +/** @file src/name_format.h + * @brief NameFormat class + */ + + #ifndef LIBDCP_NAME_FORMAT #define LIBDCP_NAME_FORMAT + #include #include #include #include + namespace dcp { + class NameFormat { public: @@ -60,14 +69,24 @@ public: typedef std::map Map; + /** @param values Values to replace our specifications with; e.g. + * if the specification contains %c it will be be replaced with the + * value corresponding to the key 'c'. + * @param suffix Suffix to add on after processing the specification. + * @param ignore Any specification characters in this string will not + * be replaced, but left as-is. + */ std::string get (Map, std::string suffix, std::string ignore = "") const; private: std::string _specification; }; + extern bool operator== (NameFormat const & a, NameFormat const & b); + } + #endif diff --git a/src/openjpeg_image.cc b/src/openjpeg_image.cc index 31889566..3594b2bd 100644 --- a/src/openjpeg_image.cc +++ b/src/openjpeg_image.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,36 +31,42 @@ files in the program, then also delete it here. */ + /** @file src/openjpeg_image.cc * @brief OpenJPEGImage class. */ + #include "openjpeg_image.h" #include "dcp_assert.h" #include #include + using namespace dcp; + #ifdef LIBDCP_OPENJPEG1 #define OPJ_CLRSPC_SRGB CLRSPC_SRGB #endif -/** Construct an OpenJPEGImage, taking ownership of the opj_image_t */ + OpenJPEGImage::OpenJPEGImage (opj_image_t* image) : _opj_image (image) { DCP_ASSERT (_opj_image->numcomps == 3); } + #ifdef LIBDCP_OPENJPEG1 typedef int32_t OPJ_INT32; typedef uint8_t OPJ_BYTE; #endif + OpenJPEGImage::OpenJPEGImage (OpenJPEGImage const & other) { - _opj_image = reinterpret_cast (malloc (sizeof (opj_image_t))); + _opj_image = reinterpret_cast(malloc(sizeof(opj_image_t))); DCP_ASSERT (_opj_image); memcpy (_opj_image, other._opj_image, sizeof (opj_image_t)); @@ -80,17 +86,13 @@ OpenJPEGImage::OpenJPEGImage (OpenJPEGImage const & other) memcpy (_opj_image->icc_profile_buf, other._opj_image->icc_profile_buf, _opj_image->icc_profile_len); } -/** Construct a new OpenJPEGImage with undefined contents. - * @param size Size for the frame in pixels. - */ + OpenJPEGImage::OpenJPEGImage (Size size) { create (size); } -/** @param data_16 XYZ/RGB image data in packed 16:16:16, 48bpp with - * the 2-byte value for each component stored as little-endian. - */ + OpenJPEGImage::OpenJPEGImage (uint8_t const * data_16, dcp::Size size, int stride) { create (size); @@ -108,6 +110,7 @@ OpenJPEGImage::OpenJPEGImage (uint8_t const * data_16, dcp::Size size, int strid } } + void OpenJPEGImage::create (Size size) { @@ -137,15 +140,13 @@ OpenJPEGImage::create (Size size) _opj_image->y1 = size.height; } -/** OpenJPEGImage destructor */ + OpenJPEGImage::~OpenJPEGImage () { opj_image_destroy (_opj_image); } -/** @param c Component index (0, 1 or 2) - * @return Pointer to the data for component c. - */ + int * OpenJPEGImage::data (int c) const { @@ -153,7 +154,7 @@ OpenJPEGImage::data (int c) const return _opj_image->comps[c].data; } -/** @return Size of the image in pixels */ + dcp::Size OpenJPEGImage::size () const { @@ -161,18 +162,21 @@ OpenJPEGImage::size () const return dcp::Size (_opj_image->x1, _opj_image->y1); } + int OpenJPEGImage::precision (int component) const { return _opj_image->comps[component].prec; } + int OpenJPEGImage::factor (int component) const { return _opj_image->comps[component].factor; } + bool OpenJPEGImage::srgb () const { diff --git a/src/openjpeg_image.h b/src/openjpeg_image.h index 002e2a83..2138a21e 100644 --- a/src/openjpeg_image.h +++ b/src/openjpeg_image.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,31 +31,53 @@ files in the program, then also delete it here. */ + /** @file src/openjpeg_image.h - * @brief OpenJPEGImage class. + * @brief OpenJPEGImage class */ + #include "util.h" + struct opj_image; typedef struct opj_image opj_image_t; + namespace dcp { + /** @class OpenJPEGImage - * @brief A wrapper of libopenjpeg's opj_image_t. + * @brief A wrapper of libopenjpeg's opj_image_t */ class OpenJPEGImage { public: + /** Construct an OpenJPEGImage, taking ownership of the opj_image_t */ explicit OpenJPEGImage (opj_image_t *); + explicit OpenJPEGImage (OpenJPEGImage const & other); + + /** Construct a new OpenJPEGImage with undefined contents + * @param size Size for the frame in pixels + */ explicit OpenJPEGImage (Size); + + /** @param data_16 XYZ/RGB image data in packed 16:16:16, 48bpp with + * the 2-byte value for each component stored as little-endian + */ OpenJPEGImage (uint8_t const * in_16, dcp::Size size, int stride); + ~OpenJPEGImage (); + /** @param c Component index (0, 1 or 2) + * @return Pointer to the data for component c. + */ int* data (int) const; + + /** @return Size of the image in pixels */ Size size () const; + int precision (int component) const; bool srgb () const; int factor (int component) const; @@ -70,7 +92,8 @@ public: private: void create (Size size); - opj_image_t* _opj_image; ///< opj_image_t that we are managing + opj_image_t* _opj_image = nullptr; ///< opj_image_t that we are managing }; + } diff --git a/src/picture_asset.cc b/src/picture_asset.cc index 6b5e9393..86d85d46 100644 --- a/src/picture_asset.cc +++ b/src/picture_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/picture_asset.cc + * @brief PictureAsset class + */ + + #include "picture_asset.h" #include "util.h" #include "exceptions.h" @@ -46,6 +52,7 @@ #include #include + using std::string; using std::list; using std::vector; @@ -55,7 +62,7 @@ using std::make_pair; using std::shared_ptr; using namespace dcp; -/** Load a PictureAsset from a file */ + PictureAsset::PictureAsset (boost::filesystem::path file) : Asset (file) , _intrinsic_duration (0) @@ -63,7 +70,7 @@ PictureAsset::PictureAsset (boost::filesystem::path file) } -/** Create a new PictureAsset with a given edit rate and standard */ + PictureAsset::PictureAsset (Fraction edit_rate, Standard standard) : MXF (standard) , _edit_rate (edit_rate) @@ -72,6 +79,7 @@ PictureAsset::PictureAsset (Fraction edit_rate, Standard standard) } + void PictureAsset::read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const & desc) { @@ -83,6 +91,7 @@ PictureAsset::read_picture_descriptor (ASDCP::JP2K::PictureDescriptor const & de _screen_aspect_ratio = Fraction (desc.AspectRatio.Numerator, desc.AspectRatio.Denominator); } + bool PictureAsset::descriptor_equals ( ASDCP::JP2K::PictureDescriptor const & a, ASDCP::JP2K::PictureDescriptor const & b, NoteHandler note @@ -125,6 +134,7 @@ PictureAsset::descriptor_equals ( return true; } + bool PictureAsset::frame_buffer_equals ( int frame, EqualityOptions opt, NoteHandler note, @@ -138,8 +148,8 @@ PictureAsset::frame_buffer_equals ( } /* Decompress the images to bitmaps */ - shared_ptr image_A = decompress_j2k (const_cast (data_A), size_A, 0); - shared_ptr image_B = decompress_j2k (const_cast (data_B), size_B, 0); + auto image_A = decompress_j2k (const_cast(data_A), size_A, 0); + auto image_B = decompress_j2k (const_cast(data_B), size_B, 0); /* Compare them */ @@ -170,11 +180,11 @@ PictureAsset::frame_buffer_equals ( double const mean = double (total) / abs_diffs.size (); uint64_t total_squared_deviation = 0; - for (vector::iterator j = abs_diffs.begin(); j != abs_diffs.end(); ++j) { - total_squared_deviation += pow (*j - mean, 2); + for (auto j: abs_diffs) { + total_squared_deviation += pow (j - mean, 2); } - double const std_dev = sqrt (double (total_squared_deviation) / abs_diffs.size()); + auto const std_dev = sqrt (double (total_squared_deviation) / abs_diffs.size()); note (NoteType::NOTE, String::compose("mean difference %1 deviation %2", mean, std_dev)); @@ -199,6 +209,7 @@ PictureAsset::frame_buffer_equals ( return true; } + string PictureAsset::static_pkl_type (Standard standard) { @@ -212,6 +223,7 @@ PictureAsset::static_pkl_type (Standard standard) } } + string PictureAsset::pkl_type (Standard standard) const { diff --git a/src/picture_asset.h b/src/picture_asset.h index a49d1a7d..6ee3bd24 100644 --- a/src/picture_asset.h +++ b/src/picture_asset.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,37 +31,46 @@ files in the program, then also delete it here. */ -#ifndef LIBDCP_PICTURE_ASSET_H -#define LIBDCP_PICTURE_ASSET_H /** @file src/picture_asset.h - * @brief PictureAsset class. + * @brief PictureAsset class */ + +#ifndef LIBDCP_PICTURE_ASSET_H +#define LIBDCP_PICTURE_ASSET_H + + #include "mxf.h" #include "util.h" #include "metadata.h" + namespace ASDCP { namespace JP2K { struct PictureDescriptor; } } -namespace dcp -{ + +namespace dcp { + class MonoPictureFrame; class StereoPictureFrame; class PictureAssetWriter; + /** @class PictureAsset - * @brief An asset made up of JPEG2000 data. + * @brief An asset made up of JPEG2000 data */ class PictureAsset : public Asset, public MXF { public: + /** Load a PictureAsset from a file */ explicit PictureAsset (boost::filesystem::path file); + + /** Create a new PictureAsset with a given edit rate and standard */ explicit PictureAsset (Fraction edit_rate, Standard standard); virtual std::shared_ptr start_write ( @@ -124,7 +133,7 @@ protected: /** The total length of this content in video frames. The amount of * content presented may be less than this. */ - int64_t _intrinsic_duration; + int64_t _intrinsic_duration = 0; /** picture size in pixels */ Size _size; Fraction _frame_rate; @@ -137,4 +146,5 @@ private: } + #endif diff --git a/src/picture_asset_writer.cc b/src/picture_asset_writer.cc index a8dee68c..f9f6630c 100644 --- a/src/picture_asset_writer.cc +++ b/src/picture_asset_writer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/picture_asset_writer.cc + * @brief PictureAssetWriter and FrameInfo classes + */ + + #include "picture_asset_writer.h" #include "exceptions.h" #include "picture_asset.h" @@ -39,10 +45,12 @@ #include #include + using std::string; using std::shared_ptr; using namespace dcp; + PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, boost::filesystem::path file, bool overwrite) : AssetWriter (asset, file) , _picture_asset (asset) diff --git a/src/picture_asset_writer.h b/src/picture_asset_writer.h index 12530513..2fcd2de1 100644 --- a/src/picture_asset_writer.h +++ b/src/picture_asset_writer.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,16 @@ files in the program, then also delete it here. */ + /** @file src/picture_asset_writer.h * @brief PictureAssetWriter and FrameInfo classes. */ + #ifndef LIBDCP_PICTURE_ASSET_WRITER_H #define LIBDCP_PICTURE_ASSET_WRITER_H + #include "metadata.h" #include "types.h" #include "asset_writer.h" @@ -46,19 +49,19 @@ #include #include + namespace dcp { + class PictureAsset; + /** @class FrameInfo * @brief Information about a single frame (either a monoscopic frame or a left *or* right eye stereoscopic frame) */ struct FrameInfo { - FrameInfo () - : offset (0) - , size (0) - {} + FrameInfo () {} FrameInfo (uint64_t o, uint64_t s, std::string h) : offset (o) @@ -66,11 +69,12 @@ struct FrameInfo , hash (h) {} - uint64_t offset; - uint64_t size; + uint64_t offset = 0; + uint64_t size = 0; std::string hash; }; + /** @class PictureAssetWriter * @brief Parent class for classes which write picture assets. */ @@ -87,9 +91,11 @@ protected: PictureAssetWriter (PictureAsset *, boost::filesystem::path, bool); PictureAsset* _picture_asset; - bool _overwrite; + bool _overwrite = false; }; + } + #endif diff --git a/src/picture_asset_writer_common.cc b/src/picture_asset_writer_common.cc index 6591823f..e719be72 100644 --- a/src/picture_asset_writer_common.cc +++ b/src/picture_asset_writer_common.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,18 @@ files in the program, then also delete it here. */ + +/** @file src/picture_asset_writer_common.cc + * @brief Common parts of PictureAssetWriter + */ + + using std::shared_ptr; + namespace dcp { + struct ASDCPStateBase { ASDCPStateBase () @@ -47,14 +55,16 @@ struct ASDCPStateBase ASDCP::JP2K::PictureDescriptor picture_descriptor; }; + } + template void dcp::start (PictureAssetWriter* writer, shared_ptr

state, Q* asset, uint8_t const * data, int size) { asset->set_file (writer->_file); - if (ASDCP_FAILURE (state->j2k_parser.OpenReadFrame (data, size, state->frame_buffer))) { + if (ASDCP_FAILURE (state->j2k_parser.OpenReadFrame(data, size, state->frame_buffer))) { boost::throw_exception (MiscError ("could not parse J2K frame")); } @@ -66,7 +76,7 @@ void dcp::start (PictureAssetWriter* writer, shared_ptr

state, Q* asset, uint asset->fill_writer_info (&state->writer_info, asset->id()); - Kumu::Result_t r = state->mxf_writer.OpenWrite ( + auto r = state->mxf_writer.OpenWrite ( asset->file()->string().c_str(), state->writer_info, state->picture_descriptor, @@ -74,8 +84,8 @@ void dcp::start (PictureAssetWriter* writer, shared_ptr

state, Q* asset, uint writer->_overwrite ); - if (ASDCP_FAILURE (r)) { - boost::throw_exception (MXFFileError ("could not open MXF file for writing", asset->file()->string(), r)); + if (ASDCP_FAILURE(r)) { + boost::throw_exception (MXFFileError("could not open MXF file for writing", asset->file()->string(), r)); } writer->_started = true; diff --git a/src/pkl.cc b/src/pkl.cc index 4971178e..9cec68be 100644 --- a/src/pkl.cc +++ b/src/pkl.cc @@ -32,6 +32,11 @@ */ +/** @file src/pkl.cc + * @brief PKL class + */ + + #include "pkl.h" #include "exceptions.h" #include "util.h" diff --git a/src/pkl.h b/src/pkl.h index fb2f3161..01988e70 100644 --- a/src/pkl.h +++ b/src/pkl.h @@ -32,6 +32,11 @@ */ +/** @file src/pkl.cc + * @brief PKL class + */ + + #ifndef LIBDCP_PKL_H #define LIBDCP_PKL_H @@ -137,6 +142,8 @@ private: mutable boost::optional _file; }; + } + #endif diff --git a/src/raw_convert.cc b/src/raw_convert.cc index b4dcb5be..7d3d1a72 100644 --- a/src/raw_convert.cc +++ b/src/raw_convert.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2016 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,16 @@ files in the program, then also delete it here. */ + #include "raw_convert.h" #include "locale_convert.h" #include + using std::string; using std::wstring; + /** @param v Numeric value as an ASCII string */ static string @@ -50,6 +53,7 @@ make_raw (string v) return v; } + static string make_local (string v) @@ -60,6 +64,7 @@ make_local (string v) return v; } + template <> string dcp::raw_convert (unsigned char v, int precision, bool fixed) @@ -67,6 +72,7 @@ dcp::raw_convert (unsigned char v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (unsigned short int v, int precision, bool fixed) @@ -74,6 +80,7 @@ dcp::raw_convert (unsigned short int v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (int v, int precision, bool fixed) @@ -81,6 +88,7 @@ dcp::raw_convert (int v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (unsigned int v, int precision, bool fixed) @@ -88,6 +96,7 @@ dcp::raw_convert (unsigned int v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (long v, int precision, bool fixed) @@ -95,6 +104,7 @@ dcp::raw_convert (long v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (unsigned long v, int precision, bool fixed) @@ -102,6 +112,7 @@ dcp::raw_convert (unsigned long v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (long long v, int precision, bool fixed) @@ -109,6 +120,7 @@ dcp::raw_convert (long long v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (unsigned long long v, int precision, bool fixed) @@ -116,6 +128,7 @@ dcp::raw_convert (unsigned long long v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (float v, int precision, bool fixed) @@ -123,6 +136,7 @@ dcp::raw_convert (float v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (double v, int precision, bool fixed) @@ -130,6 +144,7 @@ dcp::raw_convert (double v, int precision, bool fixed) return make_raw (locale_convert (v, precision, fixed)); } + template <> string dcp::raw_convert (char const * v, int, bool) @@ -137,6 +152,7 @@ dcp::raw_convert (char const * v, int, bool) return v; } + template <> string dcp::raw_convert (char* v, int, bool) @@ -144,6 +160,7 @@ dcp::raw_convert (char* v, int, bool) return v; } + template <> string dcp::raw_convert (string v, int, bool) @@ -151,6 +168,7 @@ dcp::raw_convert (string v, int, bool) return v; } + template <> string dcp::raw_convert (char v, int, bool) @@ -160,6 +178,7 @@ dcp::raw_convert (char v, int, bool) return s; } + template <> string dcp::raw_convert (wchar_t const * v, int, bool) @@ -168,6 +187,7 @@ dcp::raw_convert (wchar_t const * v, int, bool) return string (w.begin(), w.end()); } + template <> unsigned char dcp::raw_convert (std::string v, int precision, bool fixed) @@ -175,6 +195,7 @@ dcp::raw_convert (std::string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> unsigned short int dcp::raw_convert (std::string v, int precision, bool fixed) @@ -182,6 +203,7 @@ dcp::raw_convert (std::string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> int dcp::raw_convert (string v, int precision, bool fixed) @@ -189,6 +211,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> long dcp::raw_convert (string v, int precision, bool fixed) @@ -196,6 +219,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> unsigned long dcp::raw_convert (string v, int precision, bool fixed) @@ -203,6 +227,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> long long dcp::raw_convert (string v, int precision, bool fixed) @@ -210,6 +235,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> unsigned long long dcp::raw_convert (string v, int precision, bool fixed) @@ -217,6 +243,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> int dcp::raw_convert (char const * v, int precision, bool fixed) @@ -224,6 +251,7 @@ dcp::raw_convert (char const * v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> float dcp::raw_convert (string v, int precision, bool fixed) @@ -231,6 +259,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> float dcp::raw_convert (char const * v, int precision, bool fixed) @@ -238,6 +267,7 @@ dcp::raw_convert (char const * v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> double dcp::raw_convert (string v, int precision, bool fixed) @@ -245,6 +275,7 @@ dcp::raw_convert (string v, int precision, bool fixed) return locale_convert (make_local (v), precision, fixed); } + template <> double dcp::raw_convert (char const * v, int precision, bool fixed) diff --git a/src/raw_convert.h b/src/raw_convert.h index 2a0d7add..dff860e9 100644 --- a/src/raw_convert.h +++ b/src/raw_convert.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,15 +31,24 @@ files in the program, then also delete it here. */ + +/** @file src/raw_convert.h + * @brief Methods for conversion to/from string + */ + + #ifndef LIBDCP_RAW_CONVERT_H #define LIBDCP_RAW_CONVERT_H + #include "util.h" #include #include + namespace dcp { + /** A sort-of version of boost::lexical_cast that does uses the "C" * locale (i.e. no thousands separators and a . for the decimal separator). */ @@ -163,6 +172,8 @@ template <> double raw_convert (char const * v, int, bool); + } + #endif diff --git a/src/reel.cc b/src/reel.cc index 16316487..74107ed0 100644 --- a/src/reel.cc +++ b/src/reel.cc @@ -32,6 +32,11 @@ */ +/** @file src/reel.cc + * @brief Reel class + */ + + #include "reel.h" #include "util.h" #include "picture_asset.h" diff --git a/src/reel.h b/src/reel.h index fdbe473a..c81724cb 100644 --- a/src/reel.h +++ b/src/reel.h @@ -32,6 +32,11 @@ */ +/** @file src/reel.cc + * @brief Reel class + */ + + #ifndef LIBDCP_REEL_H #define LIBDCP_REEL_H diff --git a/src/reel_asset.cc b/src/reel_asset.cc index 4d26e4f4..0f47e08d 100644 --- a/src/reel_asset.cc +++ b/src/reel_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2015 Carl Hetherington + Copyright (C) 2014-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/reel_asset.cc - * @brief ReelAsset class. + * @brief ReelAsset class */ + #include "raw_convert.h" #include "reel_asset.h" #include "asset.h" @@ -43,6 +45,7 @@ #include #include + using std::pair; using std::string; using std::make_pair; @@ -50,12 +53,7 @@ using std::shared_ptr; using boost::optional; using namespace dcp; -/** Construct a ReelAsset. - * @param id ID of this ReelAsset (which is that of the MXF, if there is one) - * @param edit_rate Edit rate for the asset. - * @param intrinsic_duration Intrinsic duration of this asset. - * @param entry_point Entry point to use in that asset. - */ + ReelAsset::ReelAsset (string id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) : Object (id) , _intrinsic_duration (intrinsic_duration) @@ -66,6 +64,7 @@ ReelAsset::ReelAsset (string id, Fraction edit_rate, int64_t intrinsic_duration, DCP_ASSERT (_entry_point <= _intrinsic_duration); } + ReelAsset::ReelAsset (shared_ptr node) : Object (remove_urn_uuid (node->string_child ("Id"))) , _intrinsic_duration (node->number_child ("IntrinsicDuration")) @@ -77,15 +76,16 @@ ReelAsset::ReelAsset (shared_ptr node) } + xmlpp::Node* ReelAsset::write_to_cpl_asset (xmlpp::Node* node, Standard standard, optional hash) const { - xmlpp::Element* a = node->add_child (cpl_node_name (standard)); - pair const attr = cpl_node_attribute (standard); + auto a = node->add_child (cpl_node_name (standard)); + auto const attr = cpl_node_attribute (standard); if (!attr.first.empty ()) { a->set_attribute (attr.first, attr.second); } - pair const ns = cpl_node_namespace (standard); + auto const ns = cpl_node_namespace (standard); if (!ns.first.empty ()) { a->set_namespace_declaration (ns.first, ns.second); } @@ -105,18 +105,21 @@ ReelAsset::write_to_cpl_asset (xmlpp::Node* node, Standard standard, optional ReelAsset::cpl_node_attribute (Standard) const { return make_pair ("", ""); } + pair ReelAsset::cpl_node_namespace (Standard) const { return make_pair ("", ""); } + bool ReelAsset::asset_equals (shared_ptr other, EqualityOptions opt, NoteHandler note) const { @@ -153,7 +156,7 @@ ReelAsset::asset_equals (shared_ptr other, EqualityOptions opt, return true; } -/** @return , or - if is not present */ + int64_t ReelAsset::actual_duration () const { diff --git a/src/reel_asset.h b/src/reel_asset.h index daf2220a..344e41c3 100644 --- a/src/reel_asset.h +++ b/src/reel_asset.h @@ -31,30 +31,38 @@ files in the program, then also delete it here. */ + /** @file src/reel_asset.h - * @brief ReelAsset class. + * @brief ReelAsset class */ + #ifndef LIBDCP_REEL_ASSET_H #define LIBDCP_REEL_ASSET_H + #include "object.h" #include "util.h" #include "ref.h" #include + namespace cxml { class Node; } + namespace xmlpp { class Node; } + namespace dcp { + class Asset; + /** @class ReelAsset * @brief An entry in a <Reel> which refers to a use of a piece of content. * @@ -65,7 +73,14 @@ class Asset; class ReelAsset : public Object { public: + /** Construct a ReelAsset + * @param id ID of this ReelAsset (which is that of the MXF, if there is one) + * @param edit_rate Edit rate for the asset + * @param intrinsic_duration Intrinsic duration of this asset + * @param entry_point Entry point to use in that asset + */ ReelAsset (std::string id, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point); + explicit ReelAsset (std::shared_ptr); virtual xmlpp::Node* write_to_cpl (xmlpp::Node* node, Standard standard) const = 0; @@ -98,6 +113,7 @@ public: return _duration; } + /** @return , or - if is not present */ int64_t actual_duration () const; std::string annotation_text () const { @@ -125,7 +141,7 @@ protected: xmlpp::Node* write_to_cpl_asset (xmlpp::Node* node, Standard standard, boost::optional hash) const; - int64_t _intrinsic_duration; ///< The <IntrinsicDuration> from the reel's entry for this asset + int64_t _intrinsic_duration = 0; ///< The <IntrinsicDuration> from the reel's entry for this asset boost::optional _duration; ///< The <Duration> from the reel's entry for this asset, if present private: diff --git a/src/reel_atmos_asset.cc b/src/reel_atmos_asset.cc index 9dccbbcb..d9e290a9 100644 --- a/src/reel_atmos_asset.cc +++ b/src/reel_atmos_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2017 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,21 +31,25 @@ files in the program, then also delete it here. */ + /** @file src/reel_atmos_asset.cc - * @brief ReelAtmosAsset class. + * @brief ReelAtmosAsset class */ + #include "atmos_asset.h" #include "reel_atmos_asset.h" #include #include + using std::string; using std::pair; using std::make_pair; using std::shared_ptr; using namespace dcp; + ReelAtmosAsset::ReelAtmosAsset (std::shared_ptr asset, int64_t entry_point) : ReelAsset (asset->id(), asset->edit_rate(), asset->intrinsic_duration(), entry_point) , ReelMXF (asset, asset->key_id()) @@ -53,6 +57,7 @@ ReelAtmosAsset::ReelAtmosAsset (std::shared_ptr asset, int64_t entry } + ReelAtmosAsset::ReelAtmosAsset (std::shared_ptr node) : ReelAsset (node) , ReelMXF (node) @@ -61,39 +66,45 @@ ReelAtmosAsset::ReelAtmosAsset (std::shared_ptr node) node->done (); } + string ReelAtmosAsset::cpl_node_name (Standard) const { return "axd:AuxData"; } + pair ReelAtmosAsset::cpl_node_namespace (Standard) const { - return make_pair ("http://www.dolby.com/schemas/2012/AD", "axd"); + return { "http://www.dolby.com/schemas/2012/AD", "axd" }; } + string ReelAtmosAsset::key_type () const { return "MDEK"; } + xmlpp::Node * ReelAtmosAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const { - xmlpp::Node* asset = write_to_cpl_asset (node, standard, hash()); + auto asset = write_to_cpl_asset (node, standard, hash()); write_to_cpl_mxf (asset); asset->add_child("axd:DataType")->add_child_text("urn:smpte:ul:060e2b34.04010105.0e090604.00000000"); return asset; } + bool ReelAtmosAsset::equals (shared_ptr other, EqualityOptions opt, NoteHandler note) const { if (!asset_equals (other, opt, note)) { return false; } + if (!mxf_equals (other, opt, note)) { return false; } diff --git a/src/reel_atmos_asset.h b/src/reel_atmos_asset.h index 92077fc0..51e93248 100644 --- a/src/reel_atmos_asset.h +++ b/src/reel_atmos_asset.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2017 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,23 +31,29 @@ files in the program, then also delete it here. */ + /** @file src/reel_atmos_asset.h - * @brief ReelAtmosAsset class. + * @brief ReelAtmosAsset class */ + #ifndef LIBDCP_REEL_ATMOS_ASSET_H #define LIBDCP_REEL_ATMOS_ASSET_H + #include "reel_asset.h" #include "atmos_asset.h" #include "reel_mxf.h" + namespace dcp { + class AtmosAsset; -/** @class ReelAtmosAsset - * @brief Part of a Reel's description which refers to a Atmos MXF. + +/** @class ReelAtmosAsse + * @brief Part of a Reel's description which refers to a Atmos MXF */ class ReelAtmosAsset : public ReelAsset, public ReelMXF { @@ -68,6 +74,8 @@ private: std::pair cpl_node_namespace (Standard) const; }; + } + #endif diff --git a/src/reel_closed_caption_asset.cc b/src/reel_closed_caption_asset.cc index 2aa13ead..3369fdd9 100644 --- a/src/reel_closed_caption_asset.cc +++ b/src/reel_closed_caption_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2017 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,16 +31,19 @@ files in the program, then also delete it here. */ + /** @file src/reel_closed_caption_asset.cc - * @brief ReelClosedCaptionAsset class. + * @brief ReelClosedCaptionAsset class */ + #include "subtitle_asset.h" #include "reel_closed_caption_asset.h" #include "smpte_subtitle_asset.h" #include "dcp_assert.h" #include + using std::string; using std::pair; using std::make_pair; @@ -49,6 +52,7 @@ using std::dynamic_pointer_cast; using boost::optional; using namespace dcp; + ReelClosedCaptionAsset::ReelClosedCaptionAsset (std::shared_ptr asset, Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) : ReelAsset (asset->id(), edit_rate, intrinsic_duration, entry_point) , ReelMXF (asset, dynamic_pointer_cast(asset) ? dynamic_pointer_cast(asset)->key_id() : optional()) @@ -56,6 +60,7 @@ ReelClosedCaptionAsset::ReelClosedCaptionAsset (std::shared_ptr a } + ReelClosedCaptionAsset::ReelClosedCaptionAsset (std::shared_ptr node) : ReelAsset (node) , ReelMXF (node) @@ -64,6 +69,7 @@ ReelClosedCaptionAsset::ReelClosedCaptionAsset (std::shared_ptrdone (); } + string ReelClosedCaptionAsset::cpl_node_name (Standard standard) const { @@ -77,6 +83,7 @@ ReelClosedCaptionAsset::cpl_node_name (Standard standard) const DCP_ASSERT (false); } + pair ReelClosedCaptionAsset::cpl_node_namespace (Standard standard) const { @@ -90,16 +97,18 @@ ReelClosedCaptionAsset::cpl_node_namespace (Standard standard) const DCP_ASSERT (false); } + string ReelClosedCaptionAsset::key_type () const { return "MDSK"; } + xmlpp::Node * ReelClosedCaptionAsset::write_to_cpl (xmlpp::Node* node, Standard standard) const { - xmlpp::Node* asset = write_to_cpl_asset (node, standard, hash()); + auto asset = write_to_cpl_asset (node, standard, hash()); write_to_cpl_mxf (asset); if (_language) { @@ -109,6 +118,7 @@ ReelClosedCaptionAsset::write_to_cpl (xmlpp::Node* node, Standard standard) cons return asset; } + bool ReelClosedCaptionAsset::equals (shared_ptr other, EqualityOptions opt, NoteHandler note) const { diff --git a/src/reel_closed_caption_asset.h b/src/reel_closed_caption_asset.h index 31122299..0aad8740 100644 --- a/src/reel_closed_caption_asset.h +++ b/src/reel_closed_caption_asset.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2017 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,13 +31,16 @@ files in the program, then also delete it here. */ + /** @file src/reel_closed_caption_asset.h - * @brief ReelClosedCaptionAsset class. + * @brief ReelClosedCaptionAsset class */ + #ifndef LIBDCP_REEL_CLOSED_CAPTION_ASSET_H #define LIBDCP_REEL_CLOSED_CAPTION_ASSET_H + #include "language_tag.h" #include "subtitle_asset.h" #include "reel_asset.h" @@ -49,10 +52,12 @@ struct verify_invalid_language2; namespace dcp { + class SubtitleAsset; + /** @class ReelClosedCaptionAsset - * @brief Part of a Reel's description which refers to a closed caption XML/MXF file. + * @brief Part of a Reel's description which refers to a closed caption XML/MXF file */ class ReelClosedCaptionAsset : public ReelAsset, public ReelMXF { @@ -89,6 +94,8 @@ private: boost::optional _language; }; + } + #endif diff --git a/src/reel_markers_asset.cc b/src/reel_markers_asset.cc index 1f9282fa..52151868 100644 --- a/src/reel_markers_asset.cc +++ b/src/reel_markers_asset.cc @@ -31,11 +31,13 @@ files in the program, then also delete it here. */ + #include "reel_markers_asset.h" #include "raw_convert.h" #include "dcp_assert.h" #include + using std::string; using std::map; using std::max; @@ -43,12 +45,14 @@ using boost::optional; using std::shared_ptr; using namespace dcp; + ReelMarkersAsset::ReelMarkersAsset (Fraction edit_rate, int64_t intrinsic_duration, int64_t entry_point) : ReelAsset (make_uuid(), edit_rate, intrinsic_duration, entry_point) { } + ReelMarkersAsset::ReelMarkersAsset (cxml::ConstNodePtr node) : ReelAsset (node) { @@ -59,24 +63,28 @@ ReelMarkersAsset::ReelMarkersAsset (cxml::ConstNodePtr node) } } + string ReelMarkersAsset::cpl_node_name (Standard) const { return "MainMarkers"; } + void ReelMarkersAsset::set (Marker m, Time t) { _markers[m] = t; } + void ReelMarkersAsset::unset (Marker m) { _markers.erase (m); } + optional

- *  Byte   /- 0 -------|- 1 --------|- 2 --------|- 3 --------|- 4 --------|- 5 --------| ...
- *         |(0, 0) Blue|(0, 0)Green |(0, 0) Red  |(0, 0) Alpha|(0, 1) Blue |(0, 1) Green| ...
- *  
- * - * So that the first byte is the blue component of the pixel at x=0, y=0, the second - * is the green component, and so on. - * - * Lines are packed so that the second row directly follows the first. - */ + +static auto constexpr DCI_COEFFICIENT = 48.0 / 52.37; + + void dcp::xyz_to_rgba ( std::shared_ptr xyz_image, @@ -139,15 +129,7 @@ dcp::xyz_to_rgba ( } } -/** Convert an XYZ image to 48bpp RGB. - * @param xyz_image Frame in XYZ. - * @param conversion Colour conversion to use. - * @param rgb Buffer to fill with RGB data. Format is packed RGB - * 16:16:16, 48bpp, 16R, 16G, 16B, with the 2-byte value for each - * R/G/B component stored as little-endian; i.e. AV_PIX_FMT_RGB48LE. - * @param stride Stride for RGB data in bytes. - * @param note Optional handler for any notes that may be made during the conversion (e.g. when clamping occurs). - */ + void dcp::xyz_to_rgb ( shared_ptr xyz_image, @@ -243,9 +225,6 @@ dcp::xyz_to_rgb ( } } -/** @param conversion Colour conversion. - * @param matrix Filled in with the product of the RGB to XYZ matrix, the Bradford transform and the DCI companding. - */ void dcp::combined_rgb_to_xyz (ColourConversion const & conversion, double* matrix) { @@ -272,12 +251,7 @@ dcp::combined_rgb_to_xyz (ColourConversion const & conversion, double* matrix) * DCI_COEFFICIENT * 65535; } -/** @param rgb RGB data; packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, - * with the 2-byte value for each R/G/B component stored as - * little-endian; i.e. AV_PIX_FMT_RGB48LE. - * @param size size of RGB image in pixels. - * @param size stride of RGB data in pixels. - */ + shared_ptr dcp::rgb_to_xyz ( uint8_t const * rgb, @@ -287,7 +261,7 @@ dcp::rgb_to_xyz ( optional note ) { - shared_ptr xyz (new OpenJPEGImage (size)); + auto xyz = make_shared(size); struct { double r, g, b; @@ -297,8 +271,8 @@ dcp::rgb_to_xyz ( double x, y, z; } d; - double const * lut_in = conversion.in()->lut (12, false); - double const * lut_out = conversion.out()->lut (16, true); + auto const * lut_in = conversion.in()->lut (12, false); + auto const * lut_out = conversion.out()->lut (16, true); /* This is is the product of the RGB to XYZ matrix, the Bradford transform and the DCI companding */ double fast_matrix[9]; @@ -309,7 +283,7 @@ dcp::rgb_to_xyz ( int* xyz_y = xyz->data (1); int* xyz_z = xyz->data (2); for (int y = 0; y < size.height; ++y) { - uint16_t const * p = reinterpret_cast (rgb + y * stride); + auto p = reinterpret_cast (rgb + y * stride); for (int x = 0; x < size.width; ++x) { /* In gamma LUT (converting 16-bit to 12-bit) */ diff --git a/src/rgb_xyz.h b/src/rgb_xyz.h index 60df612c..eb1b5ac8 100644 --- a/src/rgb_xyz.h +++ b/src/rgb_xyz.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,17 +31,36 @@ files in the program, then also delete it here. */ + #include "types.h" #include #include #include + namespace dcp { + class OpenJPEGImage; class Image; class ColourConversion; + +/** Convert an XYZ image to RGBA. + * @param xyz_image Image in XYZ. + * @param conversion Colour conversion to use. + * @param argb Buffer to fill with RGBA data. The format of the data is: + * + *
+ *  Byte   /- 0 -------|- 1 --------|- 2 --------|- 3 --------|- 4 --------|- 5 --------| ...
+ *         |(0, 0) Blue|(0, 0)Green |(0, 0) Red  |(0, 0) Alpha|(0, 1) Blue |(0, 1) Green| ...
+ *  
+ * + * So that the first byte is the blue component of the pixel at x=0, y=0, the second + * is the green component, and so on. + * + * Lines are packed so that the second row directly follows the first. + */ extern void xyz_to_rgba ( std::shared_ptr, ColourConversion const & conversion, @@ -49,6 +68,16 @@ extern void xyz_to_rgba ( int stride ); + +/** Convert an XYZ image to 48bpp RGB. + * @param xyz_image Frame in XYZ. + * @param conversion Colour conversion to use. + * @param rgb Buffer to fill with RGB data. Format is packed RGB + * 16:16:16, 48bpp, 16R, 16G, 16B, with the 2-byte value for each + * R/G/B component stored as little-endian; i.e. AV_PIX_FMT_RGB48LE. + * @param stride Stride for RGB data in bytes. + * @param note Optional handler for any notes that may be made during the conversion (e.g. when clamping occurs). + */ extern void xyz_to_rgb ( std::shared_ptr, ColourConversion const & conversion, @@ -57,6 +86,13 @@ extern void xyz_to_rgb ( boost::optional note = boost::optional () ); + +/** @param rgb RGB data; packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, + * with the 2-byte value for each R/G/B component stored as + * little-endian; i.e. AV_PIX_FMT_RGB48LE. + * @param size size of RGB image in pixels. + * @param size stride of RGB data in pixels. + */ extern std::shared_ptr rgb_to_xyz ( uint8_t const * rgb, dcp::Size size, @@ -65,6 +101,10 @@ extern std::shared_ptr rgb_to_xyz ( boost::optional note = boost::optional () ); + +/** @param conversion Colour conversion. + * @param matrix Filled in with the product of the RGB to XYZ matrix, the Bradford transform and the DCI companding. + */ extern void combined_rgb_to_xyz (ColourConversion const & conversion, double* matrix); } diff --git a/src/s_gamut3_transfer_function.cc b/src/s_gamut3_transfer_function.cc index 599028b4..edfbe2ad 100644 --- a/src/s_gamut3_transfer_function.cc +++ b/src/s_gamut3_transfer_function.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,18 +31,22 @@ files in the program, then also delete it here. */ + /** @file src/s_gamut3_transfer_function.cc - * @brief SGamut3TransferFunction class. + * @brief SGamut3TransferFunction class */ + #include "s_gamut3_transfer_function.h" #include + using std::pow; using std::shared_ptr; using std::dynamic_pointer_cast; using namespace dcp; + double * SGamut3TransferFunction::make_lut (int bit_depth, bool inverse) const { @@ -50,7 +54,7 @@ SGamut3TransferFunction::make_lut (int bit_depth, bool inverse) const double* lut = new double[bit_length]; if (inverse) { for (int i = 0; i < bit_length; ++i) { - double const p = static_cast (i) / (bit_length - 1); + auto const p = static_cast(i) / (bit_length - 1); if (p >= (0.01125 / 1023)) { lut[i] = (420 + log10((p + 0.01) / (0.18 + 0.01)) * 261.5) / 1023; } else { @@ -59,7 +63,7 @@ SGamut3TransferFunction::make_lut (int bit_depth, bool inverse) const } } else { for (int i = 0; i < bit_length; ++i) { - double const p = static_cast (i) / (bit_length - 1); + auto const p = static_cast(i) / (bit_length - 1); if (p >= (171.2102946929 / 1023)) { lut[i] = pow(10, ((p * 1023 - 420) / 261.5)) * (0.18 + 0.01) - 0.01; } else { @@ -70,9 +74,10 @@ SGamut3TransferFunction::make_lut (int bit_depth, bool inverse) const return lut; } + bool SGamut3TransferFunction::about_equal (shared_ptr other, double) const { - shared_ptr o = dynamic_pointer_cast (other); + auto o = dynamic_pointer_cast (other); return static_cast (o); } diff --git a/src/s_gamut3_transfer_function.h b/src/s_gamut3_transfer_function.h index 3f83da87..88a6a65a 100644 --- a/src/s_gamut3_transfer_function.h +++ b/src/s_gamut3_transfer_function.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,18 @@ files in the program, then also delete it here. */ + /** @file src/s_gamut3_transfer_function.h * @brief SGamut3TransferFunction class. */ + #include "transfer_function.h" + namespace dcp { + class SGamut3TransferFunction : public TransferFunction { public: @@ -48,4 +52,5 @@ protected: double * make_lut (int bit_depth, bool inverse) const; }; + } diff --git a/src/smpte_load_font_node.cc b/src/smpte_load_font_node.cc index 4d206784..d629b3b7 100644 --- a/src/smpte_load_font_node.cc +++ b/src/smpte_load_font_node.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,14 +31,22 @@ files in the program, then also delete it here. */ + +/** @file src/smpte_load_font_node.cc + * @brief SMPTELoadFontNode class + */ + + #include "smpte_load_font_node.h" #include "util.h" #include + using std::string; using std::shared_ptr; using namespace dcp; + SMPTELoadFontNode::SMPTELoadFontNode (string id, string urn_) : LoadFontNode (id) , urn (urn_) @@ -46,6 +54,7 @@ SMPTELoadFontNode::SMPTELoadFontNode (string id, string urn_) } + SMPTELoadFontNode::SMPTELoadFontNode (shared_ptr node) : LoadFontNode (node->string_attribute ("ID")) , urn (remove_urn_uuid (node->content())) @@ -53,12 +62,14 @@ SMPTELoadFontNode::SMPTELoadFontNode (shared_ptr node) } + bool dcp::operator== (SMPTELoadFontNode const & a, SMPTELoadFontNode const & b) { return a.id == b.id && a.urn == b.urn; } + bool dcp::operator!= (SMPTELoadFontNode const & a, SMPTELoadFontNode const & b) { diff --git a/src/smpte_load_font_node.h b/src/smpte_load_font_node.h index c310246d..7109e98b 100644 --- a/src/smpte_load_font_node.h +++ b/src/smpte_load_font_node.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,22 +31,27 @@ files in the program, then also delete it here. */ + /** @file src/smpte_load_font_node.h * @brief SMPTELoadFontNode class. */ + #include "load_font_node.h" #include #include + namespace cxml { class Node; } + namespace dcp { + /** @class SMPTELoadFontNode - * @brief Parser for LoadFont nodes from SMPTE subtitle XML. + * @brief Parser for LoadFont nodes from SMPTE subtitle XML */ class SMPTELoadFontNode : public LoadFontNode { @@ -58,7 +63,9 @@ public: std::string urn; }; + bool operator== (SMPTELoadFontNode const & a, SMPTELoadFontNode const & b); bool operator!= (SMPTELoadFontNode const & a, SMPTELoadFontNode const & b); + } diff --git a/src/smpte_subtitle_asset.cc b/src/smpte_subtitle_asset.cc index 2c53cbb3..15a366ba 100644 --- a/src/smpte_subtitle_asset.cc +++ b/src/smpte_subtitle_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2019 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/smpte_subtitle_asset.cc - * @brief SMPTESubtitleAsset class. + * @brief SMPTESubtitleAsset class */ + #include "smpte_subtitle_asset.h" #include "smpte_load_font_node.h" #include "exceptions.h" @@ -51,6 +53,7 @@ #include #include + using std::string; using std::list; using std::vector; @@ -65,33 +68,32 @@ using boost::optional; using boost::starts_with; using namespace dcp; + static string const subtitle_smpte_ns = "http://www.smpte-ra.org/schemas/428-7/2010/DCST"; + SMPTESubtitleAsset::SMPTESubtitleAsset () : MXF (Standard::SMPTE) - , _intrinsic_duration (0) , _edit_rate (24, 1) , _time_code_rate (24) - , _xml_id (make_uuid ()) + , _xml_id (make_uuid()) { } -/** Construct a SMPTESubtitleAsset by reading an MXF or XML file. - * @param file Filename. - */ + SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file) : SubtitleAsset (file) { - shared_ptr xml (new cxml::Document ("SubtitleReel")); + auto xml = make_shared("SubtitleReel"); - shared_ptr reader (new ASDCP::TimedText::MXFReader ()); - Kumu::Result_t r = Kumu::RESULT_OK; + auto reader = make_shared(); + auto r = Kumu::RESULT_OK; { ASDCPErrorSuspender sus; r = reader->OpenRead (_file->string().c_str ()); } - if (!ASDCP_FAILURE (r)) { + if (!ASDCP_FAILURE(r)) { /* MXF-wrapped */ ASDCP::WriterInfo info; reader->FillWriterInfo (info); @@ -101,13 +103,13 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file) reader->ReadTimedTextResource (_raw_xml); xml->read_string (_raw_xml); parse_xml (xml); - read_mxf_descriptor (reader, shared_ptr (new DecryptionContext (optional(), Standard::SMPTE))); + read_mxf_descriptor (reader, make_shared(optional(), Standard::SMPTE)); } } else { /* Plain XML */ try { _raw_xml = dcp::file_to_string (file); - xml.reset (new cxml::Document ("SubtitleReel")); + xml = make_shared("SubtitleReel"); xml->read_file (file); parse_xml (xml); _id = _xml_id = remove_urn_uuid (xml->string_child ("Id")); @@ -116,7 +118,7 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file) ReadError ( String::compose ( "Failed to read subtitle file %1; MXF failed with %2, XML failed with %3", - file, static_cast (r), e.what () + file, static_cast(r), e.what() ) ) ); @@ -152,6 +154,7 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file) } } + void SMPTESubtitleAsset::parse_xml (shared_ptr xml) { @@ -178,7 +181,7 @@ SMPTESubtitleAsset::parse_xml (shared_ptr xml) _time_code_rate = xml->number_child ("TimeCodeRate"); if (xml->optional_string_child ("StartTime")) { - _start_time = Time (xml->string_child ("StartTime"), _time_code_rate); + _start_time = Time (xml->string_child("StartTime"), _time_code_rate); } /* Now we need to drop down to xmlpp */ @@ -195,6 +198,7 @@ SMPTESubtitleAsset::parse_xml (shared_ptr xml) _intrinsic_duration = latest_subtitle_out().as_editable_units (_edit_rate.numerator / _edit_rate.denominator); } + void SMPTESubtitleAsset::read_mxf_descriptor (shared_ptr reader, shared_ptr dec) { @@ -213,7 +217,7 @@ SMPTESubtitleAsset::read_mxf_descriptor (shared_ptr reader->ReadAncillaryResource (i->ResourceID, buffer, dec->context(), dec->hmac()); char id[64]; - Kumu::bin2UUIDhex (i->ResourceID, ASDCP::UUIDlen, id, sizeof (id)); + Kumu::bin2UUIDhex (i->ResourceID, ASDCP::UUIDlen, id, sizeof(id)); shared_array data (new uint8_t[buffer.Size()]); memcpy (data.get(), buffer.RoData(), buffer.Size()); @@ -248,17 +252,17 @@ SMPTESubtitleAsset::read_mxf_descriptor (shared_ptr } } - /* Get intrinsic duration */ _intrinsic_duration = descriptor.ContainerDuration; } + void SMPTESubtitleAsset::set_key (Key key) { /* See if we already have a key; if we do, and we have a file, we'll already have read that file. */ - bool const had_key = static_cast (_key); + auto const had_key = static_cast(_key); MXF::set_key (key); @@ -284,35 +288,38 @@ SMPTESubtitleAsset::set_key (Key key) auto dec = make_shared(key, Standard::SMPTE); reader->ReadTimedTextResource (_raw_xml, dec->context(), dec->hmac()); - shared_ptr xml (new cxml::Document ("SubtitleReel")); + auto xml = make_shared("SubtitleReel"); xml->read_string (_raw_xml); parse_xml (xml); read_mxf_descriptor (reader, dec); } + vector> SMPTESubtitleAsset::load_font_nodes () const { vector> lf; - copy (_load_font_nodes.begin(), _load_font_nodes.end(), back_inserter (lf)); + copy (_load_font_nodes.begin(), _load_font_nodes.end(), back_inserter(lf)); return lf; } + bool SMPTESubtitleAsset::valid_mxf (boost::filesystem::path file) { ASDCP::TimedText::MXFReader reader; Kumu::DefaultLogSink().UnsetFilterFlag(Kumu::LOG_ALLOW_ALL); - Kumu::Result_t r = reader.OpenRead (file.string().c_str ()); + auto r = reader.OpenRead (file.string().c_str ()); Kumu::DefaultLogSink().SetFilterFlag(Kumu::LOG_ALLOW_ALL); return !ASDCP_FAILURE (r); } + string SMPTESubtitleAsset::xml_as_string () const { xmlpp::Document doc; - xmlpp::Element* root = doc.create_root_node ("dcst:SubtitleReel"); + auto root = doc.create_root_node ("dcst:SubtitleReel"); root->set_namespace_declaration (subtitle_smpte_ns, "dcst"); root->set_namespace_declaration ("http://www.w3.org/2001/XMLSchema", "xs"); @@ -345,7 +352,7 @@ SMPTESubtitleAsset::xml_as_string () const return doc.write_to_string ("UTF-8"); } -/** Write this content to a MXF file */ + void SMPTESubtitleAsset::write (boost::filesystem::path p) const { @@ -422,7 +429,7 @@ SMPTESubtitleAsset::write (boost::filesystem::path p) const buffer.SetData (data_copy.data(), data_copy.size()); buffer.Size (j->data.size()); r = writer.WriteAncillaryResource (buffer, enc.context(), enc.hmac()); - if (ASDCP_FAILURE (r)) { + if (ASDCP_FAILURE(r)) { boost::throw_exception (MXFFileError ("could not write font to timed text resource", p.string(), r)); } } @@ -455,7 +462,7 @@ SMPTESubtitleAsset::equals (shared_ptr other_asset, EqualityOptions return false; } - shared_ptr other = dynamic_pointer_cast (other_asset); + auto other = dynamic_pointer_cast(other_asset); if (!other) { note (NoteType::ERROR, "Subtitles are in different standards"); return false; @@ -526,14 +533,16 @@ SMPTESubtitleAsset::equals (shared_ptr other_asset, EqualityOptions return true; } + void SMPTESubtitleAsset::add_font (string load_id, dcp::ArrayData data) { string const uuid = make_uuid (); _fonts.push_back (Font(load_id, uuid, data)); - _load_font_nodes.push_back (shared_ptr (new SMPTELoadFontNode (load_id, uuid))); + _load_font_nodes.push_back (make_shared(load_id, uuid)); } + void SMPTESubtitleAsset::add (shared_ptr s) { diff --git a/src/smpte_subtitle_asset.h b/src/smpte_subtitle_asset.h index 12eb58db..1521bf35 100644 --- a/src/smpte_subtitle_asset.h +++ b/src/smpte_subtitle_asset.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2020 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington This file is part of libdcp. @@ -31,10 +31,12 @@ files in the program, then also delete it here. */ + /** @file src/smpte_subtitle_asset.h - * @brief SMPTESubtitleAsset class. + * @brief SMPTESubtitleAsset class */ + #include "subtitle_asset.h" #include "language_tag.h" #include "local_time.h" @@ -42,28 +44,34 @@ #include "crypto_context.h" #include + namespace ASDCP { namespace TimedText { class MXFReader; } } + struct verify_invalid_language1; struct verify_invalid_language2; + namespace dcp { + class SMPTELoadFontNode; + /** @class SMPTESubtitleAsset - * @brief A set of subtitles to be read and/or written in the SMPTE format. + * @brief A set of subtitles to be read and/or written in the SMPTE format */ class SMPTESubtitleAsset : public SubtitleAsset, public MXF { public: SMPTESubtitleAsset (); - /** @param file File name + /** Construct a SMPTESubtitleAsset by reading an MXF or XML file + * @param file Filename */ explicit SMPTESubtitleAsset (boost::filesystem::path file); @@ -76,7 +84,10 @@ public: std::vector> load_font_nodes () const; std::string xml_as_string () const; + + /** Write this content to a MXF file */ void write (boost::filesystem::path path) const; + void add (std::shared_ptr); void add_font (std::string id, dcp::ArrayData data); void set_key (Key key); @@ -114,7 +125,7 @@ public: } /** @return title of the film that these subtitles are for, - * to be presented to the user. + * to be presented to the user */ std::string content_title_text () const { return _content_title_text; @@ -132,7 +143,7 @@ public: return _annotation_text; } - /** @return file creation time and date */ + /** @return file issue time and date */ LocalTime issue_date () const { return _issue_date; } @@ -185,7 +196,7 @@ private: /** The total length of this content in video frames. The amount of * content presented may be less than this. */ - int64_t _intrinsic_duration; + int64_t _intrinsic_duration = 0; /** from the asset */ std::string _content_title_text; /** This is stored and returned as a string so that we can tolerate non-RFC-5646 strings, @@ -196,7 +207,7 @@ private: LocalTime _issue_date; boost::optional _reel_number; Fraction _edit_rate; - int _time_code_rate; + int _time_code_rate = 0; boost::optional