#include<lexlib/color.h>
#include<lexlib/math.h>
#include<math.h>
struct LexlibColor16 lexlibColor16Blend(struct LexlibColor16 dst, struct LexlibColor16 src, uint8_t mode){
struct LexlibColor16 color;
switch(mode){
case LEXLIB_NONE:
return src;
case LEXLIB_ADD:{
float alpha = (float)src.a / 65535.0f;
color.r = lexlibClampi(dst.r + rintf(src.r * alpha), 0, 65535);
color.g = lexlibClampi(dst.g + rintf(src.g * alpha), 0, 65535);
color.b = lexlibClampi(dst.b + rintf(src.b * alpha), 0, 65535);
color.a = dst.a;
return color;
}
case LEXLIB_SUB:{
float alpha = (float)src.a / 65535.0f;
color.r = dst.r - (src.r * alpha);
color.g = dst.g - (src.g * alpha);
color.b = dst.b - (src.b * alpha);
color.a = dst.a;
return color;
}
case LEXLIB_MUL:{
struct LexlibColor16 d = lexlibColor16Premultiply(dst);
struct LexlibColorF dstf = lexlibColor16ToF(d);
float alpha = (float)src.a / 65535.0f;
float alphainv = 1.0f - alpha;
color.r = lexlibClampi(rintf((src.r * dstf.r) + (dst.r * alphainv)), 0, 65535);
color.g = lexlibClampi(rintf((src.g * dstf.g) + (dst.g * alphainv)), 0, 65535);
color.b = lexlibClampi(rintf((src.b * dstf.b) + (dst.b * alphainv)), 0, 65535);
color.a = lexlibClampi(rintf(((alpha * dstf.a) + (dstf.a * alphainv))) * 65535.0f, 0, 65535);
return color;
}
case LEXLIB_MOD:
color.r = rintf(src.r * (dst.r / 65535.0f));
color.g = rintf(src.g * (dst.g / 65535.0f));
color.b = rintf(src.b * (dst.b / 65535.0f));
color.a = dst.a;
return color;
case LEXLIB_BLEND:{
float alpha = (float)src.a / 65535.0f;
float alphainv = 1.0f - alpha;
color.r = rintf((src.r * alpha) + (dst.r * alphainv));
color.g = rintf((src.g * alpha) + (dst.g * alphainv));
color.b = rintf((src.b * alpha) + (dst.b * alphainv));
color.a = (alpha + (((float)dst.a / 65535.0f) * alphainv)) * 65535.0f;
return color;
}
default:
return lexlibColor16Blend(dst, src, LEXLIB_ADD);
}
}
uint16_t lexlibColor16Gray(struct LexlibColor16 color){
return rintf(
((color.r * 0.299f) +
(color.g * 0.587f) +
(color.b * 0.114f)) *
((float)color.a / 65535.0f));
}
struct LexlibColor16 lexlibColor16GrayAlpha(struct LexlibColor16 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 LexlibColor16 lexlibColor16Premultiply(struct LexlibColor16 color){
float alpha = color.a / 65535.0f;
color.r = (uint16_t)rintf(color.r * alpha);
color.g = (uint16_t)rintf(color.g * alpha);
color.b = (uint16_t)rintf(color.b * alpha);
return color;
}
struct LexlibColor lexlibColor16To8(struct LexlibColor16 color){
return (struct LexlibColor){
.r = (uint8_t)(color.r / 257),
.g = (uint8_t)(color.g / 257),
.b = (uint8_t)(color.b / 257),
.a = (uint8_t)(color.a / 257),
};
}
struct LexlibColorF lexlibColor16ToF(struct LexlibColor16 color){
return (struct LexlibColorF){
.r = color.r / 65535.0f,
.g = color.g / 65535.0f,
.b = color.b / 65535.0f,
.a = color.a / 65535.0f,
};
}