alpha_test.cc (4262B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "lib/jxl/alpha.h" 7 8 #include <array> 9 10 #include "lib/jxl/base/common.h" 11 #include "lib/jxl/testing.h" 12 13 namespace jxl { 14 namespace { 15 16 AlphaBlendingInputLayer makeAbil(const Color& rgb, const float& a) { 17 const float* data = rgb.data(); 18 return {data, data + 1, data + 2, &a}; 19 } 20 21 AlphaBlendingOutput makeAbo(Color& rgb, float& a) { 22 float* data = rgb.data(); 23 return {data, data + 1, data + 2, &a}; 24 } 25 26 TEST(AlphaTest, BlendingWithNonPremultiplied) { 27 const Color bg_rgb{100, 110, 120}; 28 const float bg_a = 180.f / 255; 29 const Color fg_rgb{25, 21, 23}; 30 const float fg_a = 15420.f / 65535; 31 const float fg_a2 = 2.0f; 32 Color out_rgb; 33 float out_a; 34 PerformAlphaBlending( 35 /*bg=*/makeAbil(bg_rgb, bg_a), 36 /*fg=*/makeAbil(fg_rgb, fg_a), 37 /*out=*/makeAbo(out_rgb, out_a), 1, 38 /*alpha_is_premultiplied=*/false, /*clamp=*/false); 39 EXPECT_ARRAY_NEAR(out_rgb, (Color{77.2f, 83.0f, 90.6f}), 0.05f); 40 EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5); 41 PerformAlphaBlending( 42 /*bg=*/makeAbil(bg_rgb, bg_a), 43 /*fg=*/makeAbil(fg_rgb, fg_a2), 44 /*out=*/makeAbo(out_rgb, out_a), 1, 45 /*alpha_is_premultiplied=*/false, /*clamp=*/true); 46 EXPECT_ARRAY_NEAR(out_rgb, fg_rgb, 0.05f); 47 EXPECT_NEAR(out_a, 1.0f, 1e-5); 48 } 49 50 TEST(AlphaTest, BlendingWithPremultiplied) { 51 const Color bg_rgb{100, 110, 120}; 52 const float bg_a = 180.f / 255; 53 const Color fg_rgb{25, 21, 23}; 54 const float fg_a = 15420.f / 65535; 55 const float fg_a2 = 2.0f; 56 Color out_rgb; 57 float out_a; 58 PerformAlphaBlending( 59 /*bg=*/makeAbil(bg_rgb, bg_a), 60 /*fg=*/makeAbil(fg_rgb, fg_a), 61 /*out=*/makeAbo(out_rgb, out_a), 1, 62 /*alpha_is_premultiplied=*/true, /*clamp=*/false); 63 EXPECT_ARRAY_NEAR(out_rgb, (Color{101.5f, 105.1f, 114.8f}), 0.05f); 64 EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5); 65 PerformAlphaBlending( 66 /*bg=*/makeAbil(bg_rgb, bg_a), 67 /*fg=*/makeAbil(fg_rgb, fg_a2), 68 /*out=*/makeAbo(out_rgb, out_a), 1, 69 /*alpha_is_premultiplied=*/true, /*clamp=*/true); 70 EXPECT_ARRAY_NEAR(out_rgb, fg_rgb, 0.05f); 71 EXPECT_NEAR(out_a, 1.0f, 1e-5); 72 } 73 74 TEST(AlphaTest, Mul) { 75 const float bg = 100; 76 const float fg = 25; 77 float out; 78 PerformMulBlending(&bg, &fg, &out, 1, /*clamp=*/false); 79 EXPECT_NEAR(out, fg * bg, .05f); 80 PerformMulBlending(&bg, &fg, &out, 1, /*clamp=*/true); 81 EXPECT_NEAR(out, bg, .05f); 82 } 83 84 TEST(AlphaTest, PremultiplyAndUnpremultiply) { 85 using F4 = std::array<float, 4>; 86 const F4 alpha{0.f, 63.f / 255, 127.f / 255, 1.f}; 87 F4 r{120, 130, 140, 150}; 88 F4 g{124, 134, 144, 154}; 89 F4 b{127, 137, 147, 157}; 90 91 PremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size()); 92 EXPECT_ARRAY_NEAR(r, (F4{0.0f, 130 * 63.f / 255, 140 * 127.f / 255, 150}), 93 1e-5f); 94 EXPECT_ARRAY_NEAR(g, (F4{0.0f, 134 * 63.f / 255, 144 * 127.f / 255, 154}), 95 1e-5f); 96 EXPECT_ARRAY_NEAR(b, (F4{0.0f, 137 * 63.f / 255, 147 * 127.f / 255, 157}), 97 1e-5f); 98 99 UnpremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size()); 100 EXPECT_ARRAY_NEAR(r, (F4{120, 130, 140, 150}), 1e-4f); 101 EXPECT_ARRAY_NEAR(g, (F4{124, 134, 144, 154}), 1e-4f); 102 EXPECT_ARRAY_NEAR(b, (F4{127, 137, 147, 157}), 1e-4f); 103 } 104 105 TEST(AlphaTest, UnpremultiplyAndPremultiply) { 106 using F4 = std::array<float, 4>; 107 const F4 alpha{0.f, 63.f / 255, 127.f / 255, 1.f}; 108 F4 r{50, 60, 70, 80}; 109 F4 g{54, 64, 74, 84}; 110 F4 b{57, 67, 77, 87}; 111 112 UnpremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size()); 113 EXPECT_ARRAY_NEAR( 114 r, (F4{50.0f * (1 << 26), 60 * 255.f / 63, 70 * 255.f / 127, 80}), 1e-4f); 115 EXPECT_ARRAY_NEAR( 116 g, (F4{54.0f * (1 << 26), 64 * 255.f / 63, 74 * 255.f / 127, 84}), 1e-4f); 117 EXPECT_ARRAY_NEAR( 118 b, (F4{57.0f * (1 << 26), 67 * 255.f / 63, 77 * 255.f / 127, 87}), 1e-4f); 119 120 PremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size()); 121 EXPECT_ARRAY_NEAR(r, (F4{50, 60, 70, 80}), 1e-4); 122 EXPECT_ARRAY_NEAR(g, (F4{54, 64, 74, 84}), 1e-4); 123 EXPECT_ARRAY_NEAR(b, (F4{57, 67, 77, 87}), 1e-4); 124 } 125 126 } // namespace 127 } // namespace jxl