image-colours/colours.c
2022-11-23 22:59:30 +02:00

189 lines
2.9 KiB
C

#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;
}