summaryrefslogtreecommitdiffstats
path: root/third_party/jpeg-xl/lib/jxl/quantizer-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/jpeg-xl/lib/jxl/quantizer-inl.h')
-rw-r--r--third_party/jpeg-xl/lib/jxl/quantizer-inl.h74
1 files changed, 74 insertions, 0 deletions
diff --git a/third_party/jpeg-xl/lib/jxl/quantizer-inl.h b/third_party/jpeg-xl/lib/jxl/quantizer-inl.h
new file mode 100644
index 0000000000..64d273c552
--- /dev/null
+++ b/third_party/jpeg-xl/lib/jxl/quantizer-inl.h
@@ -0,0 +1,74 @@
+// Copyright (c) the JPEG XL Project Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#if defined(LIB_JXL_QUANTIZER_INL_H_) == defined(HWY_TARGET_TOGGLE)
+#ifdef LIB_JXL_QUANTIZER_INL_H_
+#undef LIB_JXL_QUANTIZER_INL_H_
+#else
+#define LIB_JXL_QUANTIZER_INL_H_
+#endif
+
+#include <stddef.h>
+
+#include <hwy/highway.h>
+HWY_BEFORE_NAMESPACE();
+namespace jxl {
+namespace HWY_NAMESPACE {
+namespace {
+
+// These templates are not found via ADL.
+using hwy::HWY_NAMESPACE::And;
+using hwy::HWY_NAMESPACE::AndNot;
+using hwy::HWY_NAMESPACE::ApproximateReciprocal;
+using hwy::HWY_NAMESPACE::Gt;
+using hwy::HWY_NAMESPACE::IfThenElse;
+using hwy::HWY_NAMESPACE::IfThenElseZero;
+using hwy::HWY_NAMESPACE::Lt;
+using hwy::HWY_NAMESPACE::Rebind;
+using hwy::HWY_NAMESPACE::Vec;
+using hwy::HWY_NAMESPACE::Xor;
+
+template <class DI>
+HWY_INLINE HWY_MAYBE_UNUSED Vec<Rebind<float, DI>> AdjustQuantBias(
+ DI di, const size_t c, const Vec<DI> quant_i,
+ const float* HWY_RESTRICT biases) {
+ const Rebind<float, DI> df;
+
+ const auto quant = ConvertTo(df, quant_i);
+
+ // Compare |quant|, keep sign bit for negating result.
+ const auto kSign = BitCast(df, Set(di, INT32_MIN));
+ const auto sign = And(quant, kSign); // TODO(janwas): = abs ^ orig
+ const auto abs_quant = AndNot(kSign, quant);
+
+ // If |x| is 1, kZeroBias creates a different bias for each channel.
+ // We're implementing the following:
+ // if (quant == 0) return 0;
+ // if (quant == 1) return biases[c];
+ // if (quant == -1) return -biases[c];
+ // return quant - biases[3] / quant;
+
+ // Integer comparison is not helpful because Clang incurs bypass penalties
+ // from unnecessarily mixing integer and float.
+ const auto is_01 = Lt(abs_quant, Set(df, 1.125f));
+ const auto not_0 = Gt(abs_quant, Zero(df));
+
+ // Bitwise logic is faster than quant * biases[c].
+ const auto one_bias = IfThenElseZero(not_0, Xor(Set(df, biases[c]), sign));
+
+ // About 2E-5 worse than ReciprocalNR or division.
+ const auto bias =
+ NegMulAdd(Set(df, biases[3]), ApproximateReciprocal(quant), quant);
+
+ return IfThenElse(is_01, one_bias, bias);
+}
+
+} // namespace
+// NOLINTNEXTLINE(google-readability-namespace-comments)
+} // namespace HWY_NAMESPACE
+} // namespace jxl
+HWY_AFTER_NAMESPACE();
+
+#endif // LIB_JXL_QUANTIZER_INL_H_