From a7122d7a85b25887d0af60119e2e60036acaf8e6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 16 Jan 2019 21:02:01 +0000 Subject: [PATCH] revise XYZ2CMYK fallback path better epsilon detect, add a test --- libvips/colour/XYZ2CMYK.c | 36 ++++++++++++++++------------------ test/test-suite/test_colour.py | 9 ++++++++- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/libvips/colour/XYZ2CMYK.c b/libvips/colour/XYZ2CMYK.c index 475f9235..6d03a7f1 100644 --- a/libvips/colour/XYZ2CMYK.c +++ b/libvips/colour/XYZ2CMYK.c @@ -150,26 +150,24 @@ vips_XYZ2CMYK_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) float g = p[1] / VIPS_D65_Y0; float b = p[2] / VIPS_D65_Z0; - float c, m, y, k; + float c = 1.0 - r; + float m = 1.0 - g; + float y = 1.0 - b; + float k = VIPS_MIN( c, VIPS_MIN( m, y ) ); + float ik = 1.0 - k; - c = 255.0 - r; - m = 255.0 - g; - y = 255.0 - b; - k = VIPS_MIN( c, VIPS_MIN( m, y ) ); - - c = (c - k) / (255.0 - k) * 255.0; - m = (m - k) / (255.0 - k) * 255.0; - y = (y - k) / (255.0 - k) * 255.0; - - q[0] = (unsigned char) VIPS_CLIP(0, c, 255.0); - q[1] = (unsigned char) VIPS_CLIP(0, m, 255.0); - q[2] = (unsigned char) VIPS_CLIP(0, y, 255.0); - if( r < epsilon && - g < epsilon && - b < epsilon ) - q[3] = 255.0; - else - q[3] = VIPS_CLIP( 0, k, 255 ); + if( ik < epsilon ) { + q[0] = 255; + q[1] = 255; + q[2] = 255; + q[3] = 255; + } + else { + q[0] = VIPS_CLIP( 0, 255 * (c - k) / ik, 255 ); + q[1] = VIPS_CLIP( 0, 255 * (m - k) / ik, 255 ); + q[2] = VIPS_CLIP( 0, 255 * (y - k) / ik, 255 ); + q[3] = VIPS_CLIP( 0, 255 * k, 255 ); + } p += 3; q += 4; diff --git a/test/test-suite/test_colour.py b/test/test-suite/test_colour.py index 1e2371f2..b8cb0754 100644 --- a/test/test-suite/test_colour.py +++ b/test/test-suite/test_colour.py @@ -3,7 +3,7 @@ import pytest import pyvips from helpers import JPEG_FILE, SRGB_FILE, colour_colourspaces, \ - mono_colourspaces, assert_almost_equal_objects + mono_colourspaces, assert_almost_equal_objects, skip_if_no class TestColour: @@ -124,6 +124,7 @@ class TestColour: assert abs(result - 4.97) < 0.5 assert pytest.approx(alpha, 0.001) == 42.0 + @skip_if_no("icc_import") def test_icc(self): test = pyvips.Image.new_from_file(JPEG_FILE) @@ -163,6 +164,12 @@ class TestColour: im = test.icc_import() assert im.interpretation == pyvips.Interpretation.LAB + # even without lcms, we should have a working approximation + def test_cmyk(self): + test = pyvips.Image.new_from_file(JPEG_FILE) + + im = test.colourspace("cmyk").colourspace("srgb") + if __name__ == '__main__': pytest.main()