| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <cmath> | 5 #include <cmath> |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
| 9 #include "ui/gfx/color_space.h" | 9 #include "ui/gfx/color_space.h" |
| 10 #include "ui/gfx/skia_color_space_util.h" | 10 #include "ui/gfx/skia_color_space_util.h" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 CHECK(result); | 95 CHECK(result); |
| 96 color_space.GetInverseTransferFunction(&tr_fn_inv); | 96 color_space.GetInverseTransferFunction(&tr_fn_inv); |
| 97 | 97 |
| 98 std::vector<float> x; | 98 std::vector<float> x; |
| 99 std::vector<float> t; | 99 std::vector<float> t; |
| 100 for (float v = 0; v <= 1.f; v += 1.f / table_size) { | 100 for (float v = 0; v <= 1.f; v += 1.f / table_size) { |
| 101 x.push_back(v); | 101 x.push_back(v); |
| 102 t.push_back(SkTransferFnEval(tr_fn, v)); | 102 t.push_back(SkTransferFnEval(tr_fn, v)); |
| 103 } | 103 } |
| 104 | 104 |
| 105 bool converged = false; | |
| 106 float error = 0; | |
| 107 SkColorSpaceTransferFn fn_approx; | 105 SkColorSpaceTransferFn fn_approx; |
| 108 SkApproximateTransferFn(x.data(), t.data(), x.size(), &fn_approx, &error, | 106 bool converged = |
| 109 &converged); | 107 SkApproximateTransferFn(x.data(), t.data(), x.size(), &fn_approx); |
| 108 EXPECT_TRUE(converged); |
| 110 | 109 |
| 111 for (size_t i = 0; i < x.size(); ++i) { | 110 for (size_t i = 0; i < x.size(); ++i) { |
| 112 float fn_approx_of_x = SkTransferFnEval(fn_approx, x[i]); | 111 float fn_approx_of_x = SkTransferFnEval(fn_approx, x[i]); |
| 113 EXPECT_NEAR(t[i], fn_approx_of_x, 2.f / 256.f); | 112 EXPECT_NEAR(t[i], fn_approx_of_x, 2.f / 256.f); |
| 114 if (std::abs(t[i] - fn_approx_of_x) > 2.f / 256.f) | 113 if (std::abs(t[i] - fn_approx_of_x) > 2.f / 256.f) |
| 115 break; | 114 break; |
| 116 } | 115 } |
| 117 } | 116 } |
| 118 | 117 |
| 119 ColorSpace::TransferID all_transfers[] = { | 118 ColorSpace::TransferID all_transfers[] = { |
| 120 ColorSpace::TransferID::GAMMA22, ColorSpace::TransferID::GAMMA24, | 119 ColorSpace::TransferID::GAMMA22, ColorSpace::TransferID::GAMMA24, |
| 121 ColorSpace::TransferID::GAMMA28, ColorSpace::TransferID::BT709, | 120 ColorSpace::TransferID::GAMMA28, ColorSpace::TransferID::BT709, |
| 122 ColorSpace::TransferID::SMPTE240M, ColorSpace::TransferID::IEC61966_2_1, | 121 ColorSpace::TransferID::SMPTE240M, ColorSpace::TransferID::IEC61966_2_1, |
| 123 ColorSpace::TransferID::SMPTEST428_1, ColorSpace::TransferID::LINEAR}; | 122 ColorSpace::TransferID::LINEAR}; |
| 124 | 123 |
| 125 size_t all_table_sizes[] = {512, 256, 128, 64, 16, 11, 8, 7, 6, 5, 4}; | 124 size_t all_table_sizes[] = {512, 256, 128, 64, 16, 11, 8, 7, 6, 5, 4}; |
| 126 | 125 |
| 127 INSTANTIATE_TEST_CASE_P(A, | 126 INSTANTIATE_TEST_CASE_P(A, |
| 128 ColorSpaceTableTest, | 127 ColorSpaceTableTest, |
| 129 testing::Combine(testing::ValuesIn(all_transfers), | 128 testing::Combine(testing::ValuesIn(all_transfers), |
| 130 testing::ValuesIn(all_table_sizes))); | 129 testing::ValuesIn(all_table_sizes))); |
| 131 | 130 |
| 131 TEST(ColorSpace, ApproximateTransferFnBadMatch) { |
| 132 const float kStep = 1.f / 512.f; |
| 133 ColorSpace::TransferID transfer_ids[3] = { |
| 134 ColorSpace::TransferID::IEC61966_2_1, ColorSpace::TransferID::GAMMA22, |
| 135 ColorSpace::TransferID::BT709, |
| 136 }; |
| 137 gfx::ColorSpace color_spaces[3]; |
| 138 |
| 139 // The first iteration will have a perfect match. The second will be very |
| 140 // close. The third will converge, but with an error of ~7/256. |
| 141 for (size_t transfers_to_use = 1; transfers_to_use <= 3; ++transfers_to_use) { |
| 142 std::vector<float> x; |
| 143 std::vector<float> t; |
| 144 for (size_t c = 0; c < transfers_to_use; ++c) { |
| 145 color_spaces[c] = |
| 146 gfx::ColorSpace(ColorSpace::PrimaryID::BT709, transfer_ids[c]); |
| 147 SkColorSpaceTransferFn tr_fn; |
| 148 bool result = color_spaces[c].GetTransferFunction(&tr_fn); |
| 149 CHECK(result); |
| 150 |
| 151 for (float v = 0; v <= 1.f; v += kStep) { |
| 152 x.push_back(v); |
| 153 t.push_back(SkTransferFnEval(tr_fn, v)); |
| 154 } |
| 155 } |
| 156 |
| 157 SkColorSpaceTransferFn fn_approx; |
| 158 bool converged = |
| 159 SkApproximateTransferFn(x.data(), t.data(), x.size(), &fn_approx); |
| 160 EXPECT_TRUE(converged); |
| 161 |
| 162 float expected_error = 1.5f / 256.f; |
| 163 if (transfers_to_use == 3) |
| 164 expected_error = 8.f / 256.f; |
| 165 |
| 166 for (size_t i = 0; i < x.size(); ++i) { |
| 167 float fn_approx_of_x = SkTransferFnEval(fn_approx, x[i]); |
| 168 EXPECT_NEAR(t[i], fn_approx_of_x, expected_error); |
| 169 if (std::abs(t[i] - fn_approx_of_x) > expected_error) |
| 170 break; |
| 171 } |
| 172 } |
| 173 } |
| 174 |
| 132 } // namespace | 175 } // namespace |
| 133 } // namespace gfx | 176 } // namespace gfx |
| OLD | NEW |