libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

quantizer-inl.h (2354B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #if defined(LIB_JXL_QUANTIZER_INL_H_) == defined(HWY_TARGET_TOGGLE)
      7 #ifdef LIB_JXL_QUANTIZER_INL_H_
      8 #undef LIB_JXL_QUANTIZER_INL_H_
      9 #else
     10 #define LIB_JXL_QUANTIZER_INL_H_
     11 #endif
     12 
     13 #include <stddef.h>
     14 
     15 #include <hwy/highway.h>
     16 HWY_BEFORE_NAMESPACE();
     17 namespace jxl {
     18 namespace HWY_NAMESPACE {
     19 namespace {
     20 
     21 // These templates are not found via ADL.
     22 using hwy::HWY_NAMESPACE::And;
     23 using hwy::HWY_NAMESPACE::AndNot;
     24 using hwy::HWY_NAMESPACE::ApproximateReciprocal;
     25 using hwy::HWY_NAMESPACE::Gt;
     26 using hwy::HWY_NAMESPACE::IfThenElse;
     27 using hwy::HWY_NAMESPACE::IfThenElseZero;
     28 using hwy::HWY_NAMESPACE::Lt;
     29 using hwy::HWY_NAMESPACE::Rebind;
     30 using hwy::HWY_NAMESPACE::Vec;
     31 using hwy::HWY_NAMESPACE::Xor;
     32 
     33 template <class DI>
     34 HWY_INLINE HWY_MAYBE_UNUSED Vec<Rebind<float, DI>> AdjustQuantBias(
     35     DI di, const size_t c, const Vec<DI> quant_i,
     36     const float* HWY_RESTRICT biases) {
     37   const Rebind<float, DI> df;
     38 
     39   const auto quant = ConvertTo(df, quant_i);
     40 
     41   // Compare |quant|, keep sign bit for negating result.
     42   const auto kSign = BitCast(df, Set(di, INT32_MIN));
     43   const auto sign = And(quant, kSign);  // TODO(janwas): = abs ^ orig
     44   const auto abs_quant = AndNot(kSign, quant);
     45 
     46   // If |x| is 1, kZeroBias creates a different bias for each channel.
     47   // We're implementing the following:
     48   // if (quant == 0) return 0;
     49   // if (quant == 1) return biases[c];
     50   // if (quant == -1) return -biases[c];
     51   // return quant - biases[3] / quant;
     52 
     53   // Integer comparison is not helpful because Clang incurs bypass penalties
     54   // from unnecessarily mixing integer and float.
     55   const auto is_01 = Lt(abs_quant, Set(df, 1.125f));
     56   const auto not_0 = Gt(abs_quant, Zero(df));
     57 
     58   // Bitwise logic is faster than quant * biases[c].
     59   const auto one_bias = IfThenElseZero(not_0, Xor(Set(df, biases[c]), sign));
     60 
     61   // About 2E-5 worse than ReciprocalNR or division.
     62   const auto bias =
     63       NegMulAdd(Set(df, biases[3]), ApproximateReciprocal(quant), quant);
     64 
     65   return IfThenElse(is_01, one_bias, bias);
     66 }
     67 
     68 }  // namespace
     69 // NOLINTNEXTLINE(google-readability-namespace-comments)
     70 }  // namespace HWY_NAMESPACE
     71 }  // namespace jxl
     72 HWY_AFTER_NAMESPACE();
     73 
     74 #endif  // LIB_JXL_QUANTIZER_INL_H_