| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2022 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <cmath> | 
|  | 18 | #include <gtest/gtest.h> | 
|  | 19 | #include <gmock/gmock.h> | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 20 | #include <ultrahdr/gainmapmath.h> | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 21 |  | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 22 | namespace android::ultrahdr { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 23 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 24 | class GainMapMathTest : public testing::Test { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 25 | public: | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 26 | GainMapMathTest(); | 
|  | 27 | ~GainMapMathTest(); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 28 |  | 
|  | 29 | float ComparisonEpsilon() { return 1e-4f; } | 
|  | 30 | float LuminanceEpsilon() { return 1e-2f; } | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 31 | float YuvConversionEpsilon() { return 1.0f / (255.0f * 2.0f); } | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 32 |  | 
|  | 33 | Color Yuv420(uint8_t y, uint8_t u, uint8_t v) { | 
|  | 34 | return {{{ static_cast<float>(y) / 255.0f, | 
|  | 35 | (static_cast<float>(u) - 128.0f) / 255.0f, | 
|  | 36 | (static_cast<float>(v) - 128.0f) / 255.0f }}}; | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | Color P010(uint16_t y, uint16_t u, uint16_t v) { | 
| Nick Deakin | 3812533 | 2022-12-12 15:48:24 -0500 | [diff] [blame] | 40 | return {{{ (static_cast<float>(y) - 64.0f) / 876.0f, | 
|  | 41 | (static_cast<float>(u) - 64.0f) / 896.0f - 0.5f, | 
|  | 42 | (static_cast<float>(v) - 64.0f) / 896.0f - 0.5f }}}; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 43 | } | 
|  | 44 |  | 
|  | 45 | float Map(uint8_t e) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 46 | return static_cast<float>(e) / 255.0f; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 47 | } | 
|  | 48 |  | 
|  | 49 | Color ColorMin(Color e1, Color e2) { | 
|  | 50 | return {{{ fmin(e1.r, e2.r), fmin(e1.g, e2.g), fmin(e1.b, e2.b) }}}; | 
|  | 51 | } | 
|  | 52 |  | 
|  | 53 | Color ColorMax(Color e1, Color e2) { | 
|  | 54 | return {{{ fmax(e1.r, e2.r), fmax(e1.g, e2.g), fmax(e1.b, e2.b) }}}; | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | Color RgbBlack() { return {{{ 0.0f, 0.0f, 0.0f }}}; } | 
|  | 58 | Color RgbWhite() { return {{{ 1.0f, 1.0f, 1.0f }}}; } | 
|  | 59 |  | 
|  | 60 | Color RgbRed() { return {{{ 1.0f, 0.0f, 0.0f }}}; } | 
|  | 61 | Color RgbGreen() { return {{{ 0.0f, 1.0f, 0.0f }}}; } | 
|  | 62 | Color RgbBlue() { return {{{ 0.0f, 0.0f, 1.0f }}}; } | 
|  | 63 |  | 
|  | 64 | Color YuvBlack() { return {{{ 0.0f, 0.0f, 0.0f }}}; } | 
|  | 65 | Color YuvWhite() { return {{{ 1.0f, 0.0f, 0.0f }}}; } | 
|  | 66 |  | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 67 | Color SrgbYuvRed() { return {{{ 0.2126f, -0.11457f, 0.5f }}}; } | 
|  | 68 | Color SrgbYuvGreen() { return {{{ 0.7152f, -0.38543f, -0.45415f }}}; } | 
|  | 69 | Color SrgbYuvBlue() { return {{{ 0.0722f, 0.5f, -0.04585f }}}; } | 
|  | 70 |  | 
|  | 71 | Color P3YuvRed() { return {{{ 0.299f, -0.16874f, 0.5f }}}; } | 
|  | 72 | Color P3YuvGreen() { return {{{ 0.587f, -0.33126f, -0.41869f }}}; } | 
|  | 73 | Color P3YuvBlue() { return {{{ 0.114f, 0.5f, -0.08131f }}}; } | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 74 |  | 
|  | 75 | Color Bt2100YuvRed() { return {{{ 0.2627f, -0.13963f, 0.5f }}}; } | 
|  | 76 | Color Bt2100YuvGreen() { return {{{ 0.6780f, -0.36037f, -0.45979f }}}; } | 
|  | 77 | Color Bt2100YuvBlue() { return {{{ 0.0593f, 0.5f, -0.04021f }}}; } | 
|  | 78 |  | 
|  | 79 | float SrgbYuvToLuminance(Color yuv_gamma, ColorCalculationFn luminanceFn) { | 
|  | 80 | Color rgb_gamma = srgbYuvToRgb(yuv_gamma); | 
|  | 81 | Color rgb = srgbInvOetf(rgb_gamma); | 
|  | 82 | float luminance_scaled = luminanceFn(rgb); | 
|  | 83 | return luminance_scaled * kSdrWhiteNits; | 
|  | 84 | } | 
|  | 85 |  | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 86 | float P3YuvToLuminance(Color yuv_gamma, ColorCalculationFn luminanceFn) { | 
|  | 87 | Color rgb_gamma = p3YuvToRgb(yuv_gamma); | 
|  | 88 | Color rgb = srgbInvOetf(rgb_gamma); | 
|  | 89 | float luminance_scaled = luminanceFn(rgb); | 
|  | 90 | return luminance_scaled * kSdrWhiteNits; | 
|  | 91 | } | 
|  | 92 |  | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 93 | float Bt2100YuvToLuminance(Color yuv_gamma, ColorTransformFn hdrInvOetf, | 
|  | 94 | ColorTransformFn gamutConversionFn, ColorCalculationFn luminanceFn, | 
|  | 95 | float scale_factor) { | 
|  | 96 | Color rgb_gamma = bt2100YuvToRgb(yuv_gamma); | 
|  | 97 | Color rgb = hdrInvOetf(rgb_gamma); | 
|  | 98 | rgb = gamutConversionFn(rgb); | 
|  | 99 | float luminance_scaled = luminanceFn(rgb); | 
|  | 100 | return luminance_scaled * scale_factor; | 
|  | 101 | } | 
|  | 102 |  | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 103 | Color Recover(Color yuv_gamma, float gain, ultrahdr_metadata_ptr metadata) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 104 | Color rgb_gamma = srgbYuvToRgb(yuv_gamma); | 
|  | 105 | Color rgb = srgbInvOetf(rgb_gamma); | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 106 | return applyGain(rgb, gain, metadata); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 107 | } | 
|  | 108 |  | 
|  | 109 | jpegr_uncompressed_struct Yuv420Image() { | 
|  | 110 | static uint8_t pixels[] = { | 
|  | 111 | // Y | 
|  | 112 | 0x00, 0x10, 0x20, 0x30, | 
|  | 113 | 0x01, 0x11, 0x21, 0x31, | 
|  | 114 | 0x02, 0x12, 0x22, 0x32, | 
|  | 115 | 0x03, 0x13, 0x23, 0x33, | 
|  | 116 | // U | 
|  | 117 | 0xA0, 0xA1, | 
|  | 118 | 0xA2, 0xA3, | 
|  | 119 | // V | 
|  | 120 | 0xB0, 0xB1, | 
|  | 121 | 0xB2, 0xB3, | 
|  | 122 | }; | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 123 | return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_BT709 }; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 124 | } | 
|  | 125 |  | 
|  | 126 | Color (*Yuv420Colors())[4] { | 
|  | 127 | static Color colors[4][4] = { | 
|  | 128 | { | 
|  | 129 | Yuv420(0x00, 0xA0, 0xB0), Yuv420(0x10, 0xA0, 0xB0), | 
|  | 130 | Yuv420(0x20, 0xA1, 0xB1), Yuv420(0x30, 0xA1, 0xB1), | 
|  | 131 | }, { | 
|  | 132 | Yuv420(0x01, 0xA0, 0xB0), Yuv420(0x11, 0xA0, 0xB0), | 
|  | 133 | Yuv420(0x21, 0xA1, 0xB1), Yuv420(0x31, 0xA1, 0xB1), | 
|  | 134 | }, { | 
|  | 135 | Yuv420(0x02, 0xA2, 0xB2), Yuv420(0x12, 0xA2, 0xB2), | 
|  | 136 | Yuv420(0x22, 0xA3, 0xB3), Yuv420(0x32, 0xA3, 0xB3), | 
|  | 137 | }, { | 
|  | 138 | Yuv420(0x03, 0xA2, 0xB2), Yuv420(0x13, 0xA2, 0xB2), | 
|  | 139 | Yuv420(0x23, 0xA3, 0xB3), Yuv420(0x33, 0xA3, 0xB3), | 
|  | 140 | }, | 
|  | 141 | }; | 
|  | 142 | return colors; | 
|  | 143 | } | 
|  | 144 |  | 
|  | 145 | jpegr_uncompressed_struct P010Image() { | 
|  | 146 | static uint16_t pixels[] = { | 
|  | 147 | // Y | 
|  | 148 | 0x00 << 6, 0x10 << 6, 0x20 << 6, 0x30 << 6, | 
|  | 149 | 0x01 << 6, 0x11 << 6, 0x21 << 6, 0x31 << 6, | 
|  | 150 | 0x02 << 6, 0x12 << 6, 0x22 << 6, 0x32 << 6, | 
|  | 151 | 0x03 << 6, 0x13 << 6, 0x23 << 6, 0x33 << 6, | 
|  | 152 | // UV | 
|  | 153 | 0xA0 << 6, 0xB0 << 6, 0xA1 << 6, 0xB1 << 6, | 
|  | 154 | 0xA2 << 6, 0xB2 << 6, 0xA3 << 6, 0xB3 << 6, | 
|  | 155 | }; | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 156 | return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_BT709 }; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 157 | } | 
|  | 158 |  | 
|  | 159 | Color (*P010Colors())[4] { | 
|  | 160 | static Color colors[4][4] = { | 
|  | 161 | { | 
|  | 162 | P010(0x00, 0xA0, 0xB0), P010(0x10, 0xA0, 0xB0), | 
|  | 163 | P010(0x20, 0xA1, 0xB1), P010(0x30, 0xA1, 0xB1), | 
|  | 164 | }, { | 
|  | 165 | P010(0x01, 0xA0, 0xB0), P010(0x11, 0xA0, 0xB0), | 
|  | 166 | P010(0x21, 0xA1, 0xB1), P010(0x31, 0xA1, 0xB1), | 
|  | 167 | }, { | 
|  | 168 | P010(0x02, 0xA2, 0xB2), P010(0x12, 0xA2, 0xB2), | 
|  | 169 | P010(0x22, 0xA3, 0xB3), P010(0x32, 0xA3, 0xB3), | 
|  | 170 | }, { | 
|  | 171 | P010(0x03, 0xA2, 0xB2), P010(0x13, 0xA2, 0xB2), | 
|  | 172 | P010(0x23, 0xA3, 0xB3), P010(0x33, 0xA3, 0xB3), | 
|  | 173 | }, | 
|  | 174 | }; | 
|  | 175 | return colors; | 
|  | 176 | } | 
|  | 177 |  | 
|  | 178 | jpegr_uncompressed_struct MapImage() { | 
|  | 179 | static uint8_t pixels[] = { | 
|  | 180 | 0x00, 0x10, 0x20, 0x30, | 
|  | 181 | 0x01, 0x11, 0x21, 0x31, | 
|  | 182 | 0x02, 0x12, 0x22, 0x32, | 
|  | 183 | 0x03, 0x13, 0x23, 0x33, | 
|  | 184 | }; | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 185 | return { pixels, 4, 4, ULTRAHDR_COLORGAMUT_UNSPECIFIED }; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 186 | } | 
|  | 187 |  | 
|  | 188 | float (*MapValues())[4] { | 
|  | 189 | static float values[4][4] = { | 
|  | 190 | { | 
|  | 191 | Map(0x00), Map(0x10), Map(0x20), Map(0x30), | 
|  | 192 | }, { | 
|  | 193 | Map(0x01), Map(0x11), Map(0x21), Map(0x31), | 
|  | 194 | }, { | 
|  | 195 | Map(0x02), Map(0x12), Map(0x22), Map(0x32), | 
|  | 196 | }, { | 
|  | 197 | Map(0x03), Map(0x13), Map(0x23), Map(0x33), | 
|  | 198 | }, | 
|  | 199 | }; | 
|  | 200 | return values; | 
|  | 201 | } | 
|  | 202 |  | 
|  | 203 | protected: | 
|  | 204 | virtual void SetUp(); | 
|  | 205 | virtual void TearDown(); | 
|  | 206 | }; | 
|  | 207 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 208 | GainMapMathTest::GainMapMathTest() {} | 
|  | 209 | GainMapMathTest::~GainMapMathTest() {} | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 210 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 211 | void GainMapMathTest::SetUp() {} | 
|  | 212 | void GainMapMathTest::TearDown() {} | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 213 |  | 
|  | 214 | #define EXPECT_RGB_EQ(e1, e2)       \ | 
|  | 215 | EXPECT_FLOAT_EQ((e1).r, (e2).r);  \ | 
|  | 216 | EXPECT_FLOAT_EQ((e1).g, (e2).g);  \ | 
|  | 217 | EXPECT_FLOAT_EQ((e1).b, (e2).b) | 
|  | 218 |  | 
|  | 219 | #define EXPECT_RGB_NEAR(e1, e2)                     \ | 
|  | 220 | EXPECT_NEAR((e1).r, (e2).r, ComparisonEpsilon()); \ | 
|  | 221 | EXPECT_NEAR((e1).g, (e2).g, ComparisonEpsilon()); \ | 
|  | 222 | EXPECT_NEAR((e1).b, (e2).b, ComparisonEpsilon()) | 
|  | 223 |  | 
|  | 224 | #define EXPECT_RGB_CLOSE(e1, e2)                            \ | 
|  | 225 | EXPECT_NEAR((e1).r, (e2).r, ComparisonEpsilon() * 10.0f); \ | 
|  | 226 | EXPECT_NEAR((e1).g, (e2).g, ComparisonEpsilon() * 10.0f); \ | 
|  | 227 | EXPECT_NEAR((e1).b, (e2).b, ComparisonEpsilon() * 10.0f) | 
|  | 228 |  | 
|  | 229 | #define EXPECT_YUV_EQ(e1, e2)       \ | 
|  | 230 | EXPECT_FLOAT_EQ((e1).y, (e2).y);  \ | 
|  | 231 | EXPECT_FLOAT_EQ((e1).u, (e2).u);  \ | 
|  | 232 | EXPECT_FLOAT_EQ((e1).v, (e2).v) | 
|  | 233 |  | 
|  | 234 | #define EXPECT_YUV_NEAR(e1, e2)                     \ | 
|  | 235 | EXPECT_NEAR((e1).y, (e2).y, ComparisonEpsilon()); \ | 
|  | 236 | EXPECT_NEAR((e1).u, (e2).u, ComparisonEpsilon()); \ | 
|  | 237 | EXPECT_NEAR((e1).v, (e2).v, ComparisonEpsilon()) | 
|  | 238 |  | 
|  | 239 | #define EXPECT_YUV_BETWEEN(e, min, max)                                           \ | 
|  | 240 | EXPECT_THAT((e).y, testing::AllOf(testing::Ge((min).y), testing::Le((max).y))); \ | 
|  | 241 | EXPECT_THAT((e).u, testing::AllOf(testing::Ge((min).u), testing::Le((max).u))); \ | 
|  | 242 | EXPECT_THAT((e).v, testing::AllOf(testing::Ge((min).v), testing::Le((max).v))) | 
|  | 243 |  | 
|  | 244 | // TODO: a bunch of these tests can be parameterized. | 
|  | 245 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 246 | TEST_F(GainMapMathTest, ColorConstruct) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 247 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 248 |  | 
|  | 249 | EXPECT_FLOAT_EQ(e1.r, 0.1f); | 
|  | 250 | EXPECT_FLOAT_EQ(e1.g, 0.2f); | 
|  | 251 | EXPECT_FLOAT_EQ(e1.b, 0.3f); | 
|  | 252 |  | 
|  | 253 | EXPECT_FLOAT_EQ(e1.y, 0.1f); | 
|  | 254 | EXPECT_FLOAT_EQ(e1.u, 0.2f); | 
|  | 255 | EXPECT_FLOAT_EQ(e1.v, 0.3f); | 
|  | 256 | } | 
|  | 257 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 258 | TEST_F(GainMapMathTest, ColorAddColor) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 259 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 260 |  | 
|  | 261 | Color e2 = e1 + e1; | 
|  | 262 | EXPECT_FLOAT_EQ(e2.r, e1.r * 2.0f); | 
|  | 263 | EXPECT_FLOAT_EQ(e2.g, e1.g * 2.0f); | 
|  | 264 | EXPECT_FLOAT_EQ(e2.b, e1.b * 2.0f); | 
|  | 265 |  | 
|  | 266 | e2 += e1; | 
|  | 267 | EXPECT_FLOAT_EQ(e2.r, e1.r * 3.0f); | 
|  | 268 | EXPECT_FLOAT_EQ(e2.g, e1.g * 3.0f); | 
|  | 269 | EXPECT_FLOAT_EQ(e2.b, e1.b * 3.0f); | 
|  | 270 | } | 
|  | 271 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 272 | TEST_F(GainMapMathTest, ColorAddFloat) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 273 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 274 |  | 
|  | 275 | Color e2 = e1 + 0.1f; | 
|  | 276 | EXPECT_FLOAT_EQ(e2.r, e1.r + 0.1f); | 
|  | 277 | EXPECT_FLOAT_EQ(e2.g, e1.g + 0.1f); | 
|  | 278 | EXPECT_FLOAT_EQ(e2.b, e1.b + 0.1f); | 
|  | 279 |  | 
|  | 280 | e2 += 0.1f; | 
|  | 281 | EXPECT_FLOAT_EQ(e2.r, e1.r + 0.2f); | 
|  | 282 | EXPECT_FLOAT_EQ(e2.g, e1.g + 0.2f); | 
|  | 283 | EXPECT_FLOAT_EQ(e2.b, e1.b + 0.2f); | 
|  | 284 | } | 
|  | 285 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 286 | TEST_F(GainMapMathTest, ColorSubtractColor) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 287 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 288 |  | 
|  | 289 | Color e2 = e1 - e1; | 
|  | 290 | EXPECT_FLOAT_EQ(e2.r, 0.0f); | 
|  | 291 | EXPECT_FLOAT_EQ(e2.g, 0.0f); | 
|  | 292 | EXPECT_FLOAT_EQ(e2.b, 0.0f); | 
|  | 293 |  | 
|  | 294 | e2 -= e1; | 
|  | 295 | EXPECT_FLOAT_EQ(e2.r, -e1.r); | 
|  | 296 | EXPECT_FLOAT_EQ(e2.g, -e1.g); | 
|  | 297 | EXPECT_FLOAT_EQ(e2.b, -e1.b); | 
|  | 298 | } | 
|  | 299 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 300 | TEST_F(GainMapMathTest, ColorSubtractFloat) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 301 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 302 |  | 
|  | 303 | Color e2 = e1 - 0.1f; | 
|  | 304 | EXPECT_FLOAT_EQ(e2.r, e1.r - 0.1f); | 
|  | 305 | EXPECT_FLOAT_EQ(e2.g, e1.g - 0.1f); | 
|  | 306 | EXPECT_FLOAT_EQ(e2.b, e1.b - 0.1f); | 
|  | 307 |  | 
|  | 308 | e2 -= 0.1f; | 
|  | 309 | EXPECT_FLOAT_EQ(e2.r, e1.r - 0.2f); | 
|  | 310 | EXPECT_FLOAT_EQ(e2.g, e1.g - 0.2f); | 
|  | 311 | EXPECT_FLOAT_EQ(e2.b, e1.b - 0.2f); | 
|  | 312 | } | 
|  | 313 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 314 | TEST_F(GainMapMathTest, ColorMultiplyFloat) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 315 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 316 |  | 
|  | 317 | Color e2 = e1 * 2.0f; | 
|  | 318 | EXPECT_FLOAT_EQ(e2.r, e1.r * 2.0f); | 
|  | 319 | EXPECT_FLOAT_EQ(e2.g, e1.g * 2.0f); | 
|  | 320 | EXPECT_FLOAT_EQ(e2.b, e1.b * 2.0f); | 
|  | 321 |  | 
|  | 322 | e2 *= 2.0f; | 
|  | 323 | EXPECT_FLOAT_EQ(e2.r, e1.r * 4.0f); | 
|  | 324 | EXPECT_FLOAT_EQ(e2.g, e1.g * 4.0f); | 
|  | 325 | EXPECT_FLOAT_EQ(e2.b, e1.b * 4.0f); | 
|  | 326 | } | 
|  | 327 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 328 | TEST_F(GainMapMathTest, ColorDivideFloat) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 329 | Color e1 = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 330 |  | 
|  | 331 | Color e2 = e1 / 2.0f; | 
|  | 332 | EXPECT_FLOAT_EQ(e2.r, e1.r / 2.0f); | 
|  | 333 | EXPECT_FLOAT_EQ(e2.g, e1.g / 2.0f); | 
|  | 334 | EXPECT_FLOAT_EQ(e2.b, e1.b / 2.0f); | 
|  | 335 |  | 
|  | 336 | e2 /= 2.0f; | 
|  | 337 | EXPECT_FLOAT_EQ(e2.r, e1.r / 4.0f); | 
|  | 338 | EXPECT_FLOAT_EQ(e2.g, e1.g / 4.0f); | 
|  | 339 | EXPECT_FLOAT_EQ(e2.b, e1.b / 4.0f); | 
|  | 340 | } | 
|  | 341 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 342 | TEST_F(GainMapMathTest, SrgbLuminance) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 343 | EXPECT_FLOAT_EQ(srgbLuminance(RgbBlack()), 0.0f); | 
|  | 344 | EXPECT_FLOAT_EQ(srgbLuminance(RgbWhite()), 1.0f); | 
|  | 345 | EXPECT_FLOAT_EQ(srgbLuminance(RgbRed()), 0.2126f); | 
|  | 346 | EXPECT_FLOAT_EQ(srgbLuminance(RgbGreen()), 0.7152f); | 
|  | 347 | EXPECT_FLOAT_EQ(srgbLuminance(RgbBlue()), 0.0722f); | 
|  | 348 | } | 
|  | 349 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 350 | TEST_F(GainMapMathTest, SrgbYuvToRgb) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 351 | Color rgb_black = srgbYuvToRgb(YuvBlack()); | 
|  | 352 | EXPECT_RGB_NEAR(rgb_black, RgbBlack()); | 
|  | 353 |  | 
|  | 354 | Color rgb_white = srgbYuvToRgb(YuvWhite()); | 
|  | 355 | EXPECT_RGB_NEAR(rgb_white, RgbWhite()); | 
|  | 356 |  | 
|  | 357 | Color rgb_r = srgbYuvToRgb(SrgbYuvRed()); | 
|  | 358 | EXPECT_RGB_NEAR(rgb_r, RgbRed()); | 
|  | 359 |  | 
|  | 360 | Color rgb_g = srgbYuvToRgb(SrgbYuvGreen()); | 
|  | 361 | EXPECT_RGB_NEAR(rgb_g, RgbGreen()); | 
|  | 362 |  | 
|  | 363 | Color rgb_b = srgbYuvToRgb(SrgbYuvBlue()); | 
|  | 364 | EXPECT_RGB_NEAR(rgb_b, RgbBlue()); | 
|  | 365 | } | 
|  | 366 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 367 | TEST_F(GainMapMathTest, SrgbRgbToYuv) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 368 | Color yuv_black = srgbRgbToYuv(RgbBlack()); | 
|  | 369 | EXPECT_YUV_NEAR(yuv_black, YuvBlack()); | 
|  | 370 |  | 
|  | 371 | Color yuv_white = srgbRgbToYuv(RgbWhite()); | 
|  | 372 | EXPECT_YUV_NEAR(yuv_white, YuvWhite()); | 
|  | 373 |  | 
|  | 374 | Color yuv_r = srgbRgbToYuv(RgbRed()); | 
|  | 375 | EXPECT_YUV_NEAR(yuv_r, SrgbYuvRed()); | 
|  | 376 |  | 
|  | 377 | Color yuv_g = srgbRgbToYuv(RgbGreen()); | 
|  | 378 | EXPECT_YUV_NEAR(yuv_g, SrgbYuvGreen()); | 
|  | 379 |  | 
|  | 380 | Color yuv_b = srgbRgbToYuv(RgbBlue()); | 
|  | 381 | EXPECT_YUV_NEAR(yuv_b, SrgbYuvBlue()); | 
|  | 382 | } | 
|  | 383 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 384 | TEST_F(GainMapMathTest, SrgbRgbYuvRoundtrip) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 385 | Color rgb_black = srgbYuvToRgb(srgbRgbToYuv(RgbBlack())); | 
|  | 386 | EXPECT_RGB_NEAR(rgb_black, RgbBlack()); | 
|  | 387 |  | 
|  | 388 | Color rgb_white = srgbYuvToRgb(srgbRgbToYuv(RgbWhite())); | 
|  | 389 | EXPECT_RGB_NEAR(rgb_white, RgbWhite()); | 
|  | 390 |  | 
|  | 391 | Color rgb_r = srgbYuvToRgb(srgbRgbToYuv(RgbRed())); | 
|  | 392 | EXPECT_RGB_NEAR(rgb_r, RgbRed()); | 
|  | 393 |  | 
|  | 394 | Color rgb_g = srgbYuvToRgb(srgbRgbToYuv(RgbGreen())); | 
|  | 395 | EXPECT_RGB_NEAR(rgb_g, RgbGreen()); | 
|  | 396 |  | 
|  | 397 | Color rgb_b = srgbYuvToRgb(srgbRgbToYuv(RgbBlue())); | 
|  | 398 | EXPECT_RGB_NEAR(rgb_b, RgbBlue()); | 
|  | 399 | } | 
|  | 400 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 401 | TEST_F(GainMapMathTest, SrgbTransferFunction) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 402 | EXPECT_FLOAT_EQ(srgbInvOetf(0.0f), 0.0f); | 
|  | 403 | EXPECT_NEAR(srgbInvOetf(0.02f), 0.00154f, ComparisonEpsilon()); | 
|  | 404 | EXPECT_NEAR(srgbInvOetf(0.04045f), 0.00313f, ComparisonEpsilon()); | 
|  | 405 | EXPECT_NEAR(srgbInvOetf(0.5f), 0.21404f, ComparisonEpsilon()); | 
|  | 406 | EXPECT_FLOAT_EQ(srgbInvOetf(1.0f), 1.0f); | 
|  | 407 | } | 
|  | 408 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 409 | TEST_F(GainMapMathTest, P3Luminance) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 410 | EXPECT_FLOAT_EQ(p3Luminance(RgbBlack()), 0.0f); | 
|  | 411 | EXPECT_FLOAT_EQ(p3Luminance(RgbWhite()), 1.0f); | 
|  | 412 | EXPECT_FLOAT_EQ(p3Luminance(RgbRed()), 0.20949f); | 
|  | 413 | EXPECT_FLOAT_EQ(p3Luminance(RgbGreen()), 0.72160f); | 
|  | 414 | EXPECT_FLOAT_EQ(p3Luminance(RgbBlue()), 0.06891f); | 
|  | 415 | } | 
|  | 416 |  | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 417 | TEST_F(GainMapMathTest, P3YuvToRgb) { | 
|  | 418 | Color rgb_black = p3YuvToRgb(YuvBlack()); | 
|  | 419 | EXPECT_RGB_NEAR(rgb_black, RgbBlack()); | 
|  | 420 |  | 
|  | 421 | Color rgb_white = p3YuvToRgb(YuvWhite()); | 
|  | 422 | EXPECT_RGB_NEAR(rgb_white, RgbWhite()); | 
|  | 423 |  | 
|  | 424 | Color rgb_r = p3YuvToRgb(P3YuvRed()); | 
|  | 425 | EXPECT_RGB_NEAR(rgb_r, RgbRed()); | 
|  | 426 |  | 
|  | 427 | Color rgb_g = p3YuvToRgb(P3YuvGreen()); | 
|  | 428 | EXPECT_RGB_NEAR(rgb_g, RgbGreen()); | 
|  | 429 |  | 
|  | 430 | Color rgb_b = p3YuvToRgb(P3YuvBlue()); | 
|  | 431 | EXPECT_RGB_NEAR(rgb_b, RgbBlue()); | 
|  | 432 | } | 
|  | 433 |  | 
|  | 434 | TEST_F(GainMapMathTest, P3RgbToYuv) { | 
|  | 435 | Color yuv_black = p3RgbToYuv(RgbBlack()); | 
|  | 436 | EXPECT_YUV_NEAR(yuv_black, YuvBlack()); | 
|  | 437 |  | 
|  | 438 | Color yuv_white = p3RgbToYuv(RgbWhite()); | 
|  | 439 | EXPECT_YUV_NEAR(yuv_white, YuvWhite()); | 
|  | 440 |  | 
|  | 441 | Color yuv_r = p3RgbToYuv(RgbRed()); | 
|  | 442 | EXPECT_YUV_NEAR(yuv_r, P3YuvRed()); | 
|  | 443 |  | 
|  | 444 | Color yuv_g = p3RgbToYuv(RgbGreen()); | 
|  | 445 | EXPECT_YUV_NEAR(yuv_g, P3YuvGreen()); | 
|  | 446 |  | 
|  | 447 | Color yuv_b = p3RgbToYuv(RgbBlue()); | 
|  | 448 | EXPECT_YUV_NEAR(yuv_b, P3YuvBlue()); | 
|  | 449 | } | 
|  | 450 |  | 
|  | 451 | TEST_F(GainMapMathTest, P3RgbYuvRoundtrip) { | 
|  | 452 | Color rgb_black = p3YuvToRgb(p3RgbToYuv(RgbBlack())); | 
|  | 453 | EXPECT_RGB_NEAR(rgb_black, RgbBlack()); | 
|  | 454 |  | 
|  | 455 | Color rgb_white = p3YuvToRgb(p3RgbToYuv(RgbWhite())); | 
|  | 456 | EXPECT_RGB_NEAR(rgb_white, RgbWhite()); | 
|  | 457 |  | 
|  | 458 | Color rgb_r = p3YuvToRgb(p3RgbToYuv(RgbRed())); | 
|  | 459 | EXPECT_RGB_NEAR(rgb_r, RgbRed()); | 
|  | 460 |  | 
|  | 461 | Color rgb_g = p3YuvToRgb(p3RgbToYuv(RgbGreen())); | 
|  | 462 | EXPECT_RGB_NEAR(rgb_g, RgbGreen()); | 
|  | 463 |  | 
|  | 464 | Color rgb_b = p3YuvToRgb(p3RgbToYuv(RgbBlue())); | 
|  | 465 | EXPECT_RGB_NEAR(rgb_b, RgbBlue()); | 
|  | 466 | } | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 467 | TEST_F(GainMapMathTest, Bt2100Luminance) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 468 | EXPECT_FLOAT_EQ(bt2100Luminance(RgbBlack()), 0.0f); | 
|  | 469 | EXPECT_FLOAT_EQ(bt2100Luminance(RgbWhite()), 1.0f); | 
|  | 470 | EXPECT_FLOAT_EQ(bt2100Luminance(RgbRed()), 0.2627f); | 
|  | 471 | EXPECT_FLOAT_EQ(bt2100Luminance(RgbGreen()), 0.6780f); | 
|  | 472 | EXPECT_FLOAT_EQ(bt2100Luminance(RgbBlue()), 0.0593f); | 
|  | 473 | } | 
|  | 474 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 475 | TEST_F(GainMapMathTest, Bt2100YuvToRgb) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 476 | Color rgb_black = bt2100YuvToRgb(YuvBlack()); | 
|  | 477 | EXPECT_RGB_NEAR(rgb_black, RgbBlack()); | 
|  | 478 |  | 
|  | 479 | Color rgb_white = bt2100YuvToRgb(YuvWhite()); | 
|  | 480 | EXPECT_RGB_NEAR(rgb_white, RgbWhite()); | 
|  | 481 |  | 
|  | 482 | Color rgb_r = bt2100YuvToRgb(Bt2100YuvRed()); | 
|  | 483 | EXPECT_RGB_NEAR(rgb_r, RgbRed()); | 
|  | 484 |  | 
|  | 485 | Color rgb_g = bt2100YuvToRgb(Bt2100YuvGreen()); | 
|  | 486 | EXPECT_RGB_NEAR(rgb_g, RgbGreen()); | 
|  | 487 |  | 
|  | 488 | Color rgb_b = bt2100YuvToRgb(Bt2100YuvBlue()); | 
|  | 489 | EXPECT_RGB_NEAR(rgb_b, RgbBlue()); | 
|  | 490 | } | 
|  | 491 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 492 | TEST_F(GainMapMathTest, Bt2100RgbToYuv) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 493 | Color yuv_black = bt2100RgbToYuv(RgbBlack()); | 
|  | 494 | EXPECT_YUV_NEAR(yuv_black, YuvBlack()); | 
|  | 495 |  | 
|  | 496 | Color yuv_white = bt2100RgbToYuv(RgbWhite()); | 
|  | 497 | EXPECT_YUV_NEAR(yuv_white, YuvWhite()); | 
|  | 498 |  | 
|  | 499 | Color yuv_r = bt2100RgbToYuv(RgbRed()); | 
|  | 500 | EXPECT_YUV_NEAR(yuv_r, Bt2100YuvRed()); | 
|  | 501 |  | 
|  | 502 | Color yuv_g = bt2100RgbToYuv(RgbGreen()); | 
|  | 503 | EXPECT_YUV_NEAR(yuv_g, Bt2100YuvGreen()); | 
|  | 504 |  | 
|  | 505 | Color yuv_b = bt2100RgbToYuv(RgbBlue()); | 
|  | 506 | EXPECT_YUV_NEAR(yuv_b, Bt2100YuvBlue()); | 
|  | 507 | } | 
|  | 508 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 509 | TEST_F(GainMapMathTest, Bt2100RgbYuvRoundtrip) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 510 | Color rgb_black = bt2100YuvToRgb(bt2100RgbToYuv(RgbBlack())); | 
|  | 511 | EXPECT_RGB_NEAR(rgb_black, RgbBlack()); | 
|  | 512 |  | 
|  | 513 | Color rgb_white = bt2100YuvToRgb(bt2100RgbToYuv(RgbWhite())); | 
|  | 514 | EXPECT_RGB_NEAR(rgb_white, RgbWhite()); | 
|  | 515 |  | 
|  | 516 | Color rgb_r = bt2100YuvToRgb(bt2100RgbToYuv(RgbRed())); | 
|  | 517 | EXPECT_RGB_NEAR(rgb_r, RgbRed()); | 
|  | 518 |  | 
|  | 519 | Color rgb_g = bt2100YuvToRgb(bt2100RgbToYuv(RgbGreen())); | 
|  | 520 | EXPECT_RGB_NEAR(rgb_g, RgbGreen()); | 
|  | 521 |  | 
|  | 522 | Color rgb_b = bt2100YuvToRgb(bt2100RgbToYuv(RgbBlue())); | 
|  | 523 | EXPECT_RGB_NEAR(rgb_b, RgbBlue()); | 
|  | 524 | } | 
|  | 525 |  | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 526 | TEST_F(GainMapMathTest, Bt709ToBt601YuvConversion) { | 
|  | 527 | Color yuv_black = srgbRgbToYuv(RgbBlack()); | 
|  | 528 | EXPECT_YUV_NEAR(yuv709To601(yuv_black), YuvBlack()); | 
|  | 529 |  | 
|  | 530 | Color yuv_white = srgbRgbToYuv(RgbWhite()); | 
|  | 531 | EXPECT_YUV_NEAR(yuv709To601(yuv_white), YuvWhite()); | 
|  | 532 |  | 
|  | 533 | Color yuv_r = srgbRgbToYuv(RgbRed()); | 
|  | 534 | EXPECT_YUV_NEAR(yuv709To601(yuv_r), P3YuvRed()); | 
|  | 535 |  | 
|  | 536 | Color yuv_g = srgbRgbToYuv(RgbGreen()); | 
|  | 537 | EXPECT_YUV_NEAR(yuv709To601(yuv_g), P3YuvGreen()); | 
|  | 538 |  | 
|  | 539 | Color yuv_b = srgbRgbToYuv(RgbBlue()); | 
|  | 540 | EXPECT_YUV_NEAR(yuv709To601(yuv_b), P3YuvBlue()); | 
|  | 541 | } | 
|  | 542 |  | 
|  | 543 | TEST_F(GainMapMathTest, Bt709ToBt2100YuvConversion) { | 
|  | 544 | Color yuv_black = srgbRgbToYuv(RgbBlack()); | 
|  | 545 | EXPECT_YUV_NEAR(yuv709To2100(yuv_black), YuvBlack()); | 
|  | 546 |  | 
|  | 547 | Color yuv_white = srgbRgbToYuv(RgbWhite()); | 
|  | 548 | EXPECT_YUV_NEAR(yuv709To2100(yuv_white), YuvWhite()); | 
|  | 549 |  | 
|  | 550 | Color yuv_r = srgbRgbToYuv(RgbRed()); | 
|  | 551 | EXPECT_YUV_NEAR(yuv709To2100(yuv_r), Bt2100YuvRed()); | 
|  | 552 |  | 
|  | 553 | Color yuv_g = srgbRgbToYuv(RgbGreen()); | 
|  | 554 | EXPECT_YUV_NEAR(yuv709To2100(yuv_g), Bt2100YuvGreen()); | 
|  | 555 |  | 
|  | 556 | Color yuv_b = srgbRgbToYuv(RgbBlue()); | 
|  | 557 | EXPECT_YUV_NEAR(yuv709To2100(yuv_b), Bt2100YuvBlue()); | 
|  | 558 | } | 
|  | 559 |  | 
|  | 560 | TEST_F(GainMapMathTest, Bt601ToBt709YuvConversion) { | 
|  | 561 | Color yuv_black = p3RgbToYuv(RgbBlack()); | 
|  | 562 | EXPECT_YUV_NEAR(yuv601To709(yuv_black), YuvBlack()); | 
|  | 563 |  | 
|  | 564 | Color yuv_white = p3RgbToYuv(RgbWhite()); | 
|  | 565 | EXPECT_YUV_NEAR(yuv601To709(yuv_white), YuvWhite()); | 
|  | 566 |  | 
|  | 567 | Color yuv_r = p3RgbToYuv(RgbRed()); | 
|  | 568 | EXPECT_YUV_NEAR(yuv601To709(yuv_r), SrgbYuvRed()); | 
|  | 569 |  | 
|  | 570 | Color yuv_g = p3RgbToYuv(RgbGreen()); | 
|  | 571 | EXPECT_YUV_NEAR(yuv601To709(yuv_g), SrgbYuvGreen()); | 
|  | 572 |  | 
|  | 573 | Color yuv_b = p3RgbToYuv(RgbBlue()); | 
|  | 574 | EXPECT_YUV_NEAR(yuv601To709(yuv_b), SrgbYuvBlue()); | 
|  | 575 | } | 
|  | 576 |  | 
|  | 577 | TEST_F(GainMapMathTest, Bt601ToBt2100YuvConversion) { | 
|  | 578 | Color yuv_black = p3RgbToYuv(RgbBlack()); | 
|  | 579 | EXPECT_YUV_NEAR(yuv601To2100(yuv_black), YuvBlack()); | 
|  | 580 |  | 
|  | 581 | Color yuv_white = p3RgbToYuv(RgbWhite()); | 
|  | 582 | EXPECT_YUV_NEAR(yuv601To2100(yuv_white), YuvWhite()); | 
|  | 583 |  | 
|  | 584 | Color yuv_r = p3RgbToYuv(RgbRed()); | 
|  | 585 | EXPECT_YUV_NEAR(yuv601To2100(yuv_r), Bt2100YuvRed()); | 
|  | 586 |  | 
|  | 587 | Color yuv_g = p3RgbToYuv(RgbGreen()); | 
|  | 588 | EXPECT_YUV_NEAR(yuv601To2100(yuv_g), Bt2100YuvGreen()); | 
|  | 589 |  | 
|  | 590 | Color yuv_b = p3RgbToYuv(RgbBlue()); | 
|  | 591 | EXPECT_YUV_NEAR(yuv601To2100(yuv_b), Bt2100YuvBlue()); | 
|  | 592 | } | 
|  | 593 |  | 
|  | 594 | TEST_F(GainMapMathTest, Bt2100ToBt709YuvConversion) { | 
|  | 595 | Color yuv_black = bt2100RgbToYuv(RgbBlack()); | 
|  | 596 | EXPECT_YUV_NEAR(yuv2100To709(yuv_black), YuvBlack()); | 
|  | 597 |  | 
|  | 598 | Color yuv_white = bt2100RgbToYuv(RgbWhite()); | 
|  | 599 | EXPECT_YUV_NEAR(yuv2100To709(yuv_white), YuvWhite()); | 
|  | 600 |  | 
|  | 601 | Color yuv_r = bt2100RgbToYuv(RgbRed()); | 
|  | 602 | EXPECT_YUV_NEAR(yuv2100To709(yuv_r), SrgbYuvRed()); | 
|  | 603 |  | 
|  | 604 | Color yuv_g = bt2100RgbToYuv(RgbGreen()); | 
|  | 605 | EXPECT_YUV_NEAR(yuv2100To709(yuv_g), SrgbYuvGreen()); | 
|  | 606 |  | 
|  | 607 | Color yuv_b = bt2100RgbToYuv(RgbBlue()); | 
|  | 608 | EXPECT_YUV_NEAR(yuv2100To709(yuv_b), SrgbYuvBlue()); | 
|  | 609 | } | 
|  | 610 |  | 
|  | 611 | TEST_F(GainMapMathTest, Bt2100ToBt601YuvConversion) { | 
|  | 612 | Color yuv_black = bt2100RgbToYuv(RgbBlack()); | 
|  | 613 | EXPECT_YUV_NEAR(yuv2100To601(yuv_black), YuvBlack()); | 
|  | 614 |  | 
|  | 615 | Color yuv_white = bt2100RgbToYuv(RgbWhite()); | 
|  | 616 | EXPECT_YUV_NEAR(yuv2100To601(yuv_white), YuvWhite()); | 
|  | 617 |  | 
|  | 618 | Color yuv_r = bt2100RgbToYuv(RgbRed()); | 
|  | 619 | EXPECT_YUV_NEAR(yuv2100To601(yuv_r), P3YuvRed()); | 
|  | 620 |  | 
|  | 621 | Color yuv_g = bt2100RgbToYuv(RgbGreen()); | 
|  | 622 | EXPECT_YUV_NEAR(yuv2100To601(yuv_g), P3YuvGreen()); | 
|  | 623 |  | 
|  | 624 | Color yuv_b = bt2100RgbToYuv(RgbBlue()); | 
|  | 625 | EXPECT_YUV_NEAR(yuv2100To601(yuv_b), P3YuvBlue()); | 
|  | 626 | } | 
|  | 627 |  | 
|  | 628 | TEST_F(GainMapMathTest, TransformYuv420) { | 
|  | 629 | ColorTransformFn transforms[] = { yuv709To601, yuv709To2100, yuv601To709, yuv601To2100, | 
|  | 630 | yuv2100To709, yuv2100To601 }; | 
|  | 631 | for (const ColorTransformFn& transform : transforms) { | 
|  | 632 | jpegr_uncompressed_struct input = Yuv420Image(); | 
|  | 633 |  | 
|  | 634 | size_t out_buf_size = input.width * input.height * 3 / 2; | 
|  | 635 | std::unique_ptr<uint8_t[]> out_buf = std::make_unique<uint8_t[]>(out_buf_size); | 
|  | 636 | memcpy(out_buf.get(), input.data, out_buf_size); | 
|  | 637 | jpegr_uncompressed_struct output = Yuv420Image(); | 
|  | 638 | output.data = out_buf.get(); | 
|  | 639 |  | 
|  | 640 | transformYuv420(&output, 1, 1, transform); | 
|  | 641 |  | 
|  | 642 | for (size_t y = 0; y < 4; ++y) { | 
|  | 643 | for (size_t x = 0; x < 4; ++x) { | 
|  | 644 | // Skip the last chroma sample, which we modified above | 
|  | 645 | if (x >= 2 && y >= 2) { | 
|  | 646 | continue; | 
|  | 647 | } | 
|  | 648 |  | 
|  | 649 | // All other pixels should remain unchanged | 
|  | 650 | EXPECT_YUV_EQ(getYuv420Pixel(&input, x, y), getYuv420Pixel(&output, x, y)); | 
|  | 651 | } | 
|  | 652 | } | 
|  | 653 |  | 
|  | 654 | // modified pixels should be updated as intended by the transformYuv420 algorithm | 
|  | 655 | Color in1 = getYuv420Pixel(&input,   2, 2); | 
|  | 656 | Color in2 = getYuv420Pixel(&input,   3, 2); | 
|  | 657 | Color in3 = getYuv420Pixel(&input,   2, 3); | 
|  | 658 | Color in4 = getYuv420Pixel(&input,   3, 3); | 
|  | 659 | Color out1 = getYuv420Pixel(&output, 2, 2); | 
|  | 660 | Color out2 = getYuv420Pixel(&output, 3, 2); | 
|  | 661 | Color out3 = getYuv420Pixel(&output, 2, 3); | 
|  | 662 | Color out4 = getYuv420Pixel(&output, 3, 3); | 
|  | 663 |  | 
|  | 664 | EXPECT_NEAR(transform(in1).y, out1.y, YuvConversionEpsilon()); | 
|  | 665 | EXPECT_NEAR(transform(in2).y, out2.y, YuvConversionEpsilon()); | 
|  | 666 | EXPECT_NEAR(transform(in3).y, out3.y, YuvConversionEpsilon()); | 
|  | 667 | EXPECT_NEAR(transform(in4).y, out4.y, YuvConversionEpsilon()); | 
|  | 668 |  | 
|  | 669 | Color expect_uv = (transform(in1) + transform(in2) + transform(in3) + transform(in4)) / 4.0f; | 
|  | 670 |  | 
|  | 671 | EXPECT_NEAR(expect_uv.u, out1.u, YuvConversionEpsilon()); | 
|  | 672 | EXPECT_NEAR(expect_uv.u, out2.u, YuvConversionEpsilon()); | 
|  | 673 | EXPECT_NEAR(expect_uv.u, out3.u, YuvConversionEpsilon()); | 
|  | 674 | EXPECT_NEAR(expect_uv.u, out4.u, YuvConversionEpsilon()); | 
|  | 675 |  | 
|  | 676 | EXPECT_NEAR(expect_uv.v, out1.v, YuvConversionEpsilon()); | 
|  | 677 | EXPECT_NEAR(expect_uv.v, out2.v, YuvConversionEpsilon()); | 
|  | 678 | EXPECT_NEAR(expect_uv.v, out3.v, YuvConversionEpsilon()); | 
|  | 679 | EXPECT_NEAR(expect_uv.v, out4.v, YuvConversionEpsilon()); | 
|  | 680 | } | 
|  | 681 | } | 
|  | 682 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 683 | TEST_F(GainMapMathTest, HlgOetf) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 684 | EXPECT_FLOAT_EQ(hlgOetf(0.0f), 0.0f); | 
|  | 685 | EXPECT_NEAR(hlgOetf(0.04167f), 0.35357f, ComparisonEpsilon()); | 
|  | 686 | EXPECT_NEAR(hlgOetf(0.08333f), 0.5f, ComparisonEpsilon()); | 
|  | 687 | EXPECT_NEAR(hlgOetf(0.5f), 0.87164f, ComparisonEpsilon()); | 
|  | 688 | EXPECT_FLOAT_EQ(hlgOetf(1.0f), 1.0f); | 
|  | 689 |  | 
|  | 690 | Color e = {{{ 0.04167f, 0.08333f, 0.5f }}}; | 
|  | 691 | Color e_gamma = {{{ 0.35357f, 0.5f, 0.87164f }}}; | 
|  | 692 | EXPECT_RGB_NEAR(hlgOetf(e), e_gamma); | 
|  | 693 | } | 
|  | 694 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 695 | TEST_F(GainMapMathTest, HlgInvOetf) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 696 | EXPECT_FLOAT_EQ(hlgInvOetf(0.0f), 0.0f); | 
|  | 697 | EXPECT_NEAR(hlgInvOetf(0.25f), 0.02083f, ComparisonEpsilon()); | 
|  | 698 | EXPECT_NEAR(hlgInvOetf(0.5f), 0.08333f, ComparisonEpsilon()); | 
|  | 699 | EXPECT_NEAR(hlgInvOetf(0.75f), 0.26496f, ComparisonEpsilon()); | 
|  | 700 | EXPECT_FLOAT_EQ(hlgInvOetf(1.0f), 1.0f); | 
|  | 701 |  | 
|  | 702 | Color e_gamma = {{{ 0.25f, 0.5f, 0.75f }}}; | 
|  | 703 | Color e = {{{ 0.02083f, 0.08333f, 0.26496f }}}; | 
|  | 704 | EXPECT_RGB_NEAR(hlgInvOetf(e_gamma), e); | 
|  | 705 | } | 
|  | 706 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 707 | TEST_F(GainMapMathTest, HlgTransferFunctionRoundtrip) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 708 | EXPECT_FLOAT_EQ(hlgInvOetf(hlgOetf(0.0f)), 0.0f); | 
|  | 709 | EXPECT_NEAR(hlgInvOetf(hlgOetf(0.04167f)), 0.04167f, ComparisonEpsilon()); | 
|  | 710 | EXPECT_NEAR(hlgInvOetf(hlgOetf(0.08333f)), 0.08333f, ComparisonEpsilon()); | 
|  | 711 | EXPECT_NEAR(hlgInvOetf(hlgOetf(0.5f)), 0.5f, ComparisonEpsilon()); | 
|  | 712 | EXPECT_FLOAT_EQ(hlgInvOetf(hlgOetf(1.0f)), 1.0f); | 
|  | 713 | } | 
|  | 714 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 715 | TEST_F(GainMapMathTest, PqOetf) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 716 | EXPECT_FLOAT_EQ(pqOetf(0.0f), 0.0f); | 
|  | 717 | EXPECT_NEAR(pqOetf(0.01f), 0.50808f, ComparisonEpsilon()); | 
|  | 718 | EXPECT_NEAR(pqOetf(0.5f), 0.92655f, ComparisonEpsilon()); | 
|  | 719 | EXPECT_NEAR(pqOetf(0.99f), 0.99895f, ComparisonEpsilon()); | 
|  | 720 | EXPECT_FLOAT_EQ(pqOetf(1.0f), 1.0f); | 
|  | 721 |  | 
|  | 722 | Color e = {{{ 0.01f, 0.5f, 0.99f }}}; | 
|  | 723 | Color e_gamma = {{{ 0.50808f, 0.92655f, 0.99895f }}}; | 
|  | 724 | EXPECT_RGB_NEAR(pqOetf(e), e_gamma); | 
|  | 725 | } | 
|  | 726 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 727 | TEST_F(GainMapMathTest, PqInvOetf) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 728 | EXPECT_FLOAT_EQ(pqInvOetf(0.0f), 0.0f); | 
|  | 729 | EXPECT_NEAR(pqInvOetf(0.01f), 2.31017e-7f, ComparisonEpsilon()); | 
|  | 730 | EXPECT_NEAR(pqInvOetf(0.5f), 0.00922f, ComparisonEpsilon()); | 
|  | 731 | EXPECT_NEAR(pqInvOetf(0.99f), 0.90903f, ComparisonEpsilon()); | 
|  | 732 | EXPECT_FLOAT_EQ(pqInvOetf(1.0f), 1.0f); | 
|  | 733 |  | 
|  | 734 | Color e_gamma = {{{ 0.01f, 0.5f, 0.99f }}}; | 
|  | 735 | Color e = {{{ 2.31017e-7f, 0.00922f, 0.90903f }}}; | 
|  | 736 | EXPECT_RGB_NEAR(pqInvOetf(e_gamma), e); | 
|  | 737 | } | 
|  | 738 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 739 | TEST_F(GainMapMathTest, PqInvOetfLUT) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 740 | for (int idx = 0; idx < kPqInvOETFNumEntries; idx++) { | 
|  | 741 | float value = static_cast<float>(idx) / static_cast<float>(kPqInvOETFNumEntries - 1); | 
| Harish Mahendrakar | 555a06b | 2022-12-14 09:37:27 -0800 | [diff] [blame] | 742 | EXPECT_FLOAT_EQ(pqInvOetf(value), pqInvOetfLUT(value)); | 
|  | 743 | } | 
|  | 744 | } | 
|  | 745 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 746 | TEST_F(GainMapMathTest, HlgInvOetfLUT) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 747 | for (int idx = 0; idx < kHlgInvOETFNumEntries; idx++) { | 
|  | 748 | float value = static_cast<float>(idx) / static_cast<float>(kHlgInvOETFNumEntries - 1); | 
| Harish Mahendrakar | 555a06b | 2022-12-14 09:37:27 -0800 | [diff] [blame] | 749 | EXPECT_FLOAT_EQ(hlgInvOetf(value), hlgInvOetfLUT(value)); | 
|  | 750 | } | 
|  | 751 | } | 
|  | 752 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 753 | TEST_F(GainMapMathTest, pqOetfLUT) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 754 | for (int idx = 0; idx < kPqOETFNumEntries; idx++) { | 
|  | 755 | float value = static_cast<float>(idx) / static_cast<float>(kPqOETFNumEntries - 1); | 
| Harish Mahendrakar | 555a06b | 2022-12-14 09:37:27 -0800 | [diff] [blame] | 756 | EXPECT_FLOAT_EQ(pqOetf(value), pqOetfLUT(value)); | 
|  | 757 | } | 
|  | 758 | } | 
|  | 759 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 760 | TEST_F(GainMapMathTest, hlgOetfLUT) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 761 | for (int idx = 0; idx < kHlgOETFNumEntries; idx++) { | 
|  | 762 | float value = static_cast<float>(idx) / static_cast<float>(kHlgOETFNumEntries - 1); | 
| Harish Mahendrakar | 555a06b | 2022-12-14 09:37:27 -0800 | [diff] [blame] | 763 | EXPECT_FLOAT_EQ(hlgOetf(value), hlgOetfLUT(value)); | 
|  | 764 | } | 
|  | 765 | } | 
|  | 766 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 767 | TEST_F(GainMapMathTest, srgbInvOetfLUT) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 768 | for (int idx = 0; idx < kSrgbInvOETFNumEntries; idx++) { | 
|  | 769 | float value = static_cast<float>(idx) / static_cast<float>(kSrgbInvOETFNumEntries - 1); | 
| Harish Mahendrakar | 555a06b | 2022-12-14 09:37:27 -0800 | [diff] [blame] | 770 | EXPECT_FLOAT_EQ(srgbInvOetf(value), srgbInvOetfLUT(value)); | 
|  | 771 | } | 
|  | 772 | } | 
|  | 773 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 774 | TEST_F(GainMapMathTest, applyGainLUT) { | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 775 | for (int boost = 1; boost <= 10; boost++) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 776 | ultrahdr_metadata_struct metadata = { .maxContentBoost = static_cast<float>(boost), | 
| Dichen Zhang | e286f1c | 2023-03-14 00:22:00 +0000 | [diff] [blame] | 777 | .minContentBoost = 1.0f / static_cast<float>(boost) }; | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 778 | GainLUT gainLUT(&metadata); | 
|  | 779 | GainLUT gainLUTWithBoost(&metadata, metadata.maxContentBoost); | 
|  | 780 | for (int idx = 0; idx < kGainFactorNumEntries; idx++) { | 
|  | 781 | float value = static_cast<float>(idx) / static_cast<float>(kGainFactorNumEntries - 1); | 
|  | 782 | EXPECT_RGB_NEAR(applyGain(RgbBlack(), value, &metadata), | 
|  | 783 | applyGainLUT(RgbBlack(), value, gainLUT)); | 
|  | 784 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), value, &metadata), | 
|  | 785 | applyGainLUT(RgbWhite(), value, gainLUT)); | 
|  | 786 | EXPECT_RGB_NEAR(applyGain(RgbRed(), value, &metadata), | 
|  | 787 | applyGainLUT(RgbRed(), value, gainLUT)); | 
|  | 788 | EXPECT_RGB_NEAR(applyGain(RgbGreen(), value, &metadata), | 
|  | 789 | applyGainLUT(RgbGreen(), value, gainLUT)); | 
|  | 790 | EXPECT_RGB_NEAR(applyGain(RgbBlue(), value, &metadata), | 
|  | 791 | applyGainLUT(RgbBlue(), value, gainLUT)); | 
|  | 792 | EXPECT_RGB_EQ(applyGainLUT(RgbBlack(), value, gainLUT), | 
|  | 793 | applyGainLUT(RgbBlack(), value, gainLUTWithBoost)); | 
|  | 794 | EXPECT_RGB_EQ(applyGainLUT(RgbWhite(), value, gainLUT), | 
|  | 795 | applyGainLUT(RgbWhite(), value, gainLUTWithBoost)); | 
|  | 796 | EXPECT_RGB_EQ(applyGainLUT(RgbRed(), value, gainLUT), | 
|  | 797 | applyGainLUT(RgbRed(), value, gainLUTWithBoost)); | 
|  | 798 | EXPECT_RGB_EQ(applyGainLUT(RgbGreen(), value, gainLUT), | 
|  | 799 | applyGainLUT(RgbGreen(), value, gainLUTWithBoost)); | 
|  | 800 | EXPECT_RGB_EQ(applyGainLUT(RgbBlue(), value, gainLUT), | 
|  | 801 | applyGainLUT(RgbBlue(), value, gainLUTWithBoost)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 802 | } | 
|  | 803 | } | 
|  | 804 |  | 
|  | 805 | for (int boost = 1; boost <= 10; boost++) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 806 | ultrahdr_metadata_struct metadata = { .maxContentBoost = static_cast<float>(boost), | 
| Dichen Zhang | e286f1c | 2023-03-14 00:22:00 +0000 | [diff] [blame] | 807 | .minContentBoost = 1.0f }; | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 808 | GainLUT gainLUT(&metadata); | 
|  | 809 | GainLUT gainLUTWithBoost(&metadata, metadata.maxContentBoost); | 
|  | 810 | for (int idx = 0; idx < kGainFactorNumEntries; idx++) { | 
|  | 811 | float value = static_cast<float>(idx) / static_cast<float>(kGainFactorNumEntries - 1); | 
|  | 812 | EXPECT_RGB_NEAR(applyGain(RgbBlack(), value, &metadata), | 
|  | 813 | applyGainLUT(RgbBlack(), value, gainLUT)); | 
|  | 814 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), value, &metadata), | 
|  | 815 | applyGainLUT(RgbWhite(), value, gainLUT)); | 
|  | 816 | EXPECT_RGB_NEAR(applyGain(RgbRed(), value, &metadata), | 
|  | 817 | applyGainLUT(RgbRed(), value, gainLUT)); | 
|  | 818 | EXPECT_RGB_NEAR(applyGain(RgbGreen(), value, &metadata), | 
|  | 819 | applyGainLUT(RgbGreen(), value, gainLUT)); | 
|  | 820 | EXPECT_RGB_NEAR(applyGain(RgbBlue(), value, &metadata), | 
|  | 821 | applyGainLUT(RgbBlue(), value, gainLUT)); | 
|  | 822 | EXPECT_RGB_EQ(applyGainLUT(RgbBlack(), value, gainLUT), | 
|  | 823 | applyGainLUT(RgbBlack(), value, gainLUTWithBoost)); | 
|  | 824 | EXPECT_RGB_EQ(applyGainLUT(RgbWhite(), value, gainLUT), | 
|  | 825 | applyGainLUT(RgbWhite(), value, gainLUTWithBoost)); | 
|  | 826 | EXPECT_RGB_EQ(applyGainLUT(RgbRed(), value, gainLUT), | 
|  | 827 | applyGainLUT(RgbRed(), value, gainLUTWithBoost)); | 
|  | 828 | EXPECT_RGB_EQ(applyGainLUT(RgbGreen(), value, gainLUT), | 
|  | 829 | applyGainLUT(RgbGreen(), value, gainLUTWithBoost)); | 
|  | 830 | EXPECT_RGB_EQ(applyGainLUT(RgbBlue(), value, gainLUT), | 
|  | 831 | applyGainLUT(RgbBlue(), value, gainLUTWithBoost)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 832 | } | 
|  | 833 | } | 
|  | 834 |  | 
|  | 835 | for (int boost = 1; boost <= 10; boost++) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 836 | ultrahdr_metadata_struct metadata = { .maxContentBoost = static_cast<float>(boost), | 
| Dichen Zhang | e286f1c | 2023-03-14 00:22:00 +0000 | [diff] [blame] | 837 | .minContentBoost = 1.0f / pow(static_cast<float>(boost), | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 838 | 1.0f / 3.0f) }; | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 839 | GainLUT gainLUT(&metadata); | 
|  | 840 | GainLUT gainLUTWithBoost(&metadata, metadata.maxContentBoost); | 
|  | 841 | for (int idx = 0; idx < kGainFactorNumEntries; idx++) { | 
|  | 842 | float value = static_cast<float>(idx) / static_cast<float>(kGainFactorNumEntries - 1); | 
|  | 843 | EXPECT_RGB_NEAR(applyGain(RgbBlack(), value, &metadata), | 
|  | 844 | applyGainLUT(RgbBlack(), value, gainLUT)); | 
|  | 845 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), value, &metadata), | 
|  | 846 | applyGainLUT(RgbWhite(), value, gainLUT)); | 
|  | 847 | EXPECT_RGB_NEAR(applyGain(RgbRed(), value, &metadata), | 
|  | 848 | applyGainLUT(RgbRed(), value, gainLUT)); | 
|  | 849 | EXPECT_RGB_NEAR(applyGain(RgbGreen(), value, &metadata), | 
|  | 850 | applyGainLUT(RgbGreen(), value, gainLUT)); | 
|  | 851 | EXPECT_RGB_NEAR(applyGain(RgbBlue(), value, &metadata), | 
|  | 852 | applyGainLUT(RgbBlue(), value, gainLUT)); | 
|  | 853 | EXPECT_RGB_EQ(applyGainLUT(RgbBlack(), value, gainLUT), | 
|  | 854 | applyGainLUT(RgbBlack(), value, gainLUTWithBoost)); | 
|  | 855 | EXPECT_RGB_EQ(applyGainLUT(RgbWhite(), value, gainLUT), | 
|  | 856 | applyGainLUT(RgbWhite(), value, gainLUTWithBoost)); | 
|  | 857 | EXPECT_RGB_EQ(applyGainLUT(RgbRed(), value, gainLUT), | 
|  | 858 | applyGainLUT(RgbRed(), value, gainLUTWithBoost)); | 
|  | 859 | EXPECT_RGB_EQ(applyGainLUT(RgbGreen(), value, gainLUT), | 
|  | 860 | applyGainLUT(RgbGreen(), value, gainLUTWithBoost)); | 
|  | 861 | EXPECT_RGB_EQ(applyGainLUT(RgbBlue(), value, gainLUT), | 
|  | 862 | applyGainLUT(RgbBlue(), value, gainLUTWithBoost)); | 
| Harish Mahendrakar | f25991f | 2022-12-16 11:57:44 -0800 | [diff] [blame] | 863 | } | 
|  | 864 | } | 
|  | 865 | } | 
|  | 866 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 867 | TEST_F(GainMapMathTest, PqTransferFunctionRoundtrip) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 868 | EXPECT_FLOAT_EQ(pqInvOetf(pqOetf(0.0f)), 0.0f); | 
|  | 869 | EXPECT_NEAR(pqInvOetf(pqOetf(0.01f)), 0.01f, ComparisonEpsilon()); | 
|  | 870 | EXPECT_NEAR(pqInvOetf(pqOetf(0.5f)), 0.5f, ComparisonEpsilon()); | 
|  | 871 | EXPECT_NEAR(pqInvOetf(pqOetf(0.99f)), 0.99f, ComparisonEpsilon()); | 
|  | 872 | EXPECT_FLOAT_EQ(pqInvOetf(pqOetf(1.0f)), 1.0f); | 
|  | 873 | } | 
|  | 874 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 875 | TEST_F(GainMapMathTest, ColorConversionLookup) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 876 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_UNSPECIFIED), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 877 | nullptr); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 878 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_BT709), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 879 | identityConversion); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 880 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_P3), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 881 | p3ToBt709); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 882 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_BT2100), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 883 | bt2100ToBt709); | 
|  | 884 |  | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 885 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_P3, ULTRAHDR_COLORGAMUT_UNSPECIFIED), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 886 | nullptr); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 887 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_P3, ULTRAHDR_COLORGAMUT_BT709), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 888 | bt709ToP3); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 889 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_P3, ULTRAHDR_COLORGAMUT_P3), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 890 | identityConversion); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 891 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_P3, ULTRAHDR_COLORGAMUT_BT2100), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 892 | bt2100ToP3); | 
|  | 893 |  | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 894 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT2100, ULTRAHDR_COLORGAMUT_UNSPECIFIED), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 895 | nullptr); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 896 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT2100, ULTRAHDR_COLORGAMUT_BT709), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 897 | bt709ToBt2100); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 898 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT2100, ULTRAHDR_COLORGAMUT_P3), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 899 | p3ToBt2100); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 900 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_BT2100, ULTRAHDR_COLORGAMUT_BT2100), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 901 | identityConversion); | 
|  | 902 |  | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 903 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_UNSPECIFIED, ULTRAHDR_COLORGAMUT_UNSPECIFIED), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 904 | nullptr); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 905 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_UNSPECIFIED, ULTRAHDR_COLORGAMUT_BT709), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 906 | nullptr); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 907 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_UNSPECIFIED, ULTRAHDR_COLORGAMUT_P3), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 908 | nullptr); | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 909 | EXPECT_EQ(getHdrConversionFn(ULTRAHDR_COLORGAMUT_UNSPECIFIED, ULTRAHDR_COLORGAMUT_BT2100), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 910 | nullptr); | 
|  | 911 | } | 
|  | 912 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 913 | TEST_F(GainMapMathTest, EncodeGain) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 914 | ultrahdr_metadata_struct metadata = { .maxContentBoost = 4.0f, | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 915 | .minContentBoost = 1.0f / 4.0f }; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 916 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 917 | EXPECT_EQ(encodeGain(0.0f, 0.0f, &metadata), 127); | 
|  | 918 | EXPECT_EQ(encodeGain(0.0f, 1.0f, &metadata), 127); | 
|  | 919 | EXPECT_EQ(encodeGain(1.0f, 0.0f, &metadata), 0); | 
|  | 920 | EXPECT_EQ(encodeGain(0.5f, 0.0f, &metadata), 0); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 921 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 922 | EXPECT_EQ(encodeGain(1.0f, 1.0f, &metadata), 127); | 
|  | 923 | EXPECT_EQ(encodeGain(1.0f, 4.0f, &metadata), 255); | 
|  | 924 | EXPECT_EQ(encodeGain(1.0f, 5.0f, &metadata), 255); | 
|  | 925 | EXPECT_EQ(encodeGain(4.0f, 1.0f, &metadata), 0); | 
|  | 926 | EXPECT_EQ(encodeGain(4.0f, 0.5f, &metadata), 0); | 
|  | 927 | EXPECT_EQ(encodeGain(1.0f, 2.0f, &metadata), 191); | 
|  | 928 | EXPECT_EQ(encodeGain(2.0f, 1.0f, &metadata), 63); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 929 |  | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 930 | metadata.maxContentBoost = 2.0f; | 
|  | 931 | metadata.minContentBoost = 1.0f / 2.0f; | 
|  | 932 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 933 | EXPECT_EQ(encodeGain(1.0f, 2.0f, &metadata), 255); | 
|  | 934 | EXPECT_EQ(encodeGain(2.0f, 1.0f, &metadata), 0); | 
|  | 935 | EXPECT_EQ(encodeGain(1.0f, 1.41421f, &metadata), 191); | 
|  | 936 | EXPECT_EQ(encodeGain(1.41421f, 1.0f, &metadata), 63); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 937 |  | 
|  | 938 | metadata.maxContentBoost = 8.0f; | 
|  | 939 | metadata.minContentBoost = 1.0f / 8.0f; | 
|  | 940 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 941 | EXPECT_EQ(encodeGain(1.0f, 8.0f, &metadata), 255); | 
|  | 942 | EXPECT_EQ(encodeGain(8.0f, 1.0f, &metadata), 0); | 
|  | 943 | EXPECT_EQ(encodeGain(1.0f, 2.82843f, &metadata), 191); | 
|  | 944 | EXPECT_EQ(encodeGain(2.82843f, 1.0f, &metadata), 63); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 945 |  | 
|  | 946 | metadata.maxContentBoost = 8.0f; | 
|  | 947 | metadata.minContentBoost = 1.0f; | 
|  | 948 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 949 | EXPECT_EQ(encodeGain(0.0f, 0.0f, &metadata), 0); | 
|  | 950 | EXPECT_EQ(encodeGain(1.0f, 0.0f, &metadata), 0); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 951 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 952 | EXPECT_EQ(encodeGain(1.0f, 1.0f, &metadata), 0); | 
|  | 953 | EXPECT_EQ(encodeGain(1.0f, 8.0f, &metadata), 255); | 
|  | 954 | EXPECT_EQ(encodeGain(1.0f, 4.0f, &metadata), 170); | 
|  | 955 | EXPECT_EQ(encodeGain(1.0f, 2.0f, &metadata), 85); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 956 |  | 
|  | 957 | metadata.maxContentBoost = 8.0f; | 
|  | 958 | metadata.minContentBoost = 0.5f; | 
|  | 959 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 960 | EXPECT_EQ(encodeGain(0.0f, 0.0f, &metadata), 63); | 
|  | 961 | EXPECT_EQ(encodeGain(1.0f, 0.0f, &metadata), 0); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 962 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 963 | EXPECT_EQ(encodeGain(1.0f, 1.0f, &metadata), 63); | 
|  | 964 | EXPECT_EQ(encodeGain(1.0f, 8.0f, &metadata), 255); | 
|  | 965 | EXPECT_EQ(encodeGain(1.0f, 4.0f, &metadata), 191); | 
|  | 966 | EXPECT_EQ(encodeGain(1.0f, 2.0f, &metadata), 127); | 
|  | 967 | EXPECT_EQ(encodeGain(1.0f, 0.7071f, &metadata), 31); | 
|  | 968 | EXPECT_EQ(encodeGain(1.0f, 0.5f, &metadata), 0); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 969 | } | 
|  | 970 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 971 | TEST_F(GainMapMathTest, ApplyGain) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 972 | ultrahdr_metadata_struct metadata = { .maxContentBoost = 4.0f, | 
| Nick Deakin | 0db53ee | 2023-05-19 17:14:45 -0400 | [diff] [blame] | 973 | .minContentBoost = 1.0f / 4.0f }; | 
| Dichen Zhang | c660570 | 2023-03-15 18:40:55 -0700 | [diff] [blame] | 974 | float displayBoost = metadata.maxContentBoost; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 975 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 976 | EXPECT_RGB_NEAR(applyGain(RgbBlack(), 0.0f, &metadata), RgbBlack()); | 
|  | 977 | EXPECT_RGB_NEAR(applyGain(RgbBlack(), 0.5f, &metadata), RgbBlack()); | 
|  | 978 | EXPECT_RGB_NEAR(applyGain(RgbBlack(), 1.0f, &metadata), RgbBlack()); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 979 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 980 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.0f, &metadata), RgbWhite() / 4.0f); | 
|  | 981 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.25f, &metadata), RgbWhite() / 2.0f); | 
|  | 982 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.5f, &metadata), RgbWhite()); | 
|  | 983 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.75f, &metadata), RgbWhite() * 2.0f); | 
|  | 984 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 1.0f, &metadata), RgbWhite() * 4.0f); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 985 |  | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 986 | metadata.maxContentBoost = 2.0f; | 
|  | 987 | metadata.minContentBoost = 1.0f / 2.0f; | 
|  | 988 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 989 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.0f, &metadata), RgbWhite() / 2.0f); | 
|  | 990 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.25f, &metadata), RgbWhite() / 1.41421f); | 
|  | 991 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.5f, &metadata), RgbWhite()); | 
|  | 992 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.75f, &metadata), RgbWhite() * 1.41421f); | 
|  | 993 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 1.0f, &metadata), RgbWhite() * 2.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 994 |  | 
|  | 995 | metadata.maxContentBoost = 8.0f; | 
|  | 996 | metadata.minContentBoost = 1.0f / 8.0f; | 
|  | 997 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 998 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.0f, &metadata), RgbWhite() / 8.0f); | 
|  | 999 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.25f, &metadata), RgbWhite() / 2.82843f); | 
|  | 1000 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.5f, &metadata), RgbWhite()); | 
|  | 1001 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.75f, &metadata), RgbWhite() * 2.82843f); | 
|  | 1002 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 1.0f, &metadata), RgbWhite() * 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1003 |  | 
|  | 1004 | metadata.maxContentBoost = 8.0f; | 
|  | 1005 | metadata.minContentBoost = 1.0f; | 
|  | 1006 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1007 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.0f, &metadata), RgbWhite()); | 
|  | 1008 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 1.0f / 3.0f, &metadata), RgbWhite() * 2.0f); | 
|  | 1009 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 2.0f / 3.0f, &metadata), RgbWhite() * 4.0f); | 
|  | 1010 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 1.0f, &metadata), RgbWhite() * 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1011 |  | 
|  | 1012 | metadata.maxContentBoost = 8.0f; | 
|  | 1013 | metadata.minContentBoost = 0.5f; | 
|  | 1014 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1015 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.0f, &metadata), RgbWhite() / 2.0f); | 
|  | 1016 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.25f, &metadata), RgbWhite()); | 
|  | 1017 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.5f, &metadata), RgbWhite() * 2.0f); | 
|  | 1018 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 0.75f, &metadata), RgbWhite() * 4.0f); | 
|  | 1019 | EXPECT_RGB_NEAR(applyGain(RgbWhite(), 1.0f, &metadata), RgbWhite() * 8.0f); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1020 |  | 
|  | 1021 | Color e = {{{ 0.0f, 0.5f, 1.0f }}}; | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1022 | metadata.maxContentBoost = 4.0f; | 
|  | 1023 | metadata.minContentBoost = 1.0f / 4.0f; | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1024 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1025 | EXPECT_RGB_NEAR(applyGain(e, 0.0f, &metadata), e / 4.0f); | 
|  | 1026 | EXPECT_RGB_NEAR(applyGain(e, 0.25f, &metadata), e / 2.0f); | 
|  | 1027 | EXPECT_RGB_NEAR(applyGain(e, 0.5f, &metadata), e); | 
|  | 1028 | EXPECT_RGB_NEAR(applyGain(e, 0.75f, &metadata), e * 2.0f); | 
|  | 1029 | EXPECT_RGB_NEAR(applyGain(e, 1.0f, &metadata), e * 4.0f); | 
| Dichen Zhang | c660570 | 2023-03-15 18:40:55 -0700 | [diff] [blame] | 1030 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1031 | EXPECT_RGB_EQ(applyGain(RgbBlack(), 1.0f, &metadata), | 
|  | 1032 | applyGain(RgbBlack(), 1.0f, &metadata, displayBoost)); | 
|  | 1033 | EXPECT_RGB_EQ(applyGain(RgbWhite(), 1.0f, &metadata), | 
|  | 1034 | applyGain(RgbWhite(), 1.0f, &metadata, displayBoost)); | 
|  | 1035 | EXPECT_RGB_EQ(applyGain(RgbRed(), 1.0f, &metadata), | 
|  | 1036 | applyGain(RgbRed(), 1.0f, &metadata, displayBoost)); | 
|  | 1037 | EXPECT_RGB_EQ(applyGain(RgbGreen(), 1.0f, &metadata), | 
|  | 1038 | applyGain(RgbGreen(), 1.0f, &metadata, displayBoost)); | 
|  | 1039 | EXPECT_RGB_EQ(applyGain(RgbBlue(), 1.0f, &metadata), | 
|  | 1040 | applyGain(RgbBlue(), 1.0f, &metadata, displayBoost)); | 
|  | 1041 | EXPECT_RGB_EQ(applyGain(e, 1.0f, &metadata), | 
|  | 1042 | applyGain(e, 1.0f, &metadata, displayBoost)); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1043 | } | 
|  | 1044 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1045 | TEST_F(GainMapMathTest, GetYuv420Pixel) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1046 | jpegr_uncompressed_struct image = Yuv420Image(); | 
|  | 1047 | Color (*colors)[4] = Yuv420Colors(); | 
|  | 1048 |  | 
|  | 1049 | for (size_t y = 0; y < 4; ++y) { | 
|  | 1050 | for (size_t x = 0; x < 4; ++x) { | 
|  | 1051 | EXPECT_YUV_NEAR(getYuv420Pixel(&image, x, y), colors[y][x]); | 
|  | 1052 | } | 
|  | 1053 | } | 
|  | 1054 | } | 
|  | 1055 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1056 | TEST_F(GainMapMathTest, GetP010Pixel) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1057 | jpegr_uncompressed_struct image = P010Image(); | 
|  | 1058 | Color (*colors)[4] = P010Colors(); | 
|  | 1059 |  | 
|  | 1060 | for (size_t y = 0; y < 4; ++y) { | 
|  | 1061 | for (size_t x = 0; x < 4; ++x) { | 
|  | 1062 | EXPECT_YUV_NEAR(getP010Pixel(&image, x, y), colors[y][x]); | 
|  | 1063 | } | 
|  | 1064 | } | 
|  | 1065 | } | 
|  | 1066 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1067 | TEST_F(GainMapMathTest, SampleYuv420) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1068 | jpegr_uncompressed_struct image = Yuv420Image(); | 
|  | 1069 | Color (*colors)[4] = Yuv420Colors(); | 
|  | 1070 |  | 
|  | 1071 | static const size_t kMapScaleFactor = 2; | 
|  | 1072 | for (size_t y = 0; y < 4 / kMapScaleFactor; ++y) { | 
|  | 1073 | for (size_t x = 0; x < 4 / kMapScaleFactor; ++x) { | 
|  | 1074 | Color min = {{{ 1.0f, 1.0f, 1.0f }}}; | 
|  | 1075 | Color max = {{{ -1.0f, -1.0f, -1.0f }}}; | 
|  | 1076 |  | 
|  | 1077 | for (size_t dy = 0; dy < kMapScaleFactor; ++dy) { | 
|  | 1078 | for (size_t dx = 0; dx < kMapScaleFactor; ++dx) { | 
|  | 1079 | Color e = colors[y * kMapScaleFactor + dy][x * kMapScaleFactor + dx]; | 
|  | 1080 | min = ColorMin(min, e); | 
|  | 1081 | max = ColorMax(max, e); | 
|  | 1082 | } | 
|  | 1083 | } | 
|  | 1084 |  | 
|  | 1085 | // Instead of reimplementing the sampling algorithm, confirm that the | 
|  | 1086 | // sample output is within the range of the min and max of the nearest | 
|  | 1087 | // points. | 
|  | 1088 | EXPECT_YUV_BETWEEN(sampleYuv420(&image, kMapScaleFactor, x, y), min, max); | 
|  | 1089 | } | 
|  | 1090 | } | 
|  | 1091 | } | 
|  | 1092 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1093 | TEST_F(GainMapMathTest, SampleP010) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1094 | jpegr_uncompressed_struct image = P010Image(); | 
|  | 1095 | Color (*colors)[4] = P010Colors(); | 
|  | 1096 |  | 
|  | 1097 | static const size_t kMapScaleFactor = 2; | 
|  | 1098 | for (size_t y = 0; y < 4 / kMapScaleFactor; ++y) { | 
|  | 1099 | for (size_t x = 0; x < 4 / kMapScaleFactor; ++x) { | 
|  | 1100 | Color min = {{{ 1.0f, 1.0f, 1.0f }}}; | 
|  | 1101 | Color max = {{{ -1.0f, -1.0f, -1.0f }}}; | 
|  | 1102 |  | 
|  | 1103 | for (size_t dy = 0; dy < kMapScaleFactor; ++dy) { | 
|  | 1104 | for (size_t dx = 0; dx < kMapScaleFactor; ++dx) { | 
|  | 1105 | Color e = colors[y * kMapScaleFactor + dy][x * kMapScaleFactor + dx]; | 
|  | 1106 | min = ColorMin(min, e); | 
|  | 1107 | max = ColorMax(max, e); | 
|  | 1108 | } | 
|  | 1109 | } | 
|  | 1110 |  | 
|  | 1111 | // Instead of reimplementing the sampling algorithm, confirm that the | 
|  | 1112 | // sample output is within the range of the min and max of the nearest | 
|  | 1113 | // points. | 
|  | 1114 | EXPECT_YUV_BETWEEN(sampleP010(&image, kMapScaleFactor, x, y), min, max); | 
|  | 1115 | } | 
|  | 1116 | } | 
|  | 1117 | } | 
|  | 1118 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1119 | TEST_F(GainMapMathTest, SampleMap) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1120 | jpegr_uncompressed_struct image = MapImage(); | 
|  | 1121 | float (*values)[4] = MapValues(); | 
|  | 1122 |  | 
|  | 1123 | static const size_t kMapScaleFactor = 2; | 
| Ram Mohan | fe723d6 | 2022-12-15 00:59:11 +0530 | [diff] [blame] | 1124 | ShepardsIDW idwTable(kMapScaleFactor); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1125 | for (size_t y = 0; y < 4 * kMapScaleFactor; ++y) { | 
|  | 1126 | for (size_t x = 0; x < 4 * kMapScaleFactor; ++x) { | 
|  | 1127 | size_t x_base = x / kMapScaleFactor; | 
|  | 1128 | size_t y_base = y / kMapScaleFactor; | 
|  | 1129 |  | 
|  | 1130 | float min = 1.0f; | 
|  | 1131 | float max = -1.0f; | 
|  | 1132 |  | 
|  | 1133 | min = fmin(min, values[y_base][x_base]); | 
|  | 1134 | max = fmax(max, values[y_base][x_base]); | 
|  | 1135 | if (y_base + 1 < 4) { | 
|  | 1136 | min = fmin(min, values[y_base + 1][x_base]); | 
|  | 1137 | max = fmax(max, values[y_base + 1][x_base]); | 
|  | 1138 | } | 
|  | 1139 | if (x_base + 1 < 4) { | 
|  | 1140 | min = fmin(min, values[y_base][x_base + 1]); | 
|  | 1141 | max = fmax(max, values[y_base][x_base + 1]); | 
|  | 1142 | } | 
|  | 1143 | if (y_base + 1 < 4 && x_base + 1 < 4) { | 
|  | 1144 | min = fmin(min, values[y_base + 1][x_base + 1]); | 
|  | 1145 | max = fmax(max, values[y_base + 1][x_base + 1]); | 
|  | 1146 | } | 
|  | 1147 |  | 
|  | 1148 | // Instead of reimplementing the sampling algorithm, confirm that the | 
|  | 1149 | // sample output is within the range of the min and max of the nearest | 
|  | 1150 | // points. | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1151 | EXPECT_THAT(sampleMap(&image, kMapScaleFactor, x, y), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1152 | testing::AllOf(testing::Ge(min), testing::Le(max))); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1153 | EXPECT_EQ(sampleMap(&image, kMapScaleFactor, x, y, idwTable), | 
|  | 1154 | sampleMap(&image, kMapScaleFactor, x, y)); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1155 | } | 
|  | 1156 | } | 
|  | 1157 | } | 
|  | 1158 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1159 | TEST_F(GainMapMathTest, ColorToRgba1010102) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1160 | EXPECT_EQ(colorToRgba1010102(RgbBlack()), 0x3 << 30); | 
|  | 1161 | EXPECT_EQ(colorToRgba1010102(RgbWhite()), 0xFFFFFFFF); | 
|  | 1162 | EXPECT_EQ(colorToRgba1010102(RgbRed()), 0x3 << 30 | 0x3ff); | 
|  | 1163 | EXPECT_EQ(colorToRgba1010102(RgbGreen()), 0x3 << 30 | 0x3ff << 10); | 
|  | 1164 | EXPECT_EQ(colorToRgba1010102(RgbBlue()), 0x3 << 30 | 0x3ff << 20); | 
|  | 1165 |  | 
|  | 1166 | Color e_gamma = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 1167 | EXPECT_EQ(colorToRgba1010102(e_gamma), | 
|  | 1168 | 0x3 << 30 | 
|  | 1169 | | static_cast<uint32_t>(0.1f * static_cast<float>(0x3ff)) | 
|  | 1170 | | static_cast<uint32_t>(0.2f * static_cast<float>(0x3ff)) << 10 | 
|  | 1171 | | static_cast<uint32_t>(0.3f * static_cast<float>(0x3ff)) << 20); | 
|  | 1172 | } | 
|  | 1173 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1174 | TEST_F(GainMapMathTest, ColorToRgbaF16) { | 
| Dichen Zhang | f106df7 | 2023-04-04 17:44:46 +0000 | [diff] [blame] | 1175 | EXPECT_EQ(colorToRgbaF16(RgbBlack()), ((uint64_t) 0x3C00) << 48); | 
|  | 1176 | EXPECT_EQ(colorToRgbaF16(RgbWhite()), 0x3C003C003C003C00); | 
|  | 1177 | EXPECT_EQ(colorToRgbaF16(RgbRed()),   (((uint64_t) 0x3C00) << 48) | ((uint64_t) 0x3C00)); | 
|  | 1178 | EXPECT_EQ(colorToRgbaF16(RgbGreen()), (((uint64_t) 0x3C00) << 48) | (((uint64_t) 0x3C00) << 16)); | 
|  | 1179 | EXPECT_EQ(colorToRgbaF16(RgbBlue()),  (((uint64_t) 0x3C00) << 48) | (((uint64_t) 0x3C00) << 32)); | 
|  | 1180 |  | 
|  | 1181 | Color e_gamma = {{{ 0.1f, 0.2f, 0.3f }}}; | 
|  | 1182 | EXPECT_EQ(colorToRgbaF16(e_gamma), 0x3C0034CD32662E66); | 
|  | 1183 | } | 
|  | 1184 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1185 | TEST_F(GainMapMathTest, Float32ToFloat16) { | 
| Dichen Zhang | f106df7 | 2023-04-04 17:44:46 +0000 | [diff] [blame] | 1186 | EXPECT_EQ(floatToHalf(0.1f), 0x2E66); | 
|  | 1187 | EXPECT_EQ(floatToHalf(0.0f), 0x0); | 
|  | 1188 | EXPECT_EQ(floatToHalf(1.0f), 0x3C00); | 
|  | 1189 | EXPECT_EQ(floatToHalf(-1.0f), 0xBC00); | 
|  | 1190 | EXPECT_EQ(floatToHalf(0x1.fffffep127f), 0x7FFF);  // float max | 
|  | 1191 | EXPECT_EQ(floatToHalf(-0x1.fffffep127f), 0xFFFF);  // float min | 
|  | 1192 | EXPECT_EQ(floatToHalf(0x1.0p-126f), 0x0);  // float zero | 
|  | 1193 | } | 
|  | 1194 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1195 | TEST_F(GainMapMathTest, GenerateMapLuminanceSrgb) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1196 | EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvBlack(), srgbLuminance), | 
|  | 1197 | 0.0f); | 
|  | 1198 | EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvWhite(), srgbLuminance), | 
|  | 1199 | kSdrWhiteNits); | 
|  | 1200 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvRed(), srgbLuminance), | 
|  | 1201 | srgbLuminance(RgbRed()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1202 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvGreen(), srgbLuminance), | 
|  | 1203 | srgbLuminance(RgbGreen()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1204 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvBlue(), srgbLuminance), | 
|  | 1205 | srgbLuminance(RgbBlue()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1206 | } | 
|  | 1207 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1208 | TEST_F(GainMapMathTest, GenerateMapLuminanceSrgbP3) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1209 | EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvBlack(), p3Luminance), | 
|  | 1210 | 0.0f); | 
|  | 1211 | EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvWhite(), p3Luminance), | 
|  | 1212 | kSdrWhiteNits); | 
|  | 1213 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvRed(), p3Luminance), | 
|  | 1214 | p3Luminance(RgbRed()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1215 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvGreen(), p3Luminance), | 
|  | 1216 | p3Luminance(RgbGreen()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1217 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvBlue(), p3Luminance), | 
|  | 1218 | p3Luminance(RgbBlue()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1219 | } | 
|  | 1220 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1221 | TEST_F(GainMapMathTest, GenerateMapLuminanceSrgbBt2100) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1222 | EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvBlack(), bt2100Luminance), | 
|  | 1223 | 0.0f); | 
|  | 1224 | EXPECT_FLOAT_EQ(SrgbYuvToLuminance(YuvWhite(), bt2100Luminance), | 
|  | 1225 | kSdrWhiteNits); | 
|  | 1226 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvRed(), bt2100Luminance), | 
|  | 1227 | bt2100Luminance(RgbRed()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1228 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvGreen(), bt2100Luminance), | 
|  | 1229 | bt2100Luminance(RgbGreen()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1230 | EXPECT_NEAR(SrgbYuvToLuminance(SrgbYuvBlue(), bt2100Luminance), | 
|  | 1231 | bt2100Luminance(RgbBlue()) * kSdrWhiteNits, LuminanceEpsilon()); | 
|  | 1232 | } | 
|  | 1233 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1234 | TEST_F(GainMapMathTest, GenerateMapLuminanceHlg) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1235 | EXPECT_FLOAT_EQ(Bt2100YuvToLuminance(YuvBlack(), hlgInvOetf, identityConversion, | 
|  | 1236 | bt2100Luminance, kHlgMaxNits), | 
|  | 1237 | 0.0f); | 
|  | 1238 | EXPECT_FLOAT_EQ(Bt2100YuvToLuminance(YuvWhite(), hlgInvOetf, identityConversion, | 
|  | 1239 | bt2100Luminance, kHlgMaxNits), | 
|  | 1240 | kHlgMaxNits); | 
|  | 1241 | EXPECT_NEAR(Bt2100YuvToLuminance(Bt2100YuvRed(), hlgInvOetf, identityConversion, | 
|  | 1242 | bt2100Luminance, kHlgMaxNits), | 
|  | 1243 | bt2100Luminance(RgbRed()) * kHlgMaxNits, LuminanceEpsilon()); | 
|  | 1244 | EXPECT_NEAR(Bt2100YuvToLuminance(Bt2100YuvGreen(), hlgInvOetf, identityConversion, | 
|  | 1245 | bt2100Luminance, kHlgMaxNits), | 
|  | 1246 | bt2100Luminance(RgbGreen()) * kHlgMaxNits, LuminanceEpsilon()); | 
|  | 1247 | EXPECT_NEAR(Bt2100YuvToLuminance(Bt2100YuvBlue(), hlgInvOetf, identityConversion, | 
|  | 1248 | bt2100Luminance, kHlgMaxNits), | 
|  | 1249 | bt2100Luminance(RgbBlue()) * kHlgMaxNits, LuminanceEpsilon()); | 
|  | 1250 | } | 
|  | 1251 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1252 | TEST_F(GainMapMathTest, GenerateMapLuminancePq) { | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1253 | EXPECT_FLOAT_EQ(Bt2100YuvToLuminance(YuvBlack(), pqInvOetf, identityConversion, | 
|  | 1254 | bt2100Luminance, kPqMaxNits), | 
|  | 1255 | 0.0f); | 
|  | 1256 | EXPECT_FLOAT_EQ(Bt2100YuvToLuminance(YuvWhite(), pqInvOetf, identityConversion, | 
|  | 1257 | bt2100Luminance, kPqMaxNits), | 
|  | 1258 | kPqMaxNits); | 
|  | 1259 | EXPECT_NEAR(Bt2100YuvToLuminance(Bt2100YuvRed(), pqInvOetf, identityConversion, | 
|  | 1260 | bt2100Luminance, kPqMaxNits), | 
|  | 1261 | bt2100Luminance(RgbRed()) * kPqMaxNits, LuminanceEpsilon()); | 
|  | 1262 | EXPECT_NEAR(Bt2100YuvToLuminance(Bt2100YuvGreen(), pqInvOetf, identityConversion, | 
|  | 1263 | bt2100Luminance, kPqMaxNits), | 
|  | 1264 | bt2100Luminance(RgbGreen()) * kPqMaxNits, LuminanceEpsilon()); | 
|  | 1265 | EXPECT_NEAR(Bt2100YuvToLuminance(Bt2100YuvBlue(), pqInvOetf, identityConversion, | 
|  | 1266 | bt2100Luminance, kPqMaxNits), | 
|  | 1267 | bt2100Luminance(RgbBlue()) * kPqMaxNits, LuminanceEpsilon()); | 
|  | 1268 | } | 
|  | 1269 |  | 
| Dichen Zhang | 10959a4 | 2023-04-10 16:28:16 -0700 | [diff] [blame] | 1270 | TEST_F(GainMapMathTest, ApplyMap) { | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 1271 | ultrahdr_metadata_struct metadata = { .maxContentBoost = 8.0f, | 
| Dichen Zhang | e286f1c | 2023-03-14 00:22:00 +0000 | [diff] [blame] | 1272 | .minContentBoost = 1.0f / 8.0f }; | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1273 |  | 
|  | 1274 | EXPECT_RGB_EQ(Recover(YuvWhite(), 1.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1275 | RgbWhite() * 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1276 | EXPECT_RGB_EQ(Recover(YuvBlack(), 1.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1277 | RgbBlack()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1278 | EXPECT_RGB_CLOSE(Recover(SrgbYuvRed(), 1.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1279 | RgbRed() * 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1280 | EXPECT_RGB_CLOSE(Recover(SrgbYuvGreen(), 1.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1281 | RgbGreen() * 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1282 | EXPECT_RGB_CLOSE(Recover(SrgbYuvBlue(), 1.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1283 | RgbBlue() * 8.0f); | 
|  | 1284 |  | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1285 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.75f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1286 | RgbWhite() * sqrt(8.0f)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1287 | EXPECT_RGB_EQ(Recover(YuvBlack(), 0.75f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1288 | RgbBlack()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1289 | EXPECT_RGB_CLOSE(Recover(SrgbYuvRed(), 0.75f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1290 | RgbRed() * sqrt(8.0f)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1291 | EXPECT_RGB_CLOSE(Recover(SrgbYuvGreen(), 0.75f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1292 | RgbGreen() * sqrt(8.0f)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1293 | EXPECT_RGB_CLOSE(Recover(SrgbYuvBlue(), 0.75f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1294 | RgbBlue() * sqrt(8.0f)); | 
|  | 1295 |  | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1296 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.5f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1297 | RgbWhite()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1298 | EXPECT_RGB_EQ(Recover(YuvBlack(), 0.5f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1299 | RgbBlack()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1300 | EXPECT_RGB_CLOSE(Recover(SrgbYuvRed(), 0.5f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1301 | RgbRed()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1302 | EXPECT_RGB_CLOSE(Recover(SrgbYuvGreen(), 0.5f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1303 | RgbGreen()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1304 | EXPECT_RGB_CLOSE(Recover(SrgbYuvBlue(), 0.5f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1305 | RgbBlue()); | 
|  | 1306 |  | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1307 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.25f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1308 | RgbWhite() / sqrt(8.0f)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1309 | EXPECT_RGB_EQ(Recover(YuvBlack(), 0.25f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1310 | RgbBlack()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1311 | EXPECT_RGB_CLOSE(Recover(SrgbYuvRed(), 0.25f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1312 | RgbRed() / sqrt(8.0f)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1313 | EXPECT_RGB_CLOSE(Recover(SrgbYuvGreen(), 0.25f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1314 | RgbGreen() / sqrt(8.0f)); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1315 | EXPECT_RGB_CLOSE(Recover(SrgbYuvBlue(), 0.25f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1316 | RgbBlue() / sqrt(8.0f)); | 
|  | 1317 |  | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1318 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1319 | RgbWhite() / 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1320 | EXPECT_RGB_EQ(Recover(YuvBlack(), 0.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1321 | RgbBlack()); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1322 | EXPECT_RGB_CLOSE(Recover(SrgbYuvRed(), 0.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1323 | RgbRed() / 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1324 | EXPECT_RGB_CLOSE(Recover(SrgbYuvGreen(), 0.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1325 | RgbGreen() / 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1326 | EXPECT_RGB_CLOSE(Recover(SrgbYuvBlue(), 0.0f, &metadata), | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1327 | RgbBlue() / 8.0f); | 
| Nick Deakin | d19e576 | 2023-02-10 15:39:08 -0500 | [diff] [blame] | 1328 |  | 
|  | 1329 | metadata.maxContentBoost = 8.0f; | 
|  | 1330 | metadata.minContentBoost = 1.0f; | 
|  | 1331 |  | 
|  | 1332 | EXPECT_RGB_EQ(Recover(YuvWhite(), 1.0f, &metadata), | 
|  | 1333 | RgbWhite() * 8.0f); | 
|  | 1334 | EXPECT_RGB_EQ(Recover(YuvWhite(), 2.0f / 3.0f, &metadata), | 
|  | 1335 | RgbWhite() * 4.0f); | 
|  | 1336 | EXPECT_RGB_EQ(Recover(YuvWhite(), 1.0f / 3.0f, &metadata), | 
|  | 1337 | RgbWhite() * 2.0f); | 
|  | 1338 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.0f, &metadata), | 
|  | 1339 | RgbWhite()); | 
|  | 1340 |  | 
|  | 1341 | metadata.maxContentBoost = 8.0f; | 
|  | 1342 | metadata.minContentBoost = 0.5f;; | 
|  | 1343 |  | 
|  | 1344 | EXPECT_RGB_EQ(Recover(YuvWhite(), 1.0f, &metadata), | 
|  | 1345 | RgbWhite() * 8.0f); | 
|  | 1346 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.75, &metadata), | 
|  | 1347 | RgbWhite() * 4.0f); | 
|  | 1348 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.5f, &metadata), | 
|  | 1349 | RgbWhite() * 2.0f); | 
|  | 1350 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.25f, &metadata), | 
|  | 1351 | RgbWhite()); | 
|  | 1352 | EXPECT_RGB_EQ(Recover(YuvWhite(), 0.0f, &metadata), | 
|  | 1353 | RgbWhite() / 2.0f); | 
| Nick Deakin | 65f492a | 2022-11-29 22:47:40 -0500 | [diff] [blame] | 1354 | } | 
|  | 1355 |  | 
| Dichen Zhang | dbceb0e | 2023-04-14 19:03:18 +0000 | [diff] [blame] | 1356 | } // namespace android::ultrahdr |