alpha_test.cc (5507B)
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 "lib/jxl/test_utils.h" 9 #include "lib/jxl/testing.h" 10 11 namespace jxl { 12 namespace { 13 14 using ::testing::_; 15 using ::testing::ElementsAre; 16 using ::testing::FloatNear; 17 18 TEST(AlphaTest, BlendingWithNonPremultiplied) { 19 const float bg_rgb[3] = {100, 110, 120}; 20 const float bg_a = 180.f / 255; 21 const float fg_rgb[3] = {25, 21, 23}; 22 const float fg_a = 15420.f / 65535; 23 const float fg_a2 = 2.0f; 24 float out_rgb[3]; 25 float out_a; 26 PerformAlphaBlending( 27 /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, 28 /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a}, 29 /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, 30 /*alpha_is_premultiplied=*/false, /*clamp=*/false); 31 EXPECT_THAT(out_rgb, 32 ElementsAre(FloatNear(77.2f, .05f), FloatNear(83.0f, .05f), 33 FloatNear(90.6f, .05f))); 34 EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5); 35 PerformAlphaBlending( 36 /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, 37 /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a2}, 38 /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, 39 /*alpha_is_premultiplied=*/false, /*clamp=*/true); 40 EXPECT_THAT(out_rgb, ElementsAre(FloatNear(fg_rgb[0], .05f), 41 FloatNear(fg_rgb[1], .05f), 42 FloatNear(fg_rgb[2], .05f))); 43 EXPECT_NEAR(out_a, 1.0f, 1e-5); 44 } 45 46 TEST(AlphaTest, BlendingWithPremultiplied) { 47 const float bg_rgb[3] = {100, 110, 120}; 48 const float bg_a = 180.f / 255; 49 const float fg_rgb[3] = {25, 21, 23}; 50 const float fg_a = 15420.f / 65535; 51 const float fg_a2 = 2.0f; 52 float out_rgb[3]; 53 float out_a; 54 PerformAlphaBlending( 55 /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, 56 /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a}, 57 /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, 58 /*alpha_is_premultiplied=*/true, /*clamp=*/false); 59 EXPECT_THAT(out_rgb, 60 ElementsAre(FloatNear(101.5f, .05f), FloatNear(105.1f, .05f), 61 FloatNear(114.8f, .05f))); 62 EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5); 63 PerformAlphaBlending( 64 /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, 65 /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a2}, 66 /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, 67 /*alpha_is_premultiplied=*/true, /*clamp=*/true); 68 EXPECT_THAT(out_rgb, ElementsAre(FloatNear(fg_rgb[0], .05f), 69 FloatNear(fg_rgb[1], .05f), 70 FloatNear(fg_rgb[2], .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_THAT(out, FloatNear(fg * bg, .05f)); 80 PerformMulBlending(&bg, &fg, &out, 1, /*clamp=*/true); 81 EXPECT_THAT(out, FloatNear(bg, .05f)); 82 } 83 84 TEST(AlphaTest, PremultiplyAndUnpremultiply) { 85 const float alpha[] = {0.f, 63.f / 255, 127.f / 255, 1.f}; 86 float r[] = {120, 130, 140, 150}; 87 float g[] = {124, 134, 144, 154}; 88 float b[] = {127, 137, 147, 157}; 89 90 PremultiplyAlpha(r, g, b, alpha, 4); 91 EXPECT_THAT( 92 r, ElementsAre(FloatNear(0.f, 1e-5f), FloatNear(130 * 63.f / 255, 1e-5f), 93 FloatNear(140 * 127.f / 255, 1e-5f), 150)); 94 EXPECT_THAT( 95 g, ElementsAre(FloatNear(0.f, 1e-5f), FloatNear(134 * 63.f / 255, 1e-5f), 96 FloatNear(144 * 127.f / 255, 1e-5f), 154)); 97 EXPECT_THAT( 98 b, ElementsAre(FloatNear(0.f, 1e-5f), FloatNear(137 * 63.f / 255, 1e-5f), 99 FloatNear(147 * 127.f / 255, 1e-5f), 157)); 100 101 UnpremultiplyAlpha(r, g, b, alpha, 4); 102 EXPECT_THAT(r, ElementsAre(FloatNear(120, 1e-4f), FloatNear(130, 1e-4f), 103 FloatNear(140, 1e-4f), FloatNear(150, 1e-4f))); 104 EXPECT_THAT(g, ElementsAre(FloatNear(124, 1e-4f), FloatNear(134, 1e-4f), 105 FloatNear(144, 1e-4f), FloatNear(154, 1e-4f))); 106 EXPECT_THAT(b, ElementsAre(FloatNear(127, 1e-4f), FloatNear(137, 1e-4f), 107 FloatNear(147, 1e-4f), FloatNear(157, 1e-4f))); 108 } 109 110 TEST(AlphaTest, UnpremultiplyAndPremultiply) { 111 const float alpha[] = {0.f, 63.f / 255, 127.f / 255, 1.f}; 112 float r[] = {50, 60, 70, 80}; 113 float g[] = {54, 64, 74, 84}; 114 float b[] = {57, 67, 77, 87}; 115 116 UnpremultiplyAlpha(r, g, b, alpha, 4); 117 EXPECT_THAT(r, ElementsAre(_, FloatNear(60 * 255.f / 63, 1e-4f), 118 FloatNear(70 * 255.f / 127, 1e-4f), 80)); 119 EXPECT_THAT(g, ElementsAre(_, FloatNear(64 * 255.f / 63, 1e-4f), 120 FloatNear(74 * 255.f / 127, 1e-4f), 84)); 121 EXPECT_THAT(b, ElementsAre(_, FloatNear(67 * 255.f / 63, 1e-4f), 122 FloatNear(77 * 255.f / 127, 1e-4f), 87)); 123 124 PremultiplyAlpha(r, g, b, alpha, 4); 125 EXPECT_THAT(r, ElementsAre(FloatNear(50, 1e-4f), FloatNear(60, 1e-4f), 126 FloatNear(70, 1e-4f), FloatNear(80, 1e-4f))); 127 EXPECT_THAT(g, ElementsAre(FloatNear(54, 1e-4f), FloatNear(64, 1e-4f), 128 FloatNear(74, 1e-4f), FloatNear(84, 1e-4f))); 129 EXPECT_THAT(b, ElementsAre(FloatNear(57, 1e-4f), FloatNear(67, 1e-4f), 130 FloatNear(77, 1e-4f), FloatNear(87, 1e-4f))); 131 } 132 133 } // namespace 134 } // namespace jxl