summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-06-02 16:47:56 +0200
committerCarl Hetherington <cth@carlh.net>2020-06-02 16:47:56 +0200
commite2b0092be00ebcb129a7f75230f76f52901b07b1 (patch)
tree7da551c580c24bc1aa9433ab6b8ba6fdcbfee1ee /src
parentf2d6161203f8b5c50b021dbe65a9109ea1577fd7 (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.cc8
-rw-r--r--src/transfer_function.cc34
-rw-r--r--src/transfer_function.h32
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;
};