From: Carl Hetherington Date: Sat, 21 Oct 2023 21:03:43 +0000 (+0200) Subject: Support integer LUTs. X-Git-Tag: v1.8.88~13 X-Git-Url: https://git.carlh.net/gitweb/?p=libdcp.git;a=commitdiff_plain;h=251f7a934525e0c846c95cc729664e95928e8aa5 Support integer LUTs. --- diff --git a/src/transfer_function.cc b/src/transfer_function.cc index be507af1..39c8db0a 100644 --- a/src/transfer_function.cc +++ b/src/transfer_function.cc @@ -53,23 +53,61 @@ vector const& TransferFunction::double_lut(double from, double to, int bit_depth, bool inverse) const { boost::mutex::scoped_lock lm (_mutex); + return double_lut_unlocked(from, to, bit_depth, inverse); +} + + +vector const& +TransferFunction::double_lut_unlocked(double from, double to, int bit_depth, bool inverse) const +{ + auto const descriptor = LUTDescriptor{from, to, bit_depth, inverse, 1}; + + auto i = _double_luts.find(descriptor); + if (i != _double_luts.end()) { + return i->second; + } + + _double_luts[descriptor] = make_double_lut(from, to, bit_depth, inverse); + return _double_luts[descriptor]; +} - auto const descriptor = LUTDescriptor{from, to, bit_depth, inverse}; - auto i = _luts.find(descriptor); - if (i != _luts.end()) { +vector const& +TransferFunction::int_lut(double from, double to, int bit_depth, bool inverse, int scale) const +{ + boost::mutex::scoped_lock lm (_mutex); + + auto const descriptor = LUTDescriptor{from, to, bit_depth, inverse, scale}; + + auto i = _int_luts.find(descriptor); + if (i != _int_luts.end()) { return i->second; } - _luts[descriptor] = make_double_lut(from, to, bit_depth, inverse); - return _luts[descriptor]; + _int_luts[descriptor] = make_int_lut(from, to, bit_depth, inverse, scale); + return _int_luts[descriptor]; +} + + +/* Caller must hold lock on _mutex */ +vector +TransferFunction::make_int_lut(double from, double to, int bit_depth, bool inverse, int scale) const +{ + auto source_lut = double_lut_unlocked(from, to, bit_depth, inverse); + auto const size = source_lut.size(); + vector lut(size); + for (size_t i = 0; i < size; ++i) { + lut[i] = lrint(source_lut[i] * scale); + } + + return lut; } bool TransferFunction::LUTDescriptor::operator==(TransferFunction::LUTDescriptor const& other) const { - return from == other.from && to == other.to && bit_depth == other.bit_depth && inverse == other.inverse; + return from == other.from && to == other.to && bit_depth == other.bit_depth && inverse == other.inverse && scale == other.scale; } @@ -79,6 +117,7 @@ TransferFunction::LUTDescriptorHasher::operator()(TransferFunction::LUTDescripto return std::hash()(desc.from) ^ std::hash()(desc.to) ^ std::hash()(desc.bit_depth) ^ - std::hash()(desc.inverse); + std::hash()(desc.inverse) ^ + std::hash()(desc.scale); } diff --git a/src/transfer_function.h b/src/transfer_function.h index 033c3045..2340ebfd 100644 --- a/src/transfer_function.h +++ b/src/transfer_function.h @@ -62,6 +62,7 @@ public: /** @return A look-up table (of size 2^bit_depth) */ std::vector const& double_lut(double from, double to, int bit_depth, bool inverse) const; + std::vector const& int_lut(double from, double to, int bit_depth, bool inverse, int scale) const; virtual bool about_equal (std::shared_ptr other, double epsilon) const = 0; @@ -69,11 +70,15 @@ protected: virtual std::vector make_double_lut(double from, double to, int bit_depth, bool inverse) const = 0; private: + std::vector make_int_lut(double from, double to, int bit_depth, bool inverse, int scale) const; + std::vector const& double_lut_unlocked(double from, double to, int bit_depth, bool inverse) const; + struct LUTDescriptor { double from; double to; int bit_depth; bool inverse; + int scale; bool operator==(LUTDescriptor const& other) const; }; @@ -82,8 +87,9 @@ private: std::size_t operator()(LUTDescriptor const& desc) const; }; - mutable std::unordered_map, LUTDescriptorHasher> _luts; - /** mutex to protect _luts */ + mutable std::unordered_map, LUTDescriptorHasher> _double_luts; + mutable std::unordered_map, LUTDescriptorHasher> _int_luts; + /** mutex to protect _double_luts and _int_luts */ mutable boost::mutex _mutex; };