API: moved functions to files to make it easier to import to other projects
This commit is contained in:
+217
@@ -0,0 +1,217 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// #include "utils.h"
|
||||
#include "filters.h"
|
||||
|
||||
unsigned int
|
||||
u32_put_alpha(const unsigned int clr, const unsigned char alpha)
|
||||
{
|
||||
return (clr & BYTE_RGB) | alpha << SHIFT_24;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_invert(const unsigned int clr)
|
||||
{
|
||||
return ((~clr) & BYTE_RGB) | (clr & BYTE_A);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_swap_rb(const unsigned int clr)
|
||||
{
|
||||
return (clr & 0xFF00FF00) | ((clr & BYTE_R) >> SHIFT_16) |
|
||||
((clr & BYTE_B) << SHIFT_16);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_grayscale(const unsigned int clr)
|
||||
{
|
||||
unsigned int red = DECODE_R(clr);
|
||||
unsigned int green = DECODE_G(clr);
|
||||
unsigned int blue = DECODE_B(clr);
|
||||
unsigned int gray =
|
||||
((red * 77) + (green * 150) + (blue * 29)) >> SHIFT_8;
|
||||
|
||||
return (clr & BYTE_A) | (gray << SHIFT_16) | (gray << SHIFT_8) | gray;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_step(const unsigned int clr, const unsigned char max)
|
||||
{
|
||||
if (DECODE_B(u32_grayscale(clr)) < max)
|
||||
{
|
||||
return ENCODE_ARGB(0, 0, 0, 0);
|
||||
}
|
||||
return ENCODE_ARGB(MAX, MAX, MAX, MAX);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_brighten(const unsigned int clr, const float factor)
|
||||
{
|
||||
unsigned int alpha = (clr & BYTE_A);
|
||||
unsigned int red = CLAMP_MAX(DECODE_R(clr) * factor);
|
||||
unsigned int green = CLAMP_MAX(DECODE_G(clr) * factor);
|
||||
unsigned int blue = CLAMP_MAX(DECODE_B(clr) * factor);
|
||||
return (clr & BYTE_A) | (red << SHIFT_16) | (green << SHIFT_8) | blue;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_mix(const unsigned int clr_a, const unsigned int clr_b)
|
||||
{
|
||||
unsigned char blue = (DECODE_B(clr_a) + DECODE_B(clr_b)) / 2;
|
||||
unsigned char green = (DECODE_G(clr_a) + DECODE_G(clr_b)) / 2;
|
||||
unsigned char red = (DECODE_R(clr_a) + DECODE_R(clr_b)) / 2;
|
||||
|
||||
return ENCODE_ARGB(DECODE_A(clr_a), red, green, blue);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_lerp(const unsigned clr_a, const unsigned int clr_b, const float ratio)
|
||||
{
|
||||
unsigned char blue =
|
||||
((DECODE_B(clr_a) * (1 - ratio)) + ((DECODE_B(clr_b) * ratio)));
|
||||
unsigned char green =
|
||||
((DECODE_G(clr_a) * (1 - ratio)) + ((DECODE_G(clr_b) * ratio)));
|
||||
unsigned char red =
|
||||
((DECODE_R(clr_a) * (1 - ratio)) + ((DECODE_R(clr_b) * ratio)));
|
||||
return ENCODE_ARGB(DECODE_A(clr_a), red, green, blue);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_mask(const unsigned int clr, const char keep)
|
||||
{
|
||||
switch (keep)
|
||||
{
|
||||
case 'r':
|
||||
return clr & (BYTE_A | BYTE_R);
|
||||
break;
|
||||
case 'g':
|
||||
return clr & (BYTE_A | BYTE_G);
|
||||
break;
|
||||
case 'b':
|
||||
return clr & (BYTE_A | BYTE_B);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_rotl(const unsigned int clr, const int n)
|
||||
{
|
||||
if (n > 8)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unsigned int red = DECODE_R(clr);
|
||||
unsigned int green = DECODE_G(clr);
|
||||
unsigned int blue = DECODE_B(clr);
|
||||
red = ((red << n) | (red >> (SHIFT_8 - n))) & BYTE;
|
||||
green = ((green << n) | (green >> (SHIFT_8 - n))) & BYTE;
|
||||
blue = ((blue << n) | (blue >> (SHIFT_8 - n))) & BYTE;
|
||||
return ENCODE_RGB(red, green, blue);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_contrast(const unsigned int clr, const float factor)
|
||||
{
|
||||
int red = CLAMP_MIN(CLAMP_MAX(
|
||||
(int)(factor * (float)(int)(DECODE_R(clr) - HALF_MAX)) + HALF_MAX));
|
||||
int green = CLAMP_MIN(CLAMP_MAX(
|
||||
(int)(factor * (float)(int)(DECODE_G(clr) - HALF_MAX)) + HALF_MAX));
|
||||
int blue = CLAMP_MIN(CLAMP_MAX(
|
||||
(int)(factor * (float)(int)(DECODE_B(clr) - HALF_MAX)) + HALF_MAX));
|
||||
return BYTE_A | (red << SHIFT_16) | (green << SHIFT_8) | blue;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
u32_avg_gb(const unsigned int clr)
|
||||
{
|
||||
unsigned char red = DECODE_R(clr);
|
||||
unsigned char blue = DECODE_B(clr);
|
||||
unsigned char green = (red + blue) / 2;
|
||||
return ENCODE_RGB(red, green, blue);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
blur_col(const unsigned int* src, const int x, const int y, const PPM* img,
|
||||
const int radius)
|
||||
{
|
||||
unsigned long pt = 0, cnt = 0;
|
||||
|
||||
for (int dx = -radius; dx <= radius; dx++)
|
||||
{
|
||||
int px = x + dx;
|
||||
if (px >= 0 && px < img->width)
|
||||
{
|
||||
pt += u32to_u64(src[y * img->width + px]);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt > 0)
|
||||
{
|
||||
return u64to_u32(pt, cnt);
|
||||
}
|
||||
return src[y * img->width + x];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
blur_row(const unsigned int* src, const int x, const int y, const PPM* img,
|
||||
const int radius)
|
||||
{
|
||||
unsigned long pt = 0, cnt = 0;
|
||||
|
||||
for (int dy = -radius; dy <= radius; dy++)
|
||||
{
|
||||
int py = y + dy;
|
||||
if (py >= 0 && py < img->height)
|
||||
{
|
||||
pt += u32to_u64(src[py * img->width + x]);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt > 0)
|
||||
{
|
||||
return u64to_u32(pt, cnt);
|
||||
}
|
||||
return src[y * img->width + x];
|
||||
}
|
||||
|
||||
unsigned int*
|
||||
box_blur(const unsigned int* src_buf, const PPM* img, const int radius)
|
||||
{
|
||||
unsigned int* first_pass = malloc(img->len * sizeof(unsigned int));
|
||||
if (!first_pass)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unsigned int* dst_buf = malloc(img->len * sizeof(unsigned int));
|
||||
if (!dst_buf)
|
||||
{
|
||||
free(first_pass);
|
||||
return 0;
|
||||
}
|
||||
for (int y = 0; y < img->height; y++)
|
||||
{
|
||||
for (int x = 0; x < img->width; x++)
|
||||
{
|
||||
first_pass[y * img->width + x] =
|
||||
blur_col(src_buf, x, y, img, radius);
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < img->height; y++)
|
||||
{
|
||||
for (int x = 0; x < img->width; x++)
|
||||
{
|
||||
dst_buf[y * img->width + x] =
|
||||
blur_row(first_pass, x, y, img, radius);
|
||||
}
|
||||
}
|
||||
free(first_pass);
|
||||
return dst_buf;
|
||||
}
|
||||
Reference in New Issue
Block a user