Coverage Report

Created: 2026-09-28 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/quantizer-inl.h
Line
Count
Source
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
#include <cstddef>
7
#include <cstdint>
8
9
#if defined(LIB_JXL_QUANTIZER_INL_H_) == defined(HWY_TARGET_TOGGLE)
10
#ifdef LIB_JXL_QUANTIZER_INL_H_
11
#undef LIB_JXL_QUANTIZER_INL_H_
12
#else
13
#define LIB_JXL_QUANTIZER_INL_H_
14
#endif
15
16
#include <hwy/highway.h>
17
HWY_BEFORE_NAMESPACE();
18
namespace jxl {
19
namespace HWY_NAMESPACE {
20
namespace {
21
22
// These templates are not found via ADL.
23
using hwy::HWY_NAMESPACE::And;
24
using hwy::HWY_NAMESPACE::AndNot;
25
using hwy::HWY_NAMESPACE::ApproximateReciprocal;
26
using hwy::HWY_NAMESPACE::Gt;
27
using hwy::HWY_NAMESPACE::IfThenElse;
28
using hwy::HWY_NAMESPACE::IfThenElseZero;
29
using hwy::HWY_NAMESPACE::Lt;
30
using hwy::HWY_NAMESPACE::Rebind;
31
using hwy::HWY_NAMESPACE::Vec;
32
using hwy::HWY_NAMESPACE::Xor;
33
34
template <class DI>
35
HWY_INLINE HWY_MAYBE_UNUSED Vec<Rebind<float, DI>> AdjustQuantBias(
36
    DI di, const size_t c, const Vec<DI> quant_i,
37
448M
    const float* HWY_RESTRICT biases) {
38
448M
  const Rebind<float, DI> df;
39
40
448M
  const auto quant = ConvertTo(df, quant_i);
41
42
  // Compare |quant|, keep sign bit for negating result.
43
448M
  const auto kSign = BitCast(df, Set(di, INT32_MIN));
44
448M
  const auto sign = And(quant, kSign);  // TODO(janwas): = abs ^ orig
45
448M
  const auto abs_quant = AndNot(kSign, quant);
46
47
  // If |x| is 1, kZeroBias creates a different bias for each channel.
48
  // We're implementing the following:
49
  // if (quant == 0) return 0;
50
  // if (quant == 1) return biases[c];
51
  // if (quant == -1) return -biases[c];
52
  // return quant - biases[3] / quant;
53
54
  // Integer comparison is not helpful because Clang incurs bypass penalties
55
  // from unnecessarily mixing integer and float.
56
448M
  const auto is_01 = Lt(abs_quant, Set(df, 1.125f));
57
448M
  const auto not_0 = Gt(abs_quant, Zero(df));
58
59
  // Bitwise logic is faster than quant * biases[c].
60
448M
  const auto one_bias = IfThenElseZero(not_0, Xor(Set(df, biases[c]), sign));
61
62
  // About 2E-5 worse than ReciprocalNR or division.
63
448M
  const auto bias =
64
448M
      NegMulAdd(Set(df, biases[3]), ApproximateReciprocal(quant), quant);
65
66
448M
  return IfThenElse(is_01, one_bias, bias);
67
448M
}
Unexecuted instantiation: enc_group.cc:decltype (Zero((hwy::N_SSE4::Simd<int, 4ul, 0>::Rebind<float>)())) jxl::N_SSE4::(anonymous namespace)::AdjustQuantBias<hwy::N_SSE4::Simd<int, 4ul, 0> >(hwy::N_SSE4::Simd<int, 4ul, 0>, unsigned long, decltype (Zero((hwy::N_SSE4::Simd<int, 4ul, 0>)())), float const*)
enc_group.cc:decltype (Zero((hwy::N_AVX2::Simd<int, 8ul, 0>::Rebind<float>)())) jxl::N_AVX2::(anonymous namespace)::AdjustQuantBias<hwy::N_AVX2::Simd<int, 8ul, 0> >(hwy::N_AVX2::Simd<int, 8ul, 0>, unsigned long, decltype (Zero((hwy::N_AVX2::Simd<int, 8ul, 0>)())), float const*)
Line
Count
Source
37
43.4M
    const float* HWY_RESTRICT biases) {
38
43.4M
  const Rebind<float, DI> df;
39
40
43.4M
  const auto quant = ConvertTo(df, quant_i);
41
42
  // Compare |quant|, keep sign bit for negating result.
43
43.4M
  const auto kSign = BitCast(df, Set(di, INT32_MIN));
44
43.4M
  const auto sign = And(quant, kSign);  // TODO(janwas): = abs ^ orig
45
43.4M
  const auto abs_quant = AndNot(kSign, quant);
46
47
  // If |x| is 1, kZeroBias creates a different bias for each channel.
48
  // We're implementing the following:
49
  // if (quant == 0) return 0;
50
  // if (quant == 1) return biases[c];
51
  // if (quant == -1) return -biases[c];
52
  // return quant - biases[3] / quant;
53
54
  // Integer comparison is not helpful because Clang incurs bypass penalties
55
  // from unnecessarily mixing integer and float.
56
43.4M
  const auto is_01 = Lt(abs_quant, Set(df, 1.125f));
57
43.4M
  const auto not_0 = Gt(abs_quant, Zero(df));
58
59
  // Bitwise logic is faster than quant * biases[c].
60
43.4M
  const auto one_bias = IfThenElseZero(not_0, Xor(Set(df, biases[c]), sign));
61
62
  // About 2E-5 worse than ReciprocalNR or division.
63
43.4M
  const auto bias =
64
43.4M
      NegMulAdd(Set(df, biases[3]), ApproximateReciprocal(quant), quant);
65
66
43.4M
  return IfThenElse(is_01, one_bias, bias);
67
43.4M
}
Unexecuted instantiation: enc_group.cc:decltype (Zero((hwy::N_SSE2::Simd<int, 4ul, 0>::Rebind<float>)())) jxl::N_SSE2::(anonymous namespace)::AdjustQuantBias<hwy::N_SSE2::Simd<int, 4ul, 0> >(hwy::N_SSE2::Simd<int, 4ul, 0>, unsigned long, decltype (Zero((hwy::N_SSE2::Simd<int, 4ul, 0>)())), float const*)
Unexecuted instantiation: dec_group.cc:decltype (Zero((hwy::N_SSE4::Simd<int, 4ul, 0>::Rebind<float>)())) jxl::N_SSE4::(anonymous namespace)::AdjustQuantBias<hwy::N_SSE4::Simd<int, 4ul, 0> >(hwy::N_SSE4::Simd<int, 4ul, 0>, unsigned long, decltype (Zero((hwy::N_SSE4::Simd<int, 4ul, 0>)())), float const*)
dec_group.cc:decltype (Zero((hwy::N_AVX2::Simd<int, 8ul, 0>::Rebind<float>)())) jxl::N_AVX2::(anonymous namespace)::AdjustQuantBias<hwy::N_AVX2::Simd<int, 8ul, 0> >(hwy::N_AVX2::Simd<int, 8ul, 0>, unsigned long, decltype (Zero((hwy::N_AVX2::Simd<int, 8ul, 0>)())), float const*)
Line
Count
Source
37
404M
    const float* HWY_RESTRICT biases) {
38
404M
  const Rebind<float, DI> df;
39
40
404M
  const auto quant = ConvertTo(df, quant_i);
41
42
  // Compare |quant|, keep sign bit for negating result.
43
404M
  const auto kSign = BitCast(df, Set(di, INT32_MIN));
44
404M
  const auto sign = And(quant, kSign);  // TODO(janwas): = abs ^ orig
45
404M
  const auto abs_quant = AndNot(kSign, quant);
46
47
  // If |x| is 1, kZeroBias creates a different bias for each channel.
48
  // We're implementing the following:
49
  // if (quant == 0) return 0;
50
  // if (quant == 1) return biases[c];
51
  // if (quant == -1) return -biases[c];
52
  // return quant - biases[3] / quant;
53
54
  // Integer comparison is not helpful because Clang incurs bypass penalties
55
  // from unnecessarily mixing integer and float.
56
404M
  const auto is_01 = Lt(abs_quant, Set(df, 1.125f));
57
404M
  const auto not_0 = Gt(abs_quant, Zero(df));
58
59
  // Bitwise logic is faster than quant * biases[c].
60
404M
  const auto one_bias = IfThenElseZero(not_0, Xor(Set(df, biases[c]), sign));
61
62
  // About 2E-5 worse than ReciprocalNR or division.
63
404M
  const auto bias =
64
404M
      NegMulAdd(Set(df, biases[3]), ApproximateReciprocal(quant), quant);
65
66
404M
  return IfThenElse(is_01, one_bias, bias);
67
404M
}
Unexecuted instantiation: dec_group.cc:decltype (Zero((hwy::N_SSE2::Simd<int, 4ul, 0>::Rebind<float>)())) jxl::N_SSE2::(anonymous namespace)::AdjustQuantBias<hwy::N_SSE2::Simd<int, 4ul, 0> >(hwy::N_SSE2::Simd<int, 4ul, 0>, unsigned long, decltype (Zero((hwy::N_SSE2::Simd<int, 4ul, 0>)())), float const*)
68
69
}  // namespace
70
// NOLINTNEXTLINE(google-readability-namespace-comments)
71
}  // namespace HWY_NAMESPACE
72
}  // namespace jxl
73
HWY_AFTER_NAMESPACE();
74
75
#endif  // LIB_JXL_QUANTIZER_INL_H_