lexlib 2.0.1

library with miscellaneous stuff
Documentation
// Copyright 2023 alexevier <alexevier@proton.me>
// licensed under the zlib license <https://www.zlib.net/zlib_license.html>

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

/* BGR > RGB :) */