Add UnPreMultiplyColor()
Add a Skia-only utility function to un-premultiply FX_ABGR_STRUCT and
similar structs.
Bug: 42271020
Change-Id: Ibf0cc83f1845b8a05b0b0b10a4ab115b3020c737
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/122892
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/dib/fx_dib.h b/core/fxge/dib/fx_dib.h
index 10717f8..fea7565 100644
--- a/core/fxge/dib/fx_dib.h
+++ b/core/fxge/dib/fx_dib.h
@@ -256,6 +256,26 @@
output.red = static_cast<float>(input.red) * input.alpha / 255.0f;
return output;
}
+
+template <typename T>
+T UnPreMultiplyColor(const T& input) {
+ if (input.alpha == 255) {
+ return input;
+ }
+
+ T output;
+ output.alpha = input.alpha;
+ if (input.alpha == 0) {
+ output.blue = 0;
+ output.green = 0;
+ output.red = 0;
+ } else {
+ output.blue = static_cast<float>(input.blue) * 255.0f / input.alpha;
+ output.green = static_cast<float>(input.green) * 255.0f / input.alpha;
+ output.red = static_cast<float>(input.red) * 255.0f / input.alpha;
+ }
+ return output;
+}
#endif // defined(PDF_USE_SKIA)
#endif // CORE_FXGE_DIB_FX_DIB_H_
diff --git a/core/fxge/dib/fx_dib_unittest.cpp b/core/fxge/dib/fx_dib_unittest.cpp
index 6db5793..11b773b 100644
--- a/core/fxge/dib/fx_dib_unittest.cpp
+++ b/core/fxge/dib/fx_dib_unittest.cpp
@@ -56,4 +56,52 @@
EXPECT_FLOAT_EQ(0.0f, result_f.blue);
EXPECT_FLOAT_EQ(255.0f, result_f.alpha);
}
+
+TEST(PreMultiplyTest, UnPreMultiplyColor) {
+ FX_ABGR_STRUCT<uint8_t> result = UnPreMultiplyColor(FX_ABGR_STRUCT<uint8_t>{
+ .alpha = 192, .blue = 0, .green = 192, .red = 100});
+ EXPECT_EQ(192, result.alpha);
+ EXPECT_EQ(0, result.blue);
+ EXPECT_EQ(255, result.green);
+ EXPECT_EQ(132, result.red);
+
+ FX_RGBA_STRUCT<float> result_f = UnPreMultiplyColor(
+ FX_RGBA_STRUCT<float>{.red = 100, .green = 192, .blue = 0, .alpha = 192});
+ EXPECT_FLOAT_EQ(132.8125f, result_f.red);
+ EXPECT_FLOAT_EQ(255.0f, result_f.green);
+ EXPECT_FLOAT_EQ(0.0f, result_f.blue);
+ EXPECT_FLOAT_EQ(192.0f, result_f.alpha);
+}
+
+TEST(PreMultiplyTest, UnPreMultiplyColorFullyTransparent) {
+ FX_ABGR_STRUCT<uint8_t> result = UnPreMultiplyColor(
+ FX_ABGR_STRUCT<uint8_t>{.alpha = 0, .blue = 0, .green = 0, .red = 0});
+ EXPECT_EQ(0, result.alpha);
+ EXPECT_EQ(0, result.blue);
+ EXPECT_EQ(0, result.green);
+ EXPECT_EQ(0, result.red);
+
+ FX_RGBA_STRUCT<float> result_f = UnPreMultiplyColor(
+ FX_RGBA_STRUCT<float>{.red = 0, .green = 0, .blue = 0, .alpha = 0});
+ EXPECT_FLOAT_EQ(0.0f, result_f.red);
+ EXPECT_FLOAT_EQ(0.0f, result_f.green);
+ EXPECT_FLOAT_EQ(0.0f, result_f.blue);
+ EXPECT_FLOAT_EQ(0.0f, result_f.alpha);
+}
+
+TEST(PreMultiplyTest, UnPreMultiplyColorFullyOpaque) {
+ FX_ABGR_STRUCT<uint8_t> result = UnPreMultiplyColor(FX_ABGR_STRUCT<uint8_t>{
+ .alpha = 255, .blue = 0, .green = 255, .red = 100});
+ EXPECT_EQ(255, result.alpha);
+ EXPECT_EQ(0, result.blue);
+ EXPECT_EQ(255, result.green);
+ EXPECT_EQ(100, result.red);
+
+ FX_RGBA_STRUCT<float> result_f = UnPreMultiplyColor(
+ FX_RGBA_STRUCT<float>{.red = 100, .green = 255, .blue = 0, .alpha = 255});
+ EXPECT_FLOAT_EQ(100.0f, result_f.red);
+ EXPECT_FLOAT_EQ(255.0f, result_f.green);
+ EXPECT_FLOAT_EQ(0.0f, result_f.blue);
+ EXPECT_FLOAT_EQ(255.0f, result_f.alpha);
+}
#endif // defined(PDF_USE_SKIA)