| /* |
| * Copyright 2026 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GainmapTestCommon_DEFINED |
| #define GainmapTestCommon_DEFINED |
| |
| #include "include/core/SkColor.h" |
| #include "include/private/SkGainmapInfo.h" |
| #include "tests/Test.h" |
| |
| #include <algorithm> |
| #include <cmath> |
| |
| namespace skiatest { |
| |
| // Return true if the relative difference between x and y is less than epsilon. |
| inline bool ApproxEq(float x, float y, float epsilon) { |
| float numerator = std::abs(x - y); |
| // To avoid being too sensitive around zero, set the minimum denominator to epsilon. |
| float denominator = std::max(std::min(std::abs(x), std::abs(y)), epsilon); |
| return (numerator / denominator) <= epsilon; |
| } |
| |
| inline bool ApproxEq(const SkColor4f& x, const SkColor4f& y, float epsilon) { |
| return ApproxEq(x.fR, y.fR, epsilon) && ApproxEq(x.fG, y.fG, epsilon) && |
| ApproxEq(x.fB, y.fB, epsilon); |
| } |
| |
| template <typename Reporter> |
| void ExpectApproxEqInfo(Reporter& r, const SkGainmapInfo& a, const SkGainmapInfo& b) { |
| float kEpsilon = 1e-4f; |
| REPORTER_ASSERT(r, ApproxEq(a.fGainmapRatioMin, b.fGainmapRatioMin, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a.fGainmapRatioMax, b.fGainmapRatioMax, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a.fGainmapGamma, b.fGainmapGamma, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a.fEpsilonSdr, b.fEpsilonSdr, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a.fEpsilonHdr, b.fEpsilonHdr, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a.fDisplayRatioSdr, b.fDisplayRatioSdr, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a.fDisplayRatioHdr, b.fDisplayRatioHdr, kEpsilon)); |
| REPORTER_ASSERT(r, a.fType == b.fType); |
| REPORTER_ASSERT(r, a.fBaseImageType == b.fBaseImageType); |
| |
| REPORTER_ASSERT(r, !!a.fGainmapMathColorSpace == !!b.fGainmapMathColorSpace); |
| if (a.fGainmapMathColorSpace && b.fGainmapMathColorSpace) { |
| skcms_TransferFunction a_fn; |
| skcms_Matrix3x3 a_m; |
| a.fGainmapMathColorSpace->transferFn(&a_fn); |
| a.fGainmapMathColorSpace->toXYZD50(&a_m); |
| skcms_TransferFunction b_fn; |
| skcms_Matrix3x3 b_m; |
| b.fGainmapMathColorSpace->transferFn(&b_fn); |
| b.fGainmapMathColorSpace->toXYZD50(&b_m); |
| |
| REPORTER_ASSERT(r, ApproxEq(a_fn.g, b_fn.g, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a_fn.a, b_fn.a, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a_fn.b, b_fn.b, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a_fn.c, b_fn.c, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a_fn.d, b_fn.d, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a_fn.e, b_fn.e, kEpsilon)); |
| REPORTER_ASSERT(r, ApproxEq(a_fn.f, b_fn.f, kEpsilon)); |
| |
| // The round-trip of the color space through the ICC profile loses significant precision. |
| // Use a larger epsilon for it. |
| const float kMatrixEpsilon = 1e-2f; |
| for (int i = 0; i < 3; ++i) { |
| for (int j = 0; j < 3; ++j) { |
| REPORTER_ASSERT(r, ApproxEq(a_m.vals[i][j], b_m.vals[i][j], kMatrixEpsilon)); |
| } |
| } |
| } |
| } |
| |
| } // namespace skiatest |
| |
| #endif // GainmapTestCommon_DEFINED |