From d61ac8d1528f6ffef49395cf3e89322e629527f3 Mon Sep 17 00:00:00 2001 From: Holger Reichert Date: Tue, 26 Sep 2017 20:58:41 +0200 Subject: [PATCH] [Tradfri] Fix bug in color space conversion Ensure that calculated RGB values are not negative. Fixes: #4349 Signed-off-by: Holger Reichert --- .../tradfri/internal/TradfriColorTest.java | 20 +++++++++++++++++-- .../tradfri/internal/TradfriColor.java | 10 +++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri.test/src/test/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColorTest.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri.test/src/test/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColorTest.java index cbf1774b505..489b9a6ad20 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.tradfri.test/src/test/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColorTest.java +++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri.test/src/test/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColorTest.java @@ -51,7 +51,7 @@ public void testFromCieKnownGood2() { assertEquals(89, color.hsbType.getSaturation().intValue()); assertEquals(34, color.hsbType.getBrightness().intValue()); } - + @Test public void testFromCieKnownGood3() { TradfriColor color = TradfriColor.fromCie(19983, 37417, 1); @@ -68,6 +68,22 @@ public void testFromCieKnownGood3() { assertEquals(1, color.hsbType.getBrightness().intValue()); } + @Test + public void testFromCieKnownGood4() { + TradfriColor color = TradfriColor.fromCie(11469, 3277, 181); + assertNotNull(color); + assertEquals(12, (int) color.rgbR); + assertEquals(0, (int) color.rgbG); + assertEquals(183, (int) color.rgbB); + assertEquals(11469, (int) color.xyX); + assertEquals(3277, (int) color.xyY); + assertEquals(181, (int) color.brightness); + assertNotNull(color.hsbType); + assertEquals(245, color.hsbType.getHue().intValue()); + assertEquals(100, color.hsbType.getSaturation().intValue()); + assertEquals(72, color.hsbType.getBrightness().intValue()); + } + @Test public void testFromHSBTypeKnownGood1() { TradfriColor color = TradfriColor.fromHSBType(HSBType.RED); @@ -83,7 +99,7 @@ public void testFromHSBTypeKnownGood1() { assertEquals(100, color.hsbType.getSaturation().intValue()); assertEquals(100, color.hsbType.getBrightness().intValue()); } - + @Test public void testFromHSBTypeKnownGood2() { TradfriColor color = TradfriColor.fromHSBType(new HSBType("0,100,1")); diff --git a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColor.java b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColor.java index 594e1a46364..2e92db1e11f 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColor.java +++ b/extensions/binding/org.eclipse.smarthome.binding.tradfri/src/main/java/org/eclipse/smarthome/binding/tradfri/internal/TradfriColor.java @@ -124,6 +124,11 @@ public static TradfriColor fromCie(int xyX, int xyY, int xyBrightness) { // green = green <= 0.0031308 ? 12.92 * green : (1.0 + 0.055) * Math.pow(green, (1.0 / 2.4)) - 0.055; // blue = blue <= 0.0031308 ? 12.92 * blue : (1.0 + 0.055) * Math.pow(blue, (1.0 / 2.4)) - 0.055; + // calculated values can be slightly negative, so cap them to minimum 0.0 + red = Math.max(0.0, red); + green = Math.max(0.0, green); + blue = Math.max(0.0, blue); + int redRounded = (int) Math.round(red * 255.0); int greenRounded = (int) Math.round(green * 255.0); int blueRounded = (int) Math.round(blue * 255.0); @@ -162,7 +167,7 @@ public static TradfriColor fromHSBType(HSBType hsbType) { // red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); // green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); // blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); - + // Wide RGB D65 conversion // math inspiration: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html double X = red * 0.664511 + green * 0.154324 + blue * 0.162028; @@ -279,8 +284,7 @@ public static PercentType calculateColorTemperature(int xyX, int xyY) { } return new PercentType((int) Math.round(value * 100.0)); } - - + /** * Converts the xyBrightness value to PercentType *