summaryrefslogtreecommitdiffstats
path: root/third_party/jpeg-xl/lib/jxl/loop_filter.cc
blob: 5afe87617d3065044884e05273b97ce935965e31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// 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.

#include "lib/jxl/loop_filter.h"

#include "lib/jxl/base/status.h"
#include "lib/jxl/fields.h"

namespace jxl {

LoopFilter::LoopFilter() { Bundle::Init(this); }
Status LoopFilter::VisitFields(Visitor* JXL_RESTRICT visitor) {
  // Must come before AllDefault.

  if (visitor->AllDefault(*this, &all_default)) {
    // Overwrite all serialized fields, but not any nonserialized_*.
    visitor->SetDefault(this);
    return true;
  }

  JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(true, &gab));
  if (visitor->Conditional(gab)) {
    JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &gab_custom));
    if (visitor->Conditional(gab_custom)) {
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(1.1 * 0.104699568f, &gab_x_weight1));
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(1.1 * 0.055680538f, &gab_x_weight2));
      if (std::abs(1.0f + (gab_x_weight1 + gab_x_weight2) * 4) < 1e-8) {
        return JXL_FAILURE(
            "Gaborish x weights lead to near 0 unnormalized kernel");
      }
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(1.1 * 0.104699568f, &gab_y_weight1));
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(1.1 * 0.055680538f, &gab_y_weight2));
      if (std::abs(1.0f + (gab_y_weight1 + gab_y_weight2) * 4) < 1e-8) {
        return JXL_FAILURE(
            "Gaborish y weights lead to near 0 unnormalized kernel");
      }
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(1.1 * 0.104699568f, &gab_b_weight1));
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(1.1 * 0.055680538f, &gab_b_weight2));
      if (std::abs(1.0f + (gab_b_weight1 + gab_b_weight2) * 4) < 1e-8) {
        return JXL_FAILURE(
            "Gaborish b weights lead to near 0 unnormalized kernel");
      }
    }
  }

  JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(2, 2, &epf_iters));
  if (visitor->Conditional(epf_iters > 0)) {
    if (visitor->Conditional(!nonserialized_is_modular)) {
      JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &epf_sharp_custom));
      if (visitor->Conditional(epf_sharp_custom)) {
        for (size_t i = 0; i < kEpfSharpEntries; ++i) {
          JXL_QUIET_RETURN_IF_ERROR(visitor->F16(
              float(i) / float(kEpfSharpEntries - 1), &epf_sharp_lut[i]));
        }
      }
    }

    JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &epf_weight_custom));
    if (visitor->Conditional(epf_weight_custom)) {
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(40.0f, &epf_channel_scale[0]));
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(5.0f, &epf_channel_scale[1]));
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(3.5f, &epf_channel_scale[2]));
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(0.45f, &epf_pass1_zeroflush));
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(0.6f, &epf_pass2_zeroflush));
    }

    JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &epf_sigma_custom));
    if (visitor->Conditional(epf_sigma_custom)) {
      if (visitor->Conditional(!nonserialized_is_modular)) {
        JXL_QUIET_RETURN_IF_ERROR(visitor->F16(0.46f, &epf_quant_mul));
      }
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(0.9f, &epf_pass0_sigma_scale));
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(6.5f, &epf_pass2_sigma_scale));
      JXL_QUIET_RETURN_IF_ERROR(
          visitor->F16(0.6666666666666666f, &epf_border_sad_mul));
    }
    if (visitor->Conditional(nonserialized_is_modular)) {
      JXL_QUIET_RETURN_IF_ERROR(visitor->F16(1.0f, &epf_sigma_for_modular));
      if (epf_sigma_for_modular < 1e-8) {
        return JXL_FAILURE("EPF: sigma for modular is too small");
      }
    }
  }

  JXL_QUIET_RETURN_IF_ERROR(visitor->BeginExtensions(&extensions));
  // Extensions: in chronological order of being added to the format.
  return visitor->EndExtensions();
}

}  // namespace jxl