#include<lexlib/color.h>
#include<lexlib/math.h>
#include<math.h>
struct LexlibColor lexlibColorBlend(struct LexlibColor dst, struct LexlibColor src, uint8_t mode){
if(!mode)
return src;
switch(mode){
case LEXLIB_ADD:{
unsigned int alpha = src.a + 1;
dst.r = lexlibClampu(dst.r + (src.r * alpha >> 8), LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.g = lexlibClampu(dst.g + (src.g * alpha >> 8), LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.b = lexlibClampu(dst.b + (src.b * alpha >> 8), LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
return dst;
}
case LEXLIB_SUB:{
unsigned int alpha = src.a + 1;
dst.r = lexlibClampi(dst.r - (src.r * alpha >> 8), LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.g = lexlibClampi(dst.g - (src.g * alpha >> 8), LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.b = lexlibClampi(dst.b - (src.b * alpha >> 8), LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
return dst;
}
case LEXLIB_MUL:{
unsigned int alphaInv = 256 - src.a;
dst.r = lexlibClampu((dst.r * src.r + dst.r * alphaInv) >> 8, LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.g = lexlibClampu((dst.g * src.g + dst.g * alphaInv) >> 8, LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.b = lexlibClampu((dst.b * src.b + dst.b * alphaInv) >> 8, LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
dst.a = lexlibClampu((dst.a * src.a + dst.a * alphaInv) >> 8, LEXLIB_COLOR_MIN, LEXLIB_COLOR_MAX);
return dst;
}
case LEXLIB_MOD:
dst.r = src.r * dst.r >> 8;
dst.g = src.g * dst.g >> 8;
dst.b = src.b * dst.b >> 8;
return dst;
case LEXLIB_BLEND:{
unsigned int alpha = src.a + 1;
unsigned int alphaInv = 256 - src.a;
dst.r = (src.r * alpha + dst.r * alphaInv) >> 8;
dst.g = (src.g * alpha + dst.g * alphaInv) >> 8;
dst.b = (src.b * alpha + dst.b * alphaInv) >> 8;
dst.a = (LEXLIB_COLOR_MAX * alpha + dst.a * alphaInv) >> 8;
return dst;
}
default:
return lexlibColorBlend(dst, src, LEXLIB_ADD);
}
}
uint8_t lexlibColorGray(struct LexlibColor color){
return rintf(
((color.r * 0.299f) +
(color.g * 0.587f) +
(color.b * 0.114f)) *
((float)color.a / 255.0f));
}
struct LexlibColor lexlibColorGrayAlpha(struct LexlibColor color){
color.r = rintf(color.r * 0.299f + color.g * 0.587f + color.b * 0.114f);
color.g = color.r;
color.b = color.r;
return color;
}
struct LexlibColor lexlibColorPremultiply(struct LexlibColor color){
float alpha = color.a / 255.0f;
color.r = (uint8_t)rintf(color.r * alpha);
color.g = (uint8_t)rintf(color.g * alpha);
color.b = (uint8_t)rintf(color.b * alpha);
return color;
}
struct LexlibColorF lexlibColorToF(struct LexlibColor color){
return (struct LexlibColorF){
.r = color.r / 255.0f,
.g = color.g / 255.0f,
.b = color.b / 255.0f,
.a = color.a / 255.0f,
};
}
struct LexlibColor16 lexlibColorTo16(struct LexlibColor color){
return (struct LexlibColor16){
.r = (uint16_t)(color.r * 257),
.g = (uint16_t)(color.g * 257),
.b = (uint16_t)(color.b * 257),
.a = (uint16_t)(color.a * 257),
};
}