#include "colours.h" #include struct ColourRGB CMYKtoRGB(struct ColourCMYK cmyk) { struct ColourRGB result; result.r = (1.0 - cmyk.c) * (1.0 - cmyk.k); result.g = (1.0 - cmyk.m) * (1.0 - cmyk.k); result.b = (1.0 - cmyk.y) * (1.0 - cmyk.k); return result; } struct ColourRGB HSVtoRGB(struct ColourHSV hsv) { struct ColourRGB result; double c; double x; double m; c = hsv.s * hsv.v; x = c * (1.0 - fabs(fmod(hsv.h / 60.0, 2) - 1.0)); m = hsv.v - c; int angle = hsv.h / 60; switch (angle) { // 0 - 60 case 6: case 0: result.r = c; result.g = x; result.b = 0; break; // 60 - 120 case 1: result.r = x; result.g = c; result.b = 0; break; // 120 - 180 case 2: result.r = 0; result.g = c; result.b = x; break; // 180 - 240 case 3: result.r = 0; result.g = x; result.b = c; break; // 240 - 300 case 4: result.r = x; result.g = 0; result.b = c; break; // 300 - 360 case 5: result.r = c; result.g = 0; result.b = x; break; // Should never happen default: result.r = 0; result.g = 0; result.b = 0; break; } result.r += m; result.g += m; result.b += m; return result; } struct ColourRGB HSLtoRGB(struct ColourHSL hsl) { struct ColourRGB result; double c; double x; double m; c = hsl.s * (1.0 - fabs(2 * hsl.l - 1)); x = c * (1.0 - fabs(fmod(hsl.h / 60.0, 2) - 1.0)); m = hsl.l - c/2; int angle = hsl.h / 60; switch (angle) { // 0 - 60 case 6: case 0: result.r = c; result.g = x; result.b = 0; break; // 60 - 120 case 1: result.r = x; result.g = c; result.b = 0; break; // 120 - 180 case 2: result.r = 0; result.g = c; result.b = x; break; // 180 - 240 case 3: result.r = 0; result.g = x; result.b = c; break; // 240 - 300 case 4: result.r = x; result.g = 0; result.b = c; break; // 300 - 360 case 5: result.r = c; result.g = 0; result.b = x; break; // Should never happen default: result.r = 0; result.g = 0; result.b = 0; break; } result.r += m; result.g += m; result.b += m; return result; } struct ColourCMYK RGBtoCMYK(struct ColourRGB rgb) { struct ColourCMYK result; // max(r,g,b) result.k = rgb.r > rgb.g ? rgb.r : rgb.g; result.k = rgb.b > result.k ? rgb.b : result.k; result.k = 1.0 - result.k; if (1.0 == result.k) { result.c = 0; result.m = 0; result.y = 0; } else { result.c = (1.0 - rgb.r - result.k) / (1.0 - result.k); result.m = (1.0 - rgb.g - result.k) / (1.0 - result.k); result.y = (1.0 - rgb.b - result.k) / (1.0 - result.k); } return result; } struct ColourCMYK HSVtoCMYK(struct ColourHSV hsv) { struct ColourCMYK result; result = RGBtoCMYK(HSVtoRGB(hsv)); return result; } struct ColourCMYK HSLtoCMYK(struct ColourHSL hsl) { struct ColourCMYK result; result = RGBtoCMYK(HSLtoRGB(hsl)); return result; } struct ColourHSV RGBtoHSV(struct ColourRGB rgb) { struct ColourHSV result; double c_max; double c_min; double delta; // max(r,g,b) c_max = rgb.r > rgb.g ? rgb.r : rgb.g; c_max = rgb.b > c_max ? rgb.b : c_max; // min(r,g,b) c_min = rgb.r < rgb.g ? rgb.r : rgb.g; c_min = rgb.b < c_min ? rgb.b : c_min; delta = c_max - c_min; if (delta > 0) { if (c_max == rgb.r) { result.h = 60 * fmod((rgb.g - rgb.b) / delta, 6); } else if (c_max == rgb.g) { result.h = 60 * ((rgb.b - rgb.r) / delta + 2); } else { result.h = 60 * ((rgb.r - rgb.g) / delta + 4); } result.v = c_max; result.s = delta / result.v; } else { result.h = 0; result.s = 0; result.v = c_max; } if (result.h < 0) { result.h += 360; } return result; } struct ColourHSV CMYKtoHSV(struct ColourCMYK cmyk) { struct ColourHSV result; result = RGBtoHSV(CMYKtoRGB(cmyk)); return result; } struct ColourHSV HSLtoHSV(struct ColourHSL hsl) { struct ColourHSV result; result = RGBtoHSV(HSLtoRGB(hsl)); return result; } struct ColourHSL RGBtoHSL(struct ColourRGB rgb) { struct ColourHSL result; double c_max; double c_min; double delta; // max(r,g,b) c_max = rgb.r > rgb.g ? rgb.r : rgb.g; c_max = rgb.b > c_max ? rgb.b : c_max; // min(r,g,b) c_min = rgb.r < rgb.g ? rgb.r : rgb.g; c_min = rgb.b < c_min ? rgb.b : c_min; delta = c_max - c_min; if (delta > 0) { if (c_max == rgb.r) { result.h = 60 * fmod((rgb.g - rgb.b) / delta, 6); } else if (c_max == rgb.g) { result.h = 60 * ((rgb.b - rgb.r) / delta + 2); } else { result.h = 60 * ((rgb.r - rgb.g) / delta + 4); } result.l = (c_max + c_min) / 2; result.s = delta / (1.0 - fabs(2 * result.l - 1.0)); } else { result.h = 0; result.s = 0; result.l = (c_max + c_min) / 2; } if (result.h < 0) { result.h += 360; } return result; } struct ColourHSL CMYKtoHSL(struct ColourCMYK cmyk) { struct ColourHSL result; result = RGBtoHSL(CMYKtoRGB(cmyk)); return result; } struct ColourHSL HSVtoHSL(struct ColourHSV hsv) { struct ColourHSL result; result = RGBtoHSL(HSVtoRGB(hsv)); return result; }