add unit test for clamp-before-premul
Bug: chromium:867813
Bug: chromium:862908
Change-Id: I79a82b6637c8a707844642b9bce4444bb85828b5
Reviewed-on: https://skia-review.googlesource.com/144295
Auto-Submit: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/skcms.cc b/skcms.cc
index 3595088..6fb4af9 100644
--- a/skcms.cc
+++ b/skcms.cc
@@ -2230,7 +2230,6 @@
//
// E.g. r = 1.1, a = 0.5 would fit fine in fixed point after premul (ra=0.55,a=0.5),
// but would be carrying r > 1, which is really unexpected for downstream consumers.
- // TODO(mtklein): add a unit test
if (dstFmt < skcms_PixelFormat_RGB_hhh) {
*ops++ = Op_clamp;
}
diff --git a/tests.c b/tests.c
index 09669f7..cef8ea9 100644
--- a/tests.c
+++ b/tests.c
@@ -1086,6 +1086,46 @@
expect(skcms_ApproximatelyEqualProfiles(&p, &srgb));
}
+static void test_Clamp() {
+ // Test that we clamp out-of-gamut values when converting to fixed point,
+ // not just to byte value range but also to gamut (for compatibility with
+ // older systems).
+
+ void* dp3_ptr;
+ size_t dp3_len;
+ expect(load_file("profiles/mobile/Display_P3_parametric.icc", &dp3_ptr, &dp3_len));
+
+ // Here's the basic premise of the test: sRGB can't represent P3's full green,
+ // but if we scale it by 50% alpha, it would "fit" in a byte. We want to avoid that.
+ skcms_ICCProfile src,
+ dst = *skcms_sRGB_profile();
+ skcms_Parse(dp3_ptr, dp3_len, &src);
+ uint8_t rgba[] = { 0, 255, 0, 127 };
+
+ // First double check that the green channel is out of gamut by transforming to float.
+ float flts[4];
+ skcms_Transform(rgba, skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul, &src,
+ flts, skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul, &dst,
+ 1);
+ expect(flts[0] < 0); // A typical out-of-gamut green. r,b are negative, and g > 1.
+ expect(flts[1] > 1);
+ expect(flts[2] < 0);
+ expect(flts[3] == 127*(1/255.0f));
+
+ // Now the real test, making sure we clamp that green channel to 1.0 before premul.
+ skcms_Transform(rgba, skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul , &src,
+ rgba, skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_PremulAsEncoded, &dst,
+ 1);
+
+ expect(rgba[0] == 0);
+ expect(rgba[1] == 127); // would be 129 if we clamped after premul
+ expect(rgba[2] == 0);
+ expect(rgba[3] == 127);
+
+
+ free(dp3_ptr);
+}
+
int main(int argc, char** argv) {
bool regenTestData = false;
for (int i = 1; i < argc; ++i) {
@@ -1115,6 +1155,7 @@
test_MakeUsableAsDestinationAdobe();
test_PrimariesToXYZ();
test_Programmatic_sRGB();
+ test_Clamp();
#if 0
test_CLUT();
#endif