libjxl

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

tone_mapping_test.cc (5511B)


      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 #undef HWY_TARGET_INCLUDE
      7 #define HWY_TARGET_INCLUDE "lib/jxl/cms/tone_mapping_test.cc"
      8 #include "lib/jxl/cms/tone_mapping.h"
      9 
     10 #include <cstdio>
     11 #include <hwy/foreach_target.h>
     12 
     13 #include "lib/jxl/base/random.h"
     14 #include "lib/jxl/cms/tone_mapping-inl.h"
     15 #include "lib/jxl/testing.h"
     16 
     17 // Test utils
     18 #include <hwy/highway.h>
     19 #include <hwy/tests/hwy_gtest.h>
     20 HWY_BEFORE_NAMESPACE();
     21 namespace jxl {
     22 namespace HWY_NAMESPACE {
     23 namespace {
     24 
     25 HWY_NOINLINE void TestRec2408ToneMap() {
     26   constexpr size_t kNumTrials = 1 << 23;
     27   Rng rng(1);
     28   float max_abs_err = 0;
     29   HWY_FULL(float) d;
     30   for (size_t i = 0; i < kNumTrials; i++) {
     31     float src = 11000.0 + rng.UniformF(-150.0f, 150.0f);
     32     float tgt = 250 + rng.UniformF(-5.0f, 5.0f);
     33     float luminances[3] = {rng.UniformF(0.2f, 0.4f), rng.UniformF(0.2f, 0.4f),
     34                            rng.UniformF(0.2f, 0.4f)};
     35     float rgb[3] = {rng.UniformF(0.0f, 1.0f), rng.UniformF(0.0f, 1.0f),
     36                     rng.UniformF(0.0f, 1.0f)};
     37     Rec2408ToneMapper<decltype(d)> tone_mapper({0, src}, {0, tgt}, luminances);
     38     auto r = Set(d, rgb[0]);
     39     auto g = Set(d, rgb[1]);
     40     auto b = Set(d, rgb[2]);
     41     tone_mapper.ToneMap(&r, &g, &b);
     42     Rec2408ToneMapperBase tone_mapper_base({0, src}, {0, tgt}, luminances);
     43     tone_mapper_base.ToneMap(&rgb[0], &rgb[1], &rgb[2]);
     44     const float actual_r = GetLane(r);
     45     const float expected_r = rgb[0];
     46     const float abs_err_r = std::abs(expected_r - actual_r);
     47     EXPECT_LT(abs_err_r, 2.75e-5);
     48     const float actual_g = GetLane(g);
     49     const float expected_g = rgb[1];
     50     const float abs_err_g = std::abs(expected_g - actual_g);
     51     EXPECT_LT(abs_err_g, 2.75e-5);
     52     const float actual_b = GetLane(b);
     53     const float expected_b = rgb[2];
     54     const float abs_err_b = std::abs(expected_b - actual_b);
     55     EXPECT_LT(abs_err_b, 2.75e-5);
     56     max_abs_err = std::max({max_abs_err, abs_err_r, abs_err_g, abs_err_b});
     57   }
     58   printf("max abs err %e\n", static_cast<double>(max_abs_err));
     59 }
     60 
     61 HWY_NOINLINE void TestHlgOotfApply() {
     62   constexpr size_t kNumTrials = 1 << 23;
     63   Rng rng(1);
     64   float max_abs_err = 0;
     65   HWY_FULL(float) d;
     66   for (size_t i = 0; i < kNumTrials; i++) {
     67     float src = 300.0 + rng.UniformF(-50.0f, 50.0f);
     68     float tgt = 80 + rng.UniformF(-5.0f, 5.0f);
     69     float luminances[3] = {rng.UniformF(0.2f, 0.4f), rng.UniformF(0.2f, 0.4f),
     70                            rng.UniformF(0.2f, 0.4f)};
     71     float rgb[3] = {rng.UniformF(0.0f, 1.0f), rng.UniformF(0.0f, 1.0f),
     72                     rng.UniformF(0.0f, 1.0f)};
     73     HlgOOTF ootf(src, tgt, luminances);
     74     auto r = Set(d, rgb[0]);
     75     auto g = Set(d, rgb[1]);
     76     auto b = Set(d, rgb[2]);
     77     ootf.Apply(&r, &g, &b);
     78     HlgOOTF_Base ootf_base(src, tgt, luminances);
     79     ootf_base.Apply(&rgb[0], &rgb[1], &rgb[2]);
     80     const float actual_r = GetLane(r);
     81     const float expected_r = rgb[0];
     82     const float abs_err_r = std::abs(expected_r - actual_r);
     83     EXPECT_LT(abs_err_r, 7.2e-7);
     84     const float actual_g = GetLane(g);
     85     const float expected_g = rgb[1];
     86     const float abs_err_g = std::abs(expected_g - actual_g);
     87     EXPECT_LT(abs_err_g, 7.2e-7);
     88     const float actual_b = GetLane(b);
     89     const float expected_b = rgb[2];
     90     const float abs_err_b = std::abs(expected_b - actual_b);
     91     EXPECT_LT(abs_err_b, 7.2e-7);
     92     max_abs_err = std::max({max_abs_err, abs_err_r, abs_err_g, abs_err_b});
     93   }
     94   printf("max abs err %e\n", static_cast<double>(max_abs_err));
     95 }
     96 
     97 HWY_NOINLINE void TestGamutMap() {
     98   constexpr size_t kNumTrials = 1 << 23;
     99   Rng rng(1);
    100   float max_abs_err = 0;
    101   HWY_FULL(float) d;
    102   for (size_t i = 0; i < kNumTrials; i++) {
    103     float preserve_saturation = rng.UniformF(0.2f, 0.4f);
    104     float luminances[3] = {rng.UniformF(0.2f, 0.4f), rng.UniformF(0.2f, 0.4f),
    105                            rng.UniformF(0.2f, 0.4f)};
    106     float rgb[3] = {rng.UniformF(0.0f, 1.0f), rng.UniformF(0.0f, 1.0f),
    107                     rng.UniformF(0.0f, 1.0f)};
    108     auto r = Set(d, rgb[0]);
    109     auto g = Set(d, rgb[1]);
    110     auto b = Set(d, rgb[2]);
    111     GamutMap(&r, &g, &b, luminances, preserve_saturation);
    112     GamutMapScalar(&rgb[0], &rgb[1], &rgb[2], luminances, preserve_saturation);
    113     const float actual_r = GetLane(r);
    114     const float expected_r = rgb[0];
    115     const float abs_err_r = std::abs(expected_r - actual_r);
    116     EXPECT_LT(abs_err_r, 1e-10);
    117     const float actual_g = GetLane(g);
    118     const float expected_g = rgb[1];
    119     const float abs_err_g = std::abs(expected_g - actual_g);
    120     EXPECT_LT(abs_err_g, 1e-10);
    121     const float actual_b = GetLane(b);
    122     const float expected_b = rgb[2];
    123     const float abs_err_b = std::abs(expected_b - actual_b);
    124     EXPECT_LT(abs_err_b, 1e-10);
    125     max_abs_err = std::max({max_abs_err, abs_err_r, abs_err_g, abs_err_b});
    126   }
    127   printf("max abs err %e\n", static_cast<double>(max_abs_err));
    128 }
    129 
    130 }  // namespace
    131 // NOLINTNEXTLINE(google-readability-namespace-comments)
    132 }  // namespace HWY_NAMESPACE
    133 }  // namespace jxl
    134 HWY_AFTER_NAMESPACE();
    135 
    136 #if HWY_ONCE
    137 namespace jxl {
    138 
    139 class ToneMappingTargetTest : public hwy::TestWithParamTarget {};
    140 HWY_TARGET_INSTANTIATE_TEST_SUITE_P(ToneMappingTargetTest);
    141 
    142 HWY_EXPORT_AND_TEST_P(ToneMappingTargetTest, TestRec2408ToneMap);
    143 HWY_EXPORT_AND_TEST_P(ToneMappingTargetTest, TestHlgOotfApply);
    144 HWY_EXPORT_AND_TEST_P(ToneMappingTargetTest, TestGamutMap);
    145 
    146 }  // namespace jxl
    147 #endif  // HWY_ONCE