From 369ba52fe8b3ddeda734692541471c402016a18d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 19:44:58 +0000 Subject: Use new Size struct. --- src/util.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/util.cc') diff --git a/src/util.cc b/src/util.cc index 6769cc41..4ddb466c 100644 --- a/src/util.cc +++ b/src/util.cc @@ -216,7 +216,7 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame) int* xyz_y = xyz_frame->comps[1].data; int* xyz_z = xyz_frame->comps[2].data; - shared_ptr argb_frame (new ARGBFrame (xyz_frame->x1, xyz_frame->y1)); + shared_ptr argb_frame (new ARGBFrame (Size (xyz_frame->x1, xyz_frame->y1))); uint8_t* argb = argb_frame->data (); -- cgit v1.2.3 From c289685296d58228df0a88354e966105b242c915 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 17 Jan 2013 21:30:34 +0000 Subject: Add Size operators; install util.h --- src/util.cc | 11 +++++++++++ src/util.h | 3 +++ src/wscript | 1 + 3 files changed, 15 insertions(+) (limited to 'src/util.cc') diff --git a/src/util.cc b/src/util.cc index 4ddb466c..1cbec719 100644 --- a/src/util.cc +++ b/src/util.cc @@ -277,3 +277,14 @@ libdcp::empty_or_white_space (string s) return true; } + +bool libdcp::operator== (libdcp::Size const & a, libdcp::Size const & b) +{ + return (a.width == b.width && a.height == b.height); +} + +bool libdcp::operator!= (libdcp::Size const & a, libdcp::Size const & b) +{ + return !(a == b); +} + diff --git a/src/util.h b/src/util.h index dd153cb3..f5685970 100644 --- a/src/util.h +++ b/src/util.h @@ -49,6 +49,9 @@ struct Size { int height; }; +extern bool operator== (Size const & a, Size const & b); +extern bool operator!= (Size const & a, Size const & b); + extern std::string make_uuid (); extern std::string make_digest (std::string filename); extern std::string content_kind_to_string (ContentKind kind); diff --git a/src/wscript b/src/wscript index 04656976..d243ae46 100644 --- a/src/wscript +++ b/src/wscript @@ -49,6 +49,7 @@ def build(bld): subtitle_asset.h test_mode.h types.h + util.h version.h xml.h """ -- cgit v1.2.3 From 4a557a8b6631f132e851b1bb362cde4270ca6057 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 10 Feb 2013 21:32:30 +0000 Subject: Derive exceptions from boost::exception and use boost::throw_exception to enable thread-safe exception handling by callers. --- src/dcp.cc | 16 ++++++++-------- src/dcp_time.cc | 2 +- src/picture_asset.cc | 38 +++++++++++++++++++------------------- src/picture_frame.cc | 8 ++++---- src/sound_asset.cc | 34 +++++++++++++++++----------------- src/sound_frame.cc | 4 ++-- src/subtitle_asset.cc | 2 +- src/types.cc | 12 ++++++------ src/util.cc | 6 +++--- src/xml.cc | 20 ++++++++++---------- 10 files changed, 71 insertions(+), 71 deletions(-) (limited to 'src/util.cc') diff --git a/src/dcp.cc b/src/dcp.cc index 4f1732da..d446b205 100644 --- a/src/dcp.cc +++ b/src/dcp.cc @@ -182,17 +182,17 @@ DCP::read (bool require_mxfs) if (boost::filesystem::exists (p)) { asset_map.reset (new AssetMap (p.string ())); } else { - throw DCPReadError ("could not find AssetMap file"); + boost::throw_exception (DCPReadError ("could not find AssetMap file")); } } } catch (FileError& e) { - throw FileError ("could not load AssetMap file", files.asset_map); + boost::throw_exception (FileError ("could not load AssetMap file", files.asset_map)); } for (list >::const_iterator i = asset_map->assets.begin(); i != asset_map->assets.end(); ++i) { if ((*i)->chunks.size() != 1) { - throw XMLError ("unsupported asset chunk count"); + boost::throw_exception (XMLError ("unsupported asset chunk count")); } boost::filesystem::path t = _directory; @@ -219,24 +219,24 @@ DCP::read (bool require_mxfs) if (files.pkl.empty ()) { files.pkl = t.string(); } else { - throw DCPReadError ("duplicate PKLs found"); + boost::throw_exception (DCPReadError ("duplicate PKLs found")); } } } if (files.cpls.empty ()) { - throw FileError ("no CPL files found", ""); + boost::throw_exception (FileError ("no CPL files found", "")); } if (files.pkl.empty ()) { - throw FileError ("no PKL file found", ""); + boost::throw_exception (FileError ("no PKL file found", "")); } shared_ptr pkl; try { pkl.reset (new PKLFile (files.pkl)); } catch (FileError& e) { - throw FileError ("could not load PKL file", files.pkl); + boost::throw_exception (FileError ("could not load PKL file", files.pkl)); } /* Cross-check */ @@ -325,7 +325,7 @@ CPL::CPL (string directory, string file, shared_ptr asset_map, b try { cpl.reset (new CPLFile (file)); } catch (FileError& e) { - throw FileError ("could not load CPL file", file); + boost::throw_exception (FileError ("could not load CPL file", file)); } /* Now cherry-pick the required bits into our own data structure */ diff --git a/src/dcp_time.cc b/src/dcp_time.cc index 15ad05d4..bdf55f93 100644 --- a/src/dcp_time.cc +++ b/src/dcp_time.cc @@ -59,7 +59,7 @@ Time::Time (string time) vector b; split (b, time, is_any_of (":")); if (b.size() != 4) { - throw DCPReadError ("unrecognised time specification"); + boost::throw_exception (DCPReadError ("unrecognised time specification")); } h = lexical_cast (b[0]); diff --git a/src/picture_asset.cc b/src/picture_asset.cc index e0e55979..13253242 100644 --- a/src/picture_asset.cc +++ b/src/picture_asset.cc @@ -87,21 +87,21 @@ PictureAsset::equals (shared_ptr other, EqualityOptions opt, listpath().string().c_str()))) { - throw MXFFileError ("could not open MXF file for reading", path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); } ASDCP::JP2K::PictureDescriptor desc_A; if (ASDCP_FAILURE (reader_A.FillPictureDescriptor (desc_A))) { - throw DCPReadError ("could not read video MXF information"); + boost::throw_exception (DCPReadError ("could not read video MXF information")); } ASDCP::JP2K::PictureDescriptor desc_B; if (ASDCP_FAILURE (reader_B.FillPictureDescriptor (desc_B))) { - throw DCPReadError ("could not read video MXF information"); + boost::throw_exception (DCPReadError ("could not read video MXF information")); } if ( @@ -176,12 +176,12 @@ MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name) { ASDCP::JP2K::MXFReader reader; if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) { - throw MXFFileError ("could not open MXF file for reading", path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); } ASDCP::JP2K::PictureDescriptor desc; if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) { - throw DCPReadError ("could not read video MXF information"); + boost::throw_exception (DCPReadError ("could not read video MXF information")); } _size.width = desc.StoredWidth; @@ -197,7 +197,7 @@ MonoPictureAsset::construct (boost::function get_path) ASDCP::JP2K::CodestreamParser j2k_parser; ASDCP::JP2K::FrameBuffer frame_buffer (4 * Kumu::Megabyte); if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (get_path(0).c_str(), frame_buffer))) { - throw FileError ("could not open JPEG2000 file for reading", get_path (0)); + boost::throw_exception (FileError ("could not open JPEG2000 file for reading", get_path (0))); } ASDCP::JP2K::PictureDescriptor picture_desc; @@ -209,7 +209,7 @@ MonoPictureAsset::construct (boost::function get_path) ASDCP::JP2K::MXFWriter mxf_writer; if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, picture_desc, 16384, false))) { - throw MXFFileError ("could not open MXF file for writing", path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for writing", path().string())); } for (int i = 0; i < _intrinsic_duration; ++i) { @@ -217,11 +217,11 @@ MonoPictureAsset::construct (boost::function get_path) string const path = get_path (i); if (ASDCP_FAILURE (j2k_parser.OpenReadFrame (path.c_str(), frame_buffer))) { - throw FileError ("could not open JPEG2000 file for reading", path); + boost::throw_exception (FileError ("could not open JPEG2000 file for reading", path)); } if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, 0, 0))) { - throw MXFFileError ("error in writing video MXF", this->path().string()); + boost::throw_exception (MXFFileError ("error in writing video MXF", this->path().string())); } if (_progress) { @@ -230,7 +230,7 @@ MonoPictureAsset::construct (boost::function get_path) } if (ASDCP_FAILURE (mxf_writer.Finalize())) { - throw MXFFileError ("error in finalising video MXF", path().string()); + boost::throw_exception (MXFFileError ("error in finalising video MXF", path().string())); } } @@ -378,12 +378,12 @@ StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int f { ASDCP::JP2K::MXFSReader reader; if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) { - throw MXFFileError ("could not open MXF file for reading", path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); } ASDCP::JP2K::PictureDescriptor desc; if (ASDCP_FAILURE (reader.FillPictureDescriptor (desc))) { - throw DCPReadError ("could not read video MXF information"); + boost::throw_exception (DCPReadError ("could not read video MXF information")); } _size.width = desc.StoredWidth; @@ -447,7 +447,7 @@ void MonoPictureAssetWriter::start (uint8_t* data, int size) { if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) { - throw MiscError ("could not parse J2K frame"); + boost::throw_exception (MiscError ("could not parse J2K frame")); } _state->j2k_parser.FillPictureDescriptor (_state->picture_descriptor); @@ -463,7 +463,7 @@ MonoPictureAssetWriter::start (uint8_t* data, int size) _overwrite) )) { - throw MXFFileError ("could not open MXF file for writing", _asset->path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for writing", _asset->path().string())); } _started = true; @@ -479,14 +479,14 @@ MonoPictureAssetWriter::write (uint8_t* data, int size) } if (ASDCP_FAILURE (_state->j2k_parser.OpenReadFrame (data, size, _state->frame_buffer))) { - throw MiscError ("could not parse J2K frame"); + boost::throw_exception (MiscError ("could not parse J2K frame")); } uint64_t const before_offset = _state->mxf_writer.Tell (); string hash; if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, 0, 0, &hash))) { - throw MXFFileError ("error in writing video MXF", _asset->path().string()); + boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string())); } ++_frames_written; @@ -500,7 +500,7 @@ MonoPictureAssetWriter::fake_write (int size) assert (!_finalized); if (ASDCP_FAILURE (_state->mxf_writer.FakeWriteFrame (size))) { - throw MXFFileError ("error in writing video MXF", _asset->path().string()); + boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string())); } ++_frames_written; @@ -512,7 +512,7 @@ MonoPictureAssetWriter::finalize () assert (!_finalized); if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) { - throw MXFFileError ("error in finalizing video MXF", _asset->path().string()); + boost::throw_exception (MXFFileError ("error in finalizing video MXF", _asset->path().string())); } _finalized = true; diff --git a/src/picture_frame.cc b/src/picture_frame.cc index 907f70ab..5898d0ea 100644 --- a/src/picture_frame.cc +++ b/src/picture_frame.cc @@ -38,14 +38,14 @@ MonoPictureFrame::MonoPictureFrame (string mxf_path, int n) { ASDCP::JP2K::MXFReader reader; if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) { - throw FileError ("could not open MXF file for reading", mxf_path); + boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path)); } /* XXX: unfortunate guesswork on this buffer size */ _buffer = new ASDCP::JP2K::FrameBuffer (4 * Kumu::Megabyte); if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer))) { - throw DCPReadError ("could not read video frame"); + boost::throw_exception (DCPReadError ("could not read video frame")); } } @@ -93,14 +93,14 @@ StereoPictureFrame::StereoPictureFrame (string mxf_path, int n) { ASDCP::JP2K::MXFSReader reader; if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) { - throw FileError ("could not open MXF file for reading", mxf_path); + boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path)); } /* XXX: unfortunate guesswork on this buffer size */ _buffer = new ASDCP::JP2K::SFrameBuffer (4 * Kumu::Megabyte); if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer))) { - throw DCPReadError ("could not read video frame"); + boost::throw_exception (DCPReadError ("could not read video frame")); } } diff --git a/src/sound_asset.cc b/src/sound_asset.cc index 4d76a2fd..014b95a2 100644 --- a/src/sound_asset.cc +++ b/src/sound_asset.cc @@ -79,12 +79,12 @@ SoundAsset::SoundAsset (string directory, string mxf_name) { ASDCP::PCM::MXFReader reader; if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) { - throw MXFFileError ("could not open MXF file for reading", path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); } ASDCP::PCM::AudioDescriptor desc; if (ASDCP_FAILURE (reader.FillAudioDescriptor (desc))) { - throw DCPReadError ("could not read audio MXF information"); + boost::throw_exception (DCPReadError ("could not read audio MXF information")); } _sampling_rate = desc.AudioSamplingRate.Numerator / desc.AudioSamplingRate.Denominator; @@ -117,7 +117,7 @@ SoundAsset::construct (boost::function get_path) ASDCP::PCM::WAVParser pcm_parser_channel[_channels]; if (pcm_parser_channel[0].OpenRead (get_path(LEFT).c_str(), asdcp_edit_rate)) { - throw FileError ("could not open WAV file for reading", get_path(LEFT)); + boost::throw_exception (FileError ("could not open WAV file for reading", get_path(LEFT))); } ASDCP::PCM::AudioDescriptor audio_desc; @@ -149,7 +149,7 @@ SoundAsset::construct (boost::function get_path) string const path = get_path (channels[i]); if (ASDCP_FAILURE (pcm_parser_channel[i].OpenRead (path.c_str(), asdcp_edit_rate))) { - throw FileError ("could not open WAV file for reading", path); + boost::throw_exception (FileError ("could not open WAV file for reading", path)); } pcm_parser_channel[i].FillAudioDescriptor (audio_desc_channel[i]); @@ -168,7 +168,7 @@ SoundAsset::construct (boost::function get_path) ASDCP::PCM::MXFWriter mxf_writer; if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc))) { - throw FileError ("could not open audio MXF for writing", path().string()); + boost::throw_exception (FileError ("could not open audio MXF for writing", path().string())); } for (int i = 0; i < _intrinsic_duration; ++i) { @@ -176,7 +176,7 @@ SoundAsset::construct (boost::function get_path) for (int j = 0; j < _channels; ++j) { memset (frame_buffer_channel[j].Data(), 0, frame_buffer_channel[j].Capacity()); if (ASDCP_FAILURE (pcm_parser_channel[j].ReadFrame (frame_buffer_channel[j]))) { - throw MiscError ("could not read audio frame"); + boost::throw_exception (MiscError ("could not read audio frame")); } } @@ -195,7 +195,7 @@ SoundAsset::construct (boost::function get_path) } if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, 0, 0))) { - throw MiscError ("could not write audio MXF frame"); + boost::throw_exception (MiscError ("could not write audio MXF frame")); } if (_progress) { @@ -204,7 +204,7 @@ SoundAsset::construct (boost::function get_path) } if (ASDCP_FAILURE (mxf_writer.Finalize())) { - throw MiscError ("could not finalise audio MXF"); + boost::throw_exception (MiscError ("could not finalise audio MXF")); } } @@ -230,21 +230,21 @@ SoundAsset::equals (shared_ptr other, EqualityOptions opt, listpath().string().c_str()))) { - throw MXFFileError ("could not open MXF file for reading", path().string()); + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); } ASDCP::PCM::AudioDescriptor desc_A; if (ASDCP_FAILURE (reader_A.FillAudioDescriptor (desc_A))) { - throw DCPReadError ("could not read audio MXF information"); + boost::throw_exception (DCPReadError ("could not read audio MXF information")); } ASDCP::PCM::AudioDescriptor desc_B; if (ASDCP_FAILURE (reader_B.FillAudioDescriptor (desc_B))) { - throw DCPReadError ("could not read audio MXF information"); + boost::throw_exception (DCPReadError ("could not read audio MXF information")); } if ( @@ -269,11 +269,11 @@ SoundAsset::equals (shared_ptr other, EqualityOptions opt, listwriter_info, _asset->uuid ()); if (ASDCP_FAILURE (_state->mxf_writer.OpenWrite (_asset->path().string().c_str(), _state->writer_info, _state->audio_desc))) { - throw FileError ("could not open audio MXF for writing", _asset->path().string()); + boost::throw_exception (FileError ("could not open audio MXF for writing", _asset->path().string())); } } @@ -376,7 +376,7 @@ void SoundAssetWriter::write_current_frame () { if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, 0, 0))) { - throw MiscError ("could not write audio MXF frame"); + boost::throw_exception (MiscError ("could not write audio MXF frame")); } ++_frames_written; @@ -390,7 +390,7 @@ SoundAssetWriter::finalize () } if (ASDCP_FAILURE (_state->mxf_writer.Finalize())) { - throw MiscError ("could not finalise audio MXF"); + boost::throw_exception (MiscError ("could not finalise audio MXF")); } _finalized = true; diff --git a/src/sound_frame.cc b/src/sound_frame.cc index ed626f5e..c2a10564 100644 --- a/src/sound_frame.cc +++ b/src/sound_frame.cc @@ -29,14 +29,14 @@ SoundFrame::SoundFrame (string mxf_path, int n) { ASDCP::PCM::MXFReader reader; if (ASDCP_FAILURE (reader.OpenRead (mxf_path.c_str()))) { - throw FileError ("could not open MXF file for reading", mxf_path); + boost::throw_exception (FileError ("could not open MXF file for reading", mxf_path)); } /* XXX: unfortunate guesswork on this buffer size */ _buffer = new ASDCP::PCM::FrameBuffer (1 * Kumu::Megabyte); if (ASDCP_FAILURE (reader.ReadFrame (n, *_buffer))) { - throw DCPReadError ("could not read audio frame"); + boost::throw_exception (DCPReadError ("could not read audio frame")); } } diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc index c7051eae..ba91cf90 100644 --- a/src/subtitle_asset.cc +++ b/src/subtitle_asset.cc @@ -413,7 +413,7 @@ SubtitleAsset::write_xml (ostream& s) const << " " << _language << "\n"; if (_load_font_nodes.size() > 1) { - throw MiscError ("multiple LoadFont nodes not supported"); + boost::throw_exception (MiscError ("multiple LoadFont nodes not supported")); } if (!_load_font_nodes.empty ()) { diff --git a/src/types.cc b/src/types.cc index ac01ae45..693b9ab2 100644 --- a/src/types.cc +++ b/src/types.cc @@ -15,7 +15,7 @@ Fraction::Fraction (string s) vector b; split (b, s, is_any_of (" ")); if (b.size() != 2) { - throw XMLError ("malformed fraction " + s + " in XML node"); + boost::throw_exception (XMLError ("malformed fraction " + s + " in XML node")); } numerator = lexical_cast (b[0]); denominator = lexical_cast (b[1]); @@ -57,7 +57,7 @@ Color::Color (string argb_hex) { int alpha; if (sscanf (argb_hex.c_str(), "%2x%2x%2x%2x", &alpha, &r, &g, &b) < 4) { - throw XMLError ("could not parse colour string"); + boost::throw_exception (XMLError ("could not parse colour string")); } } @@ -118,7 +118,7 @@ libdcp::effect_to_string (Effect e) return "shadow"; } - throw MiscError ("unknown effect type"); + boost::throw_exception (MiscError ("unknown effect type")); } Effect @@ -132,7 +132,7 @@ libdcp::string_to_effect (string s) return SHADOW; } - throw DCPReadError ("unknown subtitle effect type"); + boost::throw_exception (DCPReadError ("unknown subtitle effect type")); } string @@ -147,7 +147,7 @@ libdcp::valign_to_string (VAlign v) return "bottom"; } - throw MiscError ("unknown valign type"); + boost::throw_exception (MiscError ("unknown valign type")); } VAlign @@ -161,7 +161,7 @@ libdcp::string_to_valign (string s) return BOTTOM; } - throw DCPReadError ("unknown subtitle valign type"); + boost::throw_exception (DCPReadError ("unknown subtitle valign type")); } diff --git a/src/util.cc b/src/util.cc index 1cbec719..b1556e33 100644 --- a/src/util.cc +++ b/src/util.cc @@ -66,7 +66,7 @@ libdcp::make_digest (string filename) { Kumu::FileReader reader; if (ASDCP_FAILURE (reader.OpenRead (filename.c_str ()))) { - throw FileError ("could not open file to compute digest", filename); + boost::throw_exception (FileError ("could not open file to compute digest", filename)); } SHA_CTX sha; @@ -81,7 +81,7 @@ libdcp::make_digest (string filename) if (r == Kumu::RESULT_ENDOFFILE) { break; } else if (ASDCP_FAILURE (r)) { - throw FileError ("could not read file to compute digest", filename); + boost::throw_exception (FileError ("could not read file to compute digest", filename)); } SHA1_Update (&sha, read_buffer.Data(), read); @@ -187,7 +187,7 @@ libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) if (!image) { opj_destroy_decompress (decoder); opj_cio_close (cio); - throw DCPReadError ("could not decode JPEG2000 codestream"); + boost::throw_exception (DCPReadError ("could not decode JPEG2000 codestream")); } opj_cio_close (cio); diff --git a/src/xml.cc b/src/xml.cc index 22e91ac0..508790ab 100644 --- a/src/xml.cc +++ b/src/xml.cc @@ -29,9 +29,9 @@ XMLNode::node_child (string name) { list n = node_children (name); if (n.size() > 1) { - throw XMLError ("duplicate XML tag " + name); + boost::throw_exception (XMLError ("duplicate XML tag " + name)); } else if (n.empty ()) { - throw XMLError ("missing XML tag " + name + " in " + _node->get_name()); + boost::throw_exception (XMLError ("missing XML tag " + name + " in " + _node->get_name())); } return n.front (); @@ -68,7 +68,7 @@ XMLNode::optional_string_child (string name) { list nodes = node_children (name); if (nodes.size() > 2) { - throw XMLError ("duplicate XML tag " + name); + boost::throw_exception (XMLError ("duplicate XML tag " + name)); } if (nodes.empty ()) { @@ -103,7 +103,7 @@ XMLNode::optional_int64_child (string name) { list nodes = node_children (name); if (nodes.size() > 2) { - throw XMLError ("duplicate XML tag " + name); + boost::throw_exception (XMLError ("duplicate XML tag " + name)); } if (nodes.empty ()) { @@ -136,12 +136,12 @@ XMLNode::string_attribute (string name) { xmlpp::Element const * e = dynamic_cast (_node); if (!e) { - throw XMLError ("missing attribute"); + boost::throw_exception (XMLError ("missing attribute")); } xmlpp::Attribute* a = e->get_attribute (name); if (!a) { - throw XMLError ("missing attribute"); + boost::throw_exception (XMLError ("missing attribute")); } return a->get_value (); @@ -218,7 +218,7 @@ XMLNode::done () xmlpp::Node::NodeList c = _node->get_children (); for (xmlpp::Node::NodeList::iterator i = c.begin(); i != c.end(); ++i) { if (dynamic_cast (*i) && find (_taken.begin(), _taken.end(), (*i)->get_name()) == _taken.end ()) { - throw XMLError ("unexpected XML node " + (*i)->get_name()); + boost::throw_exception (XMLError ("unexpected XML node " + (*i)->get_name())); } } } @@ -242,18 +242,18 @@ XMLNode::content () XMLFile::XMLFile (string file, string root_name) { if (!filesystem::exists (file)) { - throw FileError ("XML file does not exist", file); + boost::throw_exception (FileError ("XML file does not exist", file)); } _parser = new xmlpp::DomParser; _parser->parse_file (file); if (!_parser) { - throw XMLError ("could not parse XML"); + boost::throw_exception (XMLError ("could not parse XML")); } _node = _parser->get_document()->get_root_node (); if (_node->get_name() != root_name) { - throw XMLError ("unrecognised root node"); + boost::throw_exception (XMLError ("unrecognised root node")); } } -- cgit v1.2.3 From 45625f3116a09d3c8415a54bf8d19fdbb3a3aa9b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 13 Mar 2013 16:46:50 +0000 Subject: Compute LUTs at run-time. --- .gitignore | 2 - lut.py | 127 --------------------------------------------------- src/gamma_lut.cc | 16 +++++++ src/gamma_lut.h | 13 ++++++ src/lut.h | 63 +++++++++++++++++++++++++ src/lut_cache.h | 28 ++++++++++++ src/picture_frame.cc | 12 +++-- src/picture_frame.h | 4 +- src/util.cc | 40 ++++++++++------ src/util.h | 4 +- src/wscript | 3 +- src/xyz_srgb_lut.cc | 24 ++++++++++ src/xyz_srgb_lut.h | 13 ++++++ test/tests.cc | 1 + wscript | 3 -- 15 files changed, 199 insertions(+), 154 deletions(-) delete mode 100644 lut.py create mode 100644 src/gamma_lut.cc create mode 100644 src/gamma_lut.h create mode 100644 src/lut.h create mode 100644 src/lut_cache.h create mode 100644 src/xyz_srgb_lut.cc create mode 100644 src/xyz_srgb_lut.h (limited to 'src/util.cc') diff --git a/.gitignore b/.gitignore index d845eee5..2170048b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,6 @@ build doc/html doc/latex src/version.cc -src/lut.cc -src/lut.h *.pyc __pycache__ GPATH diff --git a/lut.py b/lut.py deleted file mode 100644 index 9dd4ff20..00000000 --- a/lut.py +++ /dev/null @@ -1,127 +0,0 @@ -from __future__ import print_function -import math - -BIT_DEPTH = 12 -DCI_GAMMA = 2.6 -SRGB_GAMMA = 2.4; -BIT_LENGTH = int(math.pow(2, BIT_DEPTH)) -COLOR_DEPTH = BIT_LENGTH - 1 - -def boilerplate(f): - print("""/* - Copyright (C) 2012 Carl Hetherington - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -/* This file is auto-generated by the build scripts; edits will be lost - on ./waf configure. -*/ -""", file=f) - -def make_luts(): - cc = open('src/lut.cc', 'w') - - boilerplate(cc) - - print("#include \"lut.h\"", file=cc) - - print(""" -/* sRGB color matrix for XYZ -> RGB */ -float color_matrix[3][3] = { - { 3.240454836, -1.537138850, -0.498531547}, - {-0.969266390, 1.876010929, 0.041556082}, - { 0.055643420, -0.204025854, 1.057225162} -};\n\n -""", file=cc) - - print(""" -float lut_in[COLOR_DEPTH + 1] = {\n -\t/* Bit depth: %d -\t * Reference white: DCI -\t * Gamma: %f -\t */ -""" % (BIT_DEPTH, DCI_GAMMA), file=cc) - - c = 0 - for i in range(0, BIT_LENGTH): - v = math.pow (i / (BIT_LENGTH - 1.0), DCI_GAMMA); - - if (c == 0): - print(" ", end='', file=cc) - - if i < BIT_LENGTH - 1: - print("%06f, " % v, end="", file=cc) - if c == 12: - c = 0; - print("", file=cc) - else: - c += 1 - else: - print("%06f" % v, file=cc) - - print("};", file=cc) - - print(""" -int lut_out[COLOR_DEPTH + 1] = { -\t/* Bit depth: %d -\t * Reference white: sRGB -\t * Gamma: %f -\t */ -""", file=cc) - - c = 0 - for i in range (0, BIT_LENGTH): - v = i / (BIT_LENGTH - 1.0) - - if (v < (0.04045 / 12.92)): - v *= 12.92 - else: - v = (1.055 * pow (v, (1 / SRGB_GAMMA))) - 0.055 - - v *= 255 - - if c == 0: - print(" ", end="", file=cc) - - if i < BIT_LENGTH - 1: - print("%d, " % v, end="", file=cc) - if c == 12: - c = 0; - print("", file=cc) - else: - c += 1 - else: - print("%d" % v, file=cc) - - print("};", file=cc) - - h = open('src/lut.h', 'w') - - boilerplate(h) - - print(""" -#define COLOR_DEPTH (%d) -#define DCI_COEFFICIENT (48.0/52.37) - -extern float color_matrix[3][3]; -extern int lut_out[COLOR_DEPTH + 1]; -extern float lut_in[COLOR_DEPTH + 1]; -""" % COLOR_DEPTH, file=h) - -if __name__ == "__main__": - make_luts() diff --git a/src/gamma_lut.cc b/src/gamma_lut.cc new file mode 100644 index 00000000..acc80af0 --- /dev/null +++ b/src/gamma_lut.cc @@ -0,0 +1,16 @@ +#include +#include "gamma_lut.h" +#include "lut_cache.h" + +using namespace libdcp; + +LUTCache GammaLUT::cache; + +GammaLUT::GammaLUT(int bits, float gamma) + : LUT (bits, gamma) +{ + int const bit_length = pow(2, bits); + for (int i = 0; i < bit_length; ++i) { + _lut[i] = pow(float(i) / (bit_length - 1), gamma); + } +} diff --git a/src/gamma_lut.h b/src/gamma_lut.h new file mode 100644 index 00000000..e41cd21f --- /dev/null +++ b/src/gamma_lut.h @@ -0,0 +1,13 @@ +#include "lut.h" +#include "lut_cache.h" + +namespace libdcp { + +class GammaLUT : public LUT +{ +public: + GammaLUT (int bit_length, float gamma); + static LUTCache cache; +}; + +} diff --git a/src/lut.h b/src/lut.h new file mode 100644 index 00000000..8363e6a4 --- /dev/null +++ b/src/lut.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2012 Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef LIBDCP_LUT_H +#define LIBDCP_LUT_H + +#include + +namespace libdcp { + +template +class LUT +{ +public: + LUT(int bit_depth, float gamma) + : _lut(0) + , _bit_depth (bit_depth) + , _gamma (gamma) + { + _lut = new T[int(std::pow(2, _bit_depth))]; + } + + virtual ~LUT() { + delete[] _lut; + } + + T const * lut() const { + return _lut; + } + + int bit_depth () const { + return _bit_depth; + } + + float gamma () const { + return _gamma; + } + +protected: + T* _lut; + int _bit_depth; + float _gamma; +}; + +} + +#endif diff --git a/src/lut_cache.h b/src/lut_cache.h new file mode 100644 index 00000000..b60ee109 --- /dev/null +++ b/src/lut_cache.h @@ -0,0 +1,28 @@ +#ifndef LIBDCP_LUT_CACHE_H +#define LIBDCP_LUT_CACHE_H + +#include +#include + +template +class LUTCache +{ +public: + boost::shared_ptr get (int bit_depth, float gamma) + { + for (typename std::list >::iterator i = _cache.begin(); i != _cache.end(); ++i) { + if ((*i)->bit_depth() == bit_depth && (*i)->gamma() == gamma) { + return *i; + } + } + + boost::shared_ptr lut (new T (bit_depth, gamma)); + _cache.push_back (lut); + return lut; + } + +private: + std::list > _cache; +}; + +#endif diff --git a/src/picture_frame.cc b/src/picture_frame.cc index 907f70ab..5d5f12c2 100644 --- a/src/picture_frame.cc +++ b/src/picture_frame.cc @@ -25,6 +25,10 @@ #include "argb_frame.h" #include "lut.h" #include "util.h" +#include "gamma_lut.h" +#include "xyz_srgb_lut.h" + +#define DCI_GAMMA 2.6 using std::string; using boost::shared_ptr; @@ -76,11 +80,11 @@ MonoPictureFrame::j2k_size () const * */ shared_ptr -MonoPictureFrame::argb_frame (int reduce) const +MonoPictureFrame::argb_frame (int reduce, float srgb_gamma) const { opj_image_t* xyz_frame = decompress_j2k (const_cast (_buffer->RoData()), _buffer->Size(), reduce); assert (xyz_frame->numcomps == 3); - shared_ptr f = xyz_to_rgb (xyz_frame); + shared_ptr f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma)); opj_image_destroy (xyz_frame); return f; } @@ -122,7 +126,7 @@ StereoPictureFrame::~StereoPictureFrame () * */ shared_ptr -StereoPictureFrame::argb_frame (Eye eye, int reduce) const +StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const { opj_image_t* xyz_frame = 0; switch (eye) { @@ -135,7 +139,7 @@ StereoPictureFrame::argb_frame (Eye eye, int reduce) const } assert (xyz_frame->numcomps == 3); - shared_ptr f = xyz_to_rgb (xyz_frame); + shared_ptr f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma)); opj_image_destroy (xyz_frame); return f; } diff --git a/src/picture_frame.h b/src/picture_frame.h index 20ce069e..42c5d629 100644 --- a/src/picture_frame.h +++ b/src/picture_frame.h @@ -40,7 +40,7 @@ public: MonoPictureFrame (std::string mxf_path, int n); ~MonoPictureFrame (); - boost::shared_ptr argb_frame (int reduce = 0) const; + boost::shared_ptr argb_frame (int reduce = 0, float srgb_gamma = 2.4) const; uint8_t const * j2k_data () const; int j2k_size () const; @@ -55,7 +55,7 @@ public: StereoPictureFrame (std::string mxf_path, int n); ~StereoPictureFrame (); - boost::shared_ptr argb_frame (Eye eye, int reduce = 0) const; + boost::shared_ptr argb_frame (Eye eye, int reduce = 0, float srgb_gamma = 2.4) const; uint8_t const * left_j2k_data () const; int left_j2k_size () const; uint8_t const * right_j2k_data () const; diff --git a/src/util.cc b/src/util.cc index 1cbec719..bd5f32ed 100644 --- a/src/util.cc +++ b/src/util.cc @@ -34,7 +34,8 @@ #include "exceptions.h" #include "types.h" #include "argb_frame.h" -#include "lut.h" +#include "gamma_lut.h" +#include "xyz_srgb_lut.h" using std::string; using std::stringstream; @@ -202,8 +203,19 @@ libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) * @return RGB image. */ shared_ptr -libdcp::xyz_to_rgb (opj_image_t* xyz_frame) +libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, shared_ptr lut_out) { + float const dci_coefficient = 48.0 / 52.37; + + /* sRGB color matrix for XYZ -> RGB */ + float const colour_matrix[3][3] = { + { 3.240454836, -1.537138850, -0.498531547}, + {-0.969266390, 1.876010929, 0.041556082}, + { 0.055643420, -0.204025854, 1.057225162} + }; + + int const max_colour = pow (2, lut_out->bit_depth()) - 1; + struct { double x, y, z; } s; @@ -227,19 +239,19 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame) assert (*xyz_x >= 0 && *xyz_y >= 0 && *xyz_z >= 0 && *xyz_x < 4096 && *xyz_x < 4096 && *xyz_z < 4096); /* In gamma LUT */ - s.x = lut_in[*xyz_x++]; - s.y = lut_in[*xyz_y++]; - s.z = lut_in[*xyz_z++]; + s.x = lut_in->lut()[*xyz_x++]; + s.y = lut_in->lut()[*xyz_y++]; + s.z = lut_in->lut()[*xyz_z++]; /* DCI companding */ - s.x /= DCI_COEFFICIENT; - s.y /= DCI_COEFFICIENT; - s.z /= DCI_COEFFICIENT; + s.x /= dci_coefficient; + s.y /= dci_coefficient; + s.z /= dci_coefficient; /* XYZ to RGB */ - d.r = ((s.x * color_matrix[0][0]) + (s.y * color_matrix[0][1]) + (s.z * color_matrix[0][2])); - d.g = ((s.x * color_matrix[1][0]) + (s.y * color_matrix[1][1]) + (s.z * color_matrix[1][2])); - d.b = ((s.x * color_matrix[2][0]) + (s.y * color_matrix[2][1]) + (s.z * color_matrix[2][2])); + d.r = ((s.x * colour_matrix[0][0]) + (s.y * colour_matrix[0][1]) + (s.z * colour_matrix[0][2])); + d.g = ((s.x * colour_matrix[1][0]) + (s.y * colour_matrix[1][1]) + (s.z * colour_matrix[1][2])); + d.b = ((s.x * colour_matrix[2][0]) + (s.y * colour_matrix[2][1]) + (s.z * colour_matrix[2][2])); d.r = min (d.r, 1.0); d.r = max (d.r, 0.0); @@ -251,9 +263,9 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame) d.b = max (d.b, 0.0); /* Out gamma LUT */ - *argb_line++ = lut_out[(int) (d.b * COLOR_DEPTH)]; - *argb_line++ = lut_out[(int) (d.g * COLOR_DEPTH)]; - *argb_line++ = lut_out[(int) (d.r * COLOR_DEPTH)]; + *argb_line++ = lut_out->lut()[(int) (d.b * max_colour)]; + *argb_line++ = lut_out->lut()[(int) (d.g * max_colour)]; + *argb_line++ = lut_out->lut()[(int) (d.r * max_colour)]; *argb_line++ = 0xff; } diff --git a/src/util.h b/src/util.h index f5685970..2036a7ce 100644 --- a/src/util.h +++ b/src/util.h @@ -33,6 +33,8 @@ namespace libdcp { class ARGBFrame; +class GammaLUT; +class XYZsRGBLUT; struct Size { Size () @@ -58,7 +60,7 @@ extern std::string content_kind_to_string (ContentKind kind); extern ContentKind content_kind_from_string (std::string kind); extern bool empty_or_white_space (std::string s); extern opj_image_t* decompress_j2k (uint8_t* data, int64_t size, int reduce); -extern boost::shared_ptr xyz_to_rgb (opj_image_t* xyz_frame); +extern boost::shared_ptr xyz_to_rgb (opj_image_t* xyz_frame, boost::shared_ptr, boost::shared_ptr); } diff --git a/src/wscript b/src/wscript index d243ae46..efba2502 100644 --- a/src/wscript +++ b/src/wscript @@ -15,7 +15,7 @@ def build(bld): cpl_file.cc dcp.cc dcp_time.cc - lut.cc + gamma_lut.cc metadata.cc mxf_asset.cc picture_asset.cc @@ -31,6 +31,7 @@ def build(bld): util.cc version.cc xml.cc + xyz_srgb_lut.cc """ headers = """ diff --git a/src/xyz_srgb_lut.cc b/src/xyz_srgb_lut.cc new file mode 100644 index 00000000..3d207195 --- /dev/null +++ b/src/xyz_srgb_lut.cc @@ -0,0 +1,24 @@ +#include +#include +#include "xyz_srgb_lut.h" + +using namespace libdcp; + +LUTCache XYZsRGBLUT::cache; + +XYZsRGBLUT::XYZsRGBLUT(int bits, float gamma) + : LUT (bits, gamma) +{ + int const bit_length = pow(2, bits); + + for (int i = 0; i < bit_length; ++i) { + float v = float(i) / (bit_length - 1); + if (v < (0.04045 / 12.92)) { + v *= 12.92; + } else { + v = (1.055 * pow (v, (1 / gamma))) - 0.055; + } + + _lut[i] = int(v * 255); + } +} diff --git a/src/xyz_srgb_lut.h b/src/xyz_srgb_lut.h new file mode 100644 index 00000000..63f89178 --- /dev/null +++ b/src/xyz_srgb_lut.h @@ -0,0 +1,13 @@ +#include "lut.h" +#include "lut_cache.h" + +namespace libdcp { + +class XYZsRGBLUT : public LUT +{ +public: + XYZsRGBLUT(int colour_depth, float gamma); + static LUTCache cache; +}; + +} diff --git a/test/tests.cc b/test/tests.cc index 62cab54c..30c9f406 100644 --- a/test/tests.cc +++ b/test/tests.cc @@ -29,6 +29,7 @@ #include "picture_asset.h" #include "sound_asset.h" #include "reel.h" +#include "gamma_lut.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE libdcp_test diff --git a/wscript b/wscript index 27483bac..8829ccd8 100644 --- a/wscript +++ b/wscript @@ -1,6 +1,5 @@ import subprocess import os -import lut APPNAME = 'libdcp' VERSION = '0.40pre' @@ -83,8 +82,6 @@ def configure(conf): msg = 'Checking for boost signals2 library', uselib_store = 'BOOST_SIGNALS2') - lut.make_luts() - conf.recurse('test') conf.recurse('asdcplib') -- cgit v1.2.3 From 1c4257eacfe62f30f3e08edfe049a954cd7b43a3 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Mar 2013 20:24:10 +0000 Subject: Try removing the DCI companding from the xyz->rgb conversion. --- src/util.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/util.cc') diff --git a/src/util.cc b/src/util.cc index a6d65374..d5565245 100644 --- a/src/util.cc +++ b/src/util.cc @@ -242,11 +242,13 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, s s.x = lut_in->lut()[*xyz_x++]; s.y = lut_in->lut()[*xyz_y++]; s.z = lut_in->lut()[*xyz_z++]; - + +#if 0 /* DCI companding */ s.x /= dci_coefficient; s.y /= dci_coefficient; s.z /= dci_coefficient; +#endif /* XYZ to RGB */ d.r = ((s.x * colour_matrix[0][0]) + (s.y * colour_matrix[0][1]) + (s.z * colour_matrix[0][2])); -- cgit v1.2.3 From 10655124e560b28418a765bebaa760dfc9885b0a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 24 Mar 2013 21:04:49 +0000 Subject: Re-enable DCI companding; modify RGB matrix to that given on http://www.digitall.net.au/products/dcp-player/64.html --- src/util.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/util.cc') diff --git a/src/util.cc b/src/util.cc index d5565245..7543f8ba 100644 --- a/src/util.cc +++ b/src/util.cc @@ -208,11 +208,19 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, s float const dci_coefficient = 48.0 / 52.37; /* sRGB color matrix for XYZ -> RGB */ +#if 0 float const colour_matrix[3][3] = { { 3.240454836, -1.537138850, -0.498531547}, {-0.969266390, 1.876010929, 0.041556082}, { 0.055643420, -0.204025854, 1.057225162} }; +#endif + + float const colour_matrix[3][3] = { + { 3.1338561, -1.6168667, -0.4906146 }, + { -0.9787684, 1.9161415, 0.0334540 }, + { 0.0719453, -0.2289914, 1.4052427 } + }; int const max_colour = pow (2, lut_out->bit_depth()) - 1; @@ -243,12 +251,10 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, s s.y = lut_in->lut()[*xyz_y++]; s.z = lut_in->lut()[*xyz_z++]; -#if 0 /* DCI companding */ s.x /= dci_coefficient; s.y /= dci_coefficient; s.z /= dci_coefficient; -#endif /* XYZ to RGB */ d.r = ((s.x * colour_matrix[0][0]) + (s.y * colour_matrix[0][1]) + (s.z * colour_matrix[0][2])); -- cgit v1.2.3 From ab3163255b9713fc40a73fcfc3753b62ee084b8d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 26 Mar 2013 20:22:05 +0000 Subject: Set RGB colour matrix from Thomas' email re FH. --- src/util.cc | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/util.cc') diff --git a/src/util.cc b/src/util.cc index 7543f8ba..2fae8561 100644 --- a/src/util.cc +++ b/src/util.cc @@ -208,18 +208,11 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, s float const dci_coefficient = 48.0 / 52.37; /* sRGB color matrix for XYZ -> RGB */ -#if 0 - float const colour_matrix[3][3] = { - { 3.240454836, -1.537138850, -0.498531547}, - {-0.969266390, 1.876010929, 0.041556082}, - { 0.055643420, -0.204025854, 1.057225162} - }; -#endif float const colour_matrix[3][3] = { - { 3.1338561, -1.6168667, -0.4906146 }, - { -0.9787684, 1.9161415, 0.0334540 }, - { 0.0719453, -0.2289914, 1.4052427 } + { 3.24096989631653, -1.5373831987381, -0.498610764741898 }, + { -0.96924364566803, 1.87596750259399, 0.0415550582110882 }, + { 0.0556300804018974, -0.203976958990097, 1.05697154998779 } }; int const max_colour = pow (2, lut_out->bit_depth()) - 1; -- cgit v1.2.3 From 5b6d753439207fcb33b84690bcc22d142a7c3bfa Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 29 Apr 2013 15:22:55 +0100 Subject: Change output gamma correction to be closer to EasyDCP behaviour. --- src/picture_frame.cc | 5 ++--- src/util.cc | 13 +++++++------ src/util.h | 2 +- src/wscript | 1 - src/xyz_srgb_lut.cc | 24 ------------------------ src/xyz_srgb_lut.h | 13 ------------- 6 files changed, 10 insertions(+), 48 deletions(-) delete mode 100644 src/xyz_srgb_lut.cc delete mode 100644 src/xyz_srgb_lut.h (limited to 'src/util.cc') diff --git a/src/picture_frame.cc b/src/picture_frame.cc index 98802101..7e6bc1f8 100644 --- a/src/picture_frame.cc +++ b/src/picture_frame.cc @@ -26,7 +26,6 @@ #include "lut.h" #include "util.h" #include "gamma_lut.h" -#include "xyz_srgb_lut.h" #define DCI_GAMMA 2.6 @@ -84,7 +83,7 @@ MonoPictureFrame::argb_frame (int reduce, float srgb_gamma) const { opj_image_t* xyz_frame = decompress_j2k (const_cast (_buffer->RoData()), _buffer->Size(), reduce); assert (xyz_frame->numcomps == 3); - shared_ptr f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma)); + shared_ptr f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma)); opj_image_destroy (xyz_frame); return f; } @@ -139,7 +138,7 @@ StereoPictureFrame::argb_frame (Eye eye, int reduce, float srgb_gamma) const } assert (xyz_frame->numcomps == 3); - shared_ptr f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), XYZsRGBLUT::cache.get (12, srgb_gamma)); + shared_ptr f = xyz_to_rgb (xyz_frame, GammaLUT::cache.get (12, DCI_GAMMA), GammaLUT::cache.get (12, 1 / srgb_gamma)); opj_image_destroy (xyz_frame); return f; } diff --git a/src/util.cc b/src/util.cc index 2fae8561..c66e63f5 100644 --- a/src/util.cc +++ b/src/util.cc @@ -35,7 +35,6 @@ #include "types.h" #include "argb_frame.h" #include "gamma_lut.h" -#include "xyz_srgb_lut.h" using std::string; using std::stringstream; @@ -203,11 +202,13 @@ libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) * @return RGB image. */ shared_ptr -libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, shared_ptr lut_out) +libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, shared_ptr lut_out) { float const dci_coefficient = 48.0 / 52.37; - /* sRGB color matrix for XYZ -> RGB */ + /* sRGB color matrix for XYZ -> RGB. This is the same as the one used by the Fraunhofer + EasyDCP player, I think. + */ float const colour_matrix[3][3] = { { 3.24096989631653, -1.5373831987381, -0.498610764741898 }, @@ -264,9 +265,9 @@ libdcp::xyz_to_rgb (opj_image_t* xyz_frame, shared_ptr lut_in, s d.b = max (d.b, 0.0); /* Out gamma LUT */ - *argb_line++ = lut_out->lut()[(int) (d.b * max_colour)]; - *argb_line++ = lut_out->lut()[(int) (d.g * max_colour)]; - *argb_line++ = lut_out->lut()[(int) (d.r * max_colour)]; + *argb_line++ = lut_out->lut()[(int) (d.b * max_colour)] * 0xff; + *argb_line++ = lut_out->lut()[(int) (d.g * max_colour)] * 0xff; + *argb_line++ = lut_out->lut()[(int) (d.r * max_colour)] * 0xff; *argb_line++ = 0xff; } diff --git a/src/util.h b/src/util.h index 2036a7ce..6332ddc0 100644 --- a/src/util.h +++ b/src/util.h @@ -60,7 +60,7 @@ extern std::string content_kind_to_string (ContentKind kind); extern ContentKind content_kind_from_string (std::string kind); extern bool empty_or_white_space (std::string s); extern opj_image_t* decompress_j2k (uint8_t* data, int64_t size, int reduce); -extern boost::shared_ptr xyz_to_rgb (opj_image_t* xyz_frame, boost::shared_ptr, boost::shared_ptr); +extern boost::shared_ptr xyz_to_rgb (opj_image_t* xyz_frame, boost::shared_ptr, boost::shared_ptr); } diff --git a/src/wscript b/src/wscript index efba2502..3960f2b0 100644 --- a/src/wscript +++ b/src/wscript @@ -31,7 +31,6 @@ def build(bld): util.cc version.cc xml.cc - xyz_srgb_lut.cc """ headers = """ diff --git a/src/xyz_srgb_lut.cc b/src/xyz_srgb_lut.cc deleted file mode 100644 index 3d207195..00000000 --- a/src/xyz_srgb_lut.cc +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include "xyz_srgb_lut.h" - -using namespace libdcp; - -LUTCache XYZsRGBLUT::cache; - -XYZsRGBLUT::XYZsRGBLUT(int bits, float gamma) - : LUT (bits, gamma) -{ - int const bit_length = pow(2, bits); - - for (int i = 0; i < bit_length; ++i) { - float v = float(i) / (bit_length - 1); - if (v < (0.04045 / 12.92)) { - v *= 12.92; - } else { - v = (1.055 * pow (v, (1 / gamma))) - 0.055; - } - - _lut[i] = int(v * 255); - } -} diff --git a/src/xyz_srgb_lut.h b/src/xyz_srgb_lut.h deleted file mode 100644 index 63f89178..00000000 --- a/src/xyz_srgb_lut.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "lut.h" -#include "lut_cache.h" - -namespace libdcp { - -class XYZsRGBLUT : public LUT -{ -public: - XYZsRGBLUT(int colour_depth, float gamma); - static LUTCache cache; -}; - -} -- cgit v1.2.3 From acf47ae643e54c09e94f7fc904207d7ea6a24c22 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 7 May 2013 23:03:51 +0100 Subject: Better error on JPEG2000 decode failure. --- src/util.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/util.cc') diff --git a/src/util.cc b/src/util.cc index c66e63f5..6bee0dc7 100644 --- a/src/util.cc +++ b/src/util.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "KM_util.h" #include "KM_fileio.h" @@ -41,6 +42,7 @@ using std::stringstream; using std::min; using std::max; using boost::shared_ptr; +using boost::lexical_cast; using namespace libdcp; /** Create a UUID. @@ -187,7 +189,7 @@ libdcp::decompress_j2k (uint8_t* data, int64_t size, int reduce) if (!image) { opj_destroy_decompress (decoder); opj_cio_close (cio); - boost::throw_exception (DCPReadError ("could not decode JPEG2000 codestream")); + boost::throw_exception (DCPReadError ("could not decode JPEG2000 codestream of " + lexical_cast (size) + " bytes.")); } opj_cio_close (cio); -- cgit v1.2.3