Added HSL colour conversion

This commit is contained in:
nedko 2022-12-07 12:33:35 +02:00
parent 984885f9a0
commit 0c6a998be6
2 changed files with 331 additions and 192 deletions

515
colours.c
View File

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

View File

@ -32,18 +32,18 @@ struct ColourHSL
struct ColourRGB CMYKtoRGB(struct ColourCMYK cmyk); struct ColourRGB CMYKtoRGB(struct ColourCMYK cmyk);
struct ColourRGB HSVtoRGB(struct ColourHSV hsv); struct ColourRGB HSVtoRGB(struct ColourHSV hsv);
// struct ColourRGB HSLtoRGB(struct ColourHSL hsl); struct ColourRGB HSLtoRGB(struct ColourHSL hsl);
struct ColourCMYK RGBtoCMYK(struct ColourRGB rgb); struct ColourCMYK RGBtoCMYK(struct ColourRGB rgb);
struct ColourCMYK HSVtoCMYK(struct ColourHSV hsv); struct ColourCMYK HSVtoCMYK(struct ColourHSV hsv);
// struct ColourCMYK HSLtoCMYK(struct ColourHSL hsl); struct ColourCMYK HSLtoCMYK(struct ColourHSL hsl);
struct ColourHSV RGBtoHSV(struct ColourRGB rgb); struct ColourHSV RGBtoHSV(struct ColourRGB rgb);
struct ColourHSV CMYKtoHSV(struct ColourCMYK cmyk); struct ColourHSV CMYKtoHSV(struct ColourCMYK cmyk);
// struct ColourHSV HSLtoHSV(struct ColourHSL hsl); struct ColourHSV HSLtoHSV(struct ColourHSL hsl);
struct ColourHSL RGBtoHSL(struct ColourRGB rgb); struct ColourHSL RGBtoHSL(struct ColourRGB rgb);
struct ColourHSL CMYKtoHSL(struct ColourCMYK cmyk); struct ColourHSL CMYKtoHSL(struct ColourCMYK cmyk);
// struct ColourHSL HSVtoHSL(struct ColourHSV hsv); struct ColourHSL HSVtoHSL(struct ColourHSV hsv);
#endif // COLOURS_H_ #endif // COLOURS_H_