Added HSL colour conversion
This commit is contained in:
parent
984885f9a0
commit
0c6a998be6
515
colours.c
515
colours.c
@ -1,188 +1,327 @@
|
||||
#include "colours.h"
|
||||
|
||||
#include <tgmath.h>
|
||||
|
||||
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 - fabs(fmod(hsv.h / 60.0, 2) - 1));
|
||||
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 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 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);
|
||||
}
|
||||
|
||||
if(c_max > 0)
|
||||
{
|
||||
result.s = delta / c_max;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.s = 0;
|
||||
}
|
||||
|
||||
result.v = c_max;
|
||||
}
|
||||
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;
|
||||
}
|
||||
#include "colours.h"
|
||||
|
||||
#include <tgmath.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -32,18 +32,18 @@ struct ColourHSL
|
||||
|
||||
struct ColourRGB CMYKtoRGB(struct ColourCMYK cmyk);
|
||||
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 HSVtoCMYK(struct ColourHSV hsv);
|
||||
// struct ColourCMYK HSLtoCMYK(struct ColourHSL hsl);
|
||||
struct ColourCMYK HSLtoCMYK(struct ColourHSL hsl);
|
||||
|
||||
struct ColourHSV RGBtoHSV(struct ColourRGB rgb);
|
||||
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 CMYKtoHSL(struct ColourCMYK cmyk);
|
||||
// struct ColourHSL HSVtoHSL(struct ColourHSV hsv);
|
||||
struct ColourHSL HSVtoHSL(struct ColourHSV hsv);
|
||||
|
||||
#endif // COLOURS_H_
|
||||
|
||||
Loading…
Reference in New Issue
Block a user