diff options
| author | Carl Hetherington <cth@carlh.net> | 2020-06-02 16:47:56 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2020-06-02 16:47:56 +0200 |
| commit | e2b0092be00ebcb129a7f75230f76f52901b07b1 (patch) | |
| tree | 7da551c580c24bc1aa9433ab6b8ba6fdcbfee1ee /src | |
| parent | f2d6161203f8b5c50b021dbe65a9109ea1577fd7 (diff) | |
Use an integer LUT for the rgb->xyz output instead of doing
multiplies and rounding in the loop.
Diffstat (limited to 'src')
| -rw-r--r-- | src/rgb_xyz.cc | 8 | ||||
| -rw-r--r-- | src/transfer_function.cc | 34 | ||||
| -rw-r--r-- | src/transfer_function.h | 32 |
3 files changed, 67 insertions, 7 deletions
diff --git a/src/rgb_xyz.cc b/src/rgb_xyz.cc index 77b61416..36185324 100644 --- a/src/rgb_xyz.cc +++ b/src/rgb_xyz.cc @@ -297,7 +297,7 @@ dcp::rgb_to_xyz ( } d; double const * lut_in = conversion.in()->lut (12, false); - double const * lut_out = conversion.out()->lut (16, true); + int const * lut_out = conversion.out()->lut_int (16, true, 4095); /* This is is the product of the RGB to XYZ matrix, the Bradford transform and the DCI companding */ double fast_matrix[9]; @@ -329,9 +329,9 @@ dcp::rgb_to_xyz ( d.z = min (65535.0, d.z); /* Out gamma LUT */ - *xyz_x++ = lrint (lut_out[lrint(d.x)] * 4095); - *xyz_y++ = lrint (lut_out[lrint(d.y)] * 4095); - *xyz_z++ = lrint (lut_out[lrint(d.z)] * 4095); + *xyz_x++ = lut_out[lrint(d.x)]; + *xyz_y++ = lut_out[lrint(d.y)]; + *xyz_z++ = lut_out[lrint(d.z)]; } } diff --git a/src/transfer_function.cc b/src/transfer_function.cc index ea71818e..0dfdb338 100644 --- a/src/transfer_function.cc +++ b/src/transfer_function.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2020 Carl Hetherington <cth@carlh.net> This file is part of libdcp. @@ -56,7 +56,13 @@ double const * TransferFunction::lut (int bit_depth, bool inverse) const { boost::mutex::scoped_lock lm (_mutex); + return lut_unlocked (bit_depth, inverse); +} + +double const * +TransferFunction::lut_unlocked (int bit_depth, bool inverse) const +{ map<pair<int, bool>, double*>::const_iterator i = _luts.find (make_pair (bit_depth, inverse)); if (i != _luts.end ()) { return i->second; @@ -65,3 +71,29 @@ TransferFunction::lut (int bit_depth, bool inverse) const _luts[make_pair(bit_depth, inverse)] = make_lut (bit_depth, inverse); return _luts[make_pair(bit_depth, inverse)]; } + + +int const * +TransferFunction::lut_int (int bit_depth, bool inverse, int multiplier) const +{ + IntDescription desc (bit_depth, inverse, multiplier); + + boost::mutex::scoped_lock lm (_mutex); + + map<IntDescription, int*>::const_iterator i = _luts_int.find (desc); + if (i != _luts_int.end()) { + return i->second; + } + + double const* lut_double = lut_unlocked (bit_depth, inverse); + + int size = lrint(pow(2.0f, bit_depth)); + int* lut_int = new int[size]; + for (int i = 0; i < size; ++i) { + lut_int[i] = lrint (lut_double[i] * multiplier); + } + + _luts_int[desc] = lut_int; + return lut_int; +} + diff --git a/src/transfer_function.h b/src/transfer_function.h index 8facf8a4..9d35b281 100644 --- a/src/transfer_function.h +++ b/src/transfer_function.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2020 Carl Hetherington <cth@carlh.net> This file is part of libdcp. @@ -55,6 +55,7 @@ public: /** @return A look-up table (of size 2^bit_depth) whose values range from 0 to 1 */ double const * lut (int bit_depth, bool inverse) const; + int const * lut_int (int bit_depth, bool inverse, int multiplier) const; virtual bool about_equal (boost::shared_ptr<const TransferFunction> other, double epsilon) const = 0; @@ -63,8 +64,35 @@ protected: virtual double * make_lut (int bit_depth, bool inverse) const = 0; private: + double const * lut_unlocked (int bit_depth, bool inverse) const; + mutable std::map<std::pair<int, bool>, double*> _luts; - /** mutex to protect _luts */ + + struct IntDescription { + IntDescription (int bit_depth_, bool inverse_, int multipler_) + : bit_depth (bit_depth_) + , inverse (inverse_) + , multiplier (multipler_) + {} + + int bit_depth; + bool inverse; + int multiplier; + + bool operator< (IntDescription const& other) const { + if (bit_depth != other.bit_depth) { + return bit_depth < other.bit_depth; + } + if (inverse != other.inverse) { + return inverse; + } + return multiplier < other.multiplier; + } + }; + + mutable std::map<IntDescription, int*> _luts_int; + + /** mutex to protect _luts* */ mutable boost::mutex _mutex; }; |
