many little optimizations removing overhead

This commit is contained in:
Andrew Haynes
2026-03-07 13:39:03 -05:00
parent 59b89a61b5
commit 8f66878367
3 changed files with 211 additions and 185 deletions
Vendored
BIN
View File
Binary file not shown.
+29
View File
@@ -0,0 +1,29 @@
# ---
# Checks: 'bugprone-*,modernize-*,performance-*,readability-*'
# WarningsAsErrors: ''
# ---
---
# Enable a broad range of useful C checks
Checks: >
-*,
bugprone-*,
concurrency-*,
misc-*,
modernize-*,
performance-*,
readability-*,
portability-*,
-readability-braces-around-statements,
-readability-implicit-bool-conversion
# Treat all enabled checks as errors (optional, shows up as Red in Neovim)
WarningsAsErrors: ""
# Project-specific settings
CheckOptions:
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.FunctionCase
value: lower_case
---
+182 -185
View File
@@ -3,147 +3,159 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#define BYTE_A 0xFF000000
#define BYTE_R 0x00FF0000
#define BYTE_G 0x0000FF00
#define BYTE_B 0x000000FF
#define BYTE_RGB 0x00FFFFFF
#define BYTE 0xFF
#define SHIFT_8 8
#define SHIFT_16 16
#define SHIFT_24 24
#define MAX 255
#define HALF_MAX ((int)(MAX / 2) + 1)
#define decode_a(clr) (((clr) >> SHIFT_24) & BYTE)
#define decode_r(clr) (((clr) >> SHIFT_16) & BYTE)
#define decode_g(clr) (((clr) >> SHIFT_8) & BYTE)
#define decode_b(clr) ((clr) & BYTE)
#define encode(r, g, b) \
(((unsigned int)(MAX) << SHIFT_24) | ((unsigned int)(r) << SHIFT_16) | \
((unsigned int)(g) << SHIFT_8) | (unsigned int)(b))
#define CLAMP_MAX(x) (((x) > MAX) ? MAX : (x))
#define CLAMP_MIN(x) (((x) < 0) ? 0 : (x))
typedef struct typedef struct
{ {
int width, height, len; int width, height, len;
char* name; const char* name;
char magic_number[3]; char fmt[3];
} Image; } Image;
unsigned int static inline unsigned int
encoder(unsigned char r, unsigned char g, unsigned char b) set_alpha(const unsigned int clr, const unsigned char alpha_value)
{ {
return (b << 0) | (g << 8) | (r << 16); return (clr & BYTE_RGB) | alpha_value << SHIFT_24;
} }
unsigned char static inline unsigned int
decoder(unsigned int clr, int byte) invert_rgb(const unsigned int clr)
{ {
if (byte == 1) return (clr & 0x000000FF) >> 0; return ((~clr) & BYTE_RGB) | (clr & BYTE_A);
else if (byte == 2) return (clr & 0x0000FF00) >> 8;
else if (byte == 3) return (clr & 0x00FF0000) >> 16;
else if (byte == 4) return (clr & 0xFF000000) >> 24;
return 0;
} }
unsigned int static inline unsigned int
set_alpha(unsigned int clr, unsigned char alpha_value) swap_rb(const unsigned int clr)
{ {
return (clr & 0x00FFFFFF) | alpha_value << 24; return (clr & 0xFF00FF00) | ((clr & BYTE_R) >> SHIFT_16) |
((clr & BYTE_B) << SHIFT_16);
} }
unsigned int static inline unsigned int
invert_rgb(unsigned int clr) to_grayscale(const unsigned int clr)
{ {
return ((~clr) & 0x00FFFFFF) | (clr & 0xFF000000); 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 static inline unsigned int
swap_rb(unsigned int clr) apply_threshold(const unsigned int clr, const unsigned char limit)
{
return (((clr & 0xFF00FF00) | ((decoder(clr, 3)) << 0) |
((decoder(clr, 1) >> 0) << 16)));
}
unsigned int
to_grayscale(unsigned int clr)
{
int average =
(decoder(clr, 3) + decoder(clr, 2) + decoder(clr, 1)) * .33333;
unsigned int mask = encoder(average, average, average);
mask = set_alpha(mask, decoder(clr, 4));
return mask;
}
unsigned int
apply_threshold(unsigned int clr, unsigned char limit)
{ {
unsigned int mask = 0; unsigned int mask = 0;
if (decoder(to_grayscale(clr), 1) < limit) mask = encoder(0, 0, 0); if (decode_b(to_grayscale(clr)) < limit) mask = encode(0, 0, 0);
else mask = encoder(255, 255, 255); else mask = encode(MAX, MAX, MAX);
mask = set_alpha(mask, decoder(clr, 4)); return BYTE_A | mask;
return mask;
} }
unsigned int static inline unsigned int
adjust_brightness(unsigned int clr, float factor) adjust_brightness(const unsigned int clr, const float factor)
{ {
unsigned int red = decoder(clr, 3) * factor; unsigned int alpha = (clr & BYTE_A);
unsigned int green = decoder(clr, 2) * factor; unsigned int red =
unsigned int blue = decoder(clr, 1) * factor; CLAMP_MAX((unsigned int)((float)decode_r(clr) * factor));
if (red > 255) red = 255; unsigned int green =
if (green > 255) green = 255; CLAMP_MAX((unsigned int)((float)decode_g(clr) * factor));
if (blue > 255) blue = 255; unsigned int blue =
unsigned int mask = encoder(red, green, blue); CLAMP_MAX((unsigned int)((float)decode_b(clr) * factor));
mask = set_alpha(mask, decoder(clr, 4)); return (clr & BYTE_A) | (red << SHIFT_16) | (green << SHIFT_8) | blue;
return mask;
} }
unsigned int static inline unsigned int
apply_tint(unsigned int clr_a, unsigned int clr_b) apply_tint(const unsigned int clr_a, const unsigned int clr_b)
{ {
unsigned char blue = (decoder(clr_a, 1) + decoder(clr_b, 1)) / 2; unsigned char blue = (decode_b(clr_a) + decode_b(clr_b)) / 2;
unsigned char green = (decoder(clr_a, 2) + decoder(clr_b, 2)) / 2; unsigned char green = (decode_g(clr_a) + decode_g(clr_b)) / 2;
unsigned char red = (decoder(clr_a, 3) + decoder(clr_b, 3)) / 2; unsigned char red = (decode_r(clr_a) + decode_r(clr_b)) / 2;
return set_alpha(encoder(red, green, blue), decoder(clr_a, 4)); return set_alpha(encode(red, green, blue), decode_a(clr_a));
} }
unsigned int static inline unsigned int
apply_opacity(unsigned clr_a, unsigned int clr_b, float ratio) apply_opacity(const unsigned clr_a, const unsigned int clr_b, const float ratio)
{ {
unsigned char blue = unsigned char blue = (unsigned char)((decode_b(clr_a) * (1 - ratio)) +
(decoder(clr_a, 1) * (1 - ratio) + (decoder(clr_b, 1) * ratio)); ((decode_b(clr_b) * ratio)));
unsigned char green = unsigned char green = (unsigned char)((decode_g(clr_a) * (1 - ratio)) +
(decoder(clr_a, 2) * (1 - ratio) + (decoder(clr_b, 2) * ratio)); ((decode_g(clr_b) * ratio)));
unsigned char red = unsigned char red = (unsigned char)((decode_r(clr_a) * (1 - ratio)) +
(decoder(clr_a, 3) * (1 - ratio) + (decoder(clr_b, 3) * ratio)); ((decode_r(clr_b) * ratio)));
return set_alpha(encoder(red, green, blue), decoder(clr_a, 4)); return set_alpha(encode(red, green, blue), decode_a(clr_a));
} }
unsigned int* static inline unsigned int*
ppm_encode(char* file, Image* img) ppm_encode(const char* file, Image* img)
{ {
unsigned char r, g, b; printf("Starting encode...\n");
unsigned char red;
unsigned char green;
unsigned char blue;
char fmt[3];
int max_val; int max_val;
FILE* fptr; FILE* fptr;
fptr = fopen(file, "r"); fptr = fopen(file, "r");
if (!fptr) return NULL; if (!fptr) return nullptr;
fscanf(fptr, "%s", img->magic_number); fscanf(fptr, "%s", fmt);
fscanf(fptr, "%d %d", &img->width, &img->height); fscanf(fptr, "%d %d", &img->width, &img->height);
img->len = img->width * img->height; img->len = img->width * img->height;
fscanf(fptr, "%d", &max_val); fscanf(fptr, "%d", &max_val);
fgetc(fptr); fgetc(fptr);
unsigned int* buf = malloc(img->len * sizeof(unsigned int)); unsigned int* buf = malloc(img->len * sizeof(unsigned int));
if (!buf) return NULL; if (!buf) return nullptr;
if (img->magic_number[1] == '3') if (fmt[1] == '3')
{ {
for (int i = 0; i < img->len; i++) for (int i = 0; i < img->len; i++)
{ {
fscanf(fptr, "%hhu %hhu %hhu", &r, &g, &b); fscanf(fptr, "%hhu %hhu %hhu", &red, &green, &blue);
unsigned int packed = encoder(r, g, b); buf[i] = encode(red, green, blue);
buf[i] = set_alpha(packed, 255);
} }
} }
else if (img->magic_number[1] == '6') else if (fmt[1] == '6')
{ {
for (int i = 0; i < img->len; i++) for (int i = 0; i < img->len; i++)
{ {
fread(&r, sizeof(unsigned char), 1, fptr); fread(&red, sizeof(unsigned char), 1, fptr);
fread(&g, sizeof(unsigned char), 1, fptr); fread(&green, sizeof(unsigned char), 1, fptr);
fread(&b, sizeof(unsigned char), 1, fptr); fread(&blue, sizeof(unsigned char), 1, fptr);
unsigned int packed = encoder(r, g, b); buf[i] = encode(red, green, blue);
buf[i] = set_alpha(packed, 255);
} }
} }
fclose(fptr); fclose(fptr);
printf("Encoding done!\n");
return buf; return buf;
} }
void static inline void
ppm_apply_brightness(unsigned int* buf, Image img, float factor) ppm_apply_brightness(unsigned int* buf, const Image img, const float factor)
{ {
for (int i = 0; i < img.len; i++) for (int i = 0; i < img.len; i++)
{ {
@@ -151,78 +163,89 @@ ppm_apply_brightness(unsigned int* buf, Image img, float factor)
} }
} }
void static inline void
ppm_decode(unsigned int* buf, Image img) ppm_decode(const unsigned int* buf, const Image img)
{ {
unsigned char red, green, blue; printf("Starting decode...\n");
FILE* fptr; FILE* fptr;
if (img.magic_number[1] == '3') fptr = fopen(img.name, "w"); if (img.fmt[1] == '3') fptr = fopen(img.name, "w");
if (img.magic_number[1] == '6') fptr = fopen(img.name, "wb"); if (img.fmt[1] == '6') fptr = fopen(img.name, "wb");
if (!fptr) return; if (!fptr) return;
fprintf(fptr, "%s\n%d %d\n255\n", img.magic_number, img.width, fprintf(fptr, "%s\n%d %d\n255\n", img.fmt, img.width, img.height);
img.height); if (img.fmt[1] == '3')
for (int i = 0; i < img.len; i++)
{ {
red = decoder(buf[i], 3); for (int i = 0; i < img.len; i++)
green = decoder(buf[i], 2); {
blue = decoder(buf[i], 1); unsigned char red = decode_r(buf[i]);
fwrite(&red, 1, 1, fptr); unsigned char green = decode_g(buf[i]);
fwrite(&green, 1, 1, fptr); unsigned char blue = decode_b(buf[i]);
fwrite(&blue, 1, 1, fptr); fprintf(fptr, "%d %d %d ", red, green, blue);
if (i % 7 == 0)
{
fprintf(fptr, "\n");
}
}
}
if (img.fmt[1] == '6')
{
for (int i = 0; i < img.len; i++)
{
unsigned char red = decode_r(buf[i]);
unsigned char green = decode_g(buf[i]);
unsigned char blue = decode_b(buf[i]);
fwrite(&red, 1, 1, fptr);
fwrite(&green, 1, 1, fptr);
fwrite(&blue, 1, 1, fptr);
}
} }
fclose(fptr); fclose(fptr);
printf("Decode Done!\n");
} }
unsigned int static inline unsigned int
channel_mask(unsigned int clr, char keep) channel_mask(const unsigned int clr, const char keep)
{ {
unsigned int mask = 0;
switch (keep) switch (keep)
{ {
case 'r': case 'r':
mask = encoder(decoder(clr, 3), 0, 0); return clr & (BYTE_A | BYTE_R);
break; break;
case 'g': case 'g':
mask = encoder(0, decoder(clr, 2), 0); return clr & (BYTE_A | BYTE_G);
break; break;
case 'b': case 'b':
mask = encoder(0, 0, decoder(clr, 1)); return clr & (BYTE_A | BYTE_B);
break; break;
} }
mask = set_alpha(mask, decoder(clr, 4)); return 0;
return mask;
} }
unsigned int static inline unsigned int
chromatic_circular_shift(unsigned int clr, int n) chromatic_circular_shift(const unsigned int clr, const int n)
{ {
unsigned int mask = 0; unsigned int red = decode_r(clr);
unsigned char r, g, b; unsigned int green = decode_g(clr);
r = decoder(clr, 3); unsigned int blue = decode_b(clr);
g = decoder(clr, 2);
b = decoder(clr, 1);
r = (r << n) | (r >> (8 - n)); red = ((red << n) | (red >> (SHIFT_8 - n))) & BYTE;
g = (g << n) | (g >> (8 - n)); green = ((green << n) | (green >> (SHIFT_8 - n))) & BYTE;
b = (b << n) | (b >> (8 - n)); blue = ((blue << n) | (blue >> (SHIFT_8 - n))) & BYTE;
mask = encoder(r, g, b); return encode(red, green, blue);
mask = set_alpha(mask, decoder(clr, 4));
return mask;
} }
unsigned int* static inline unsigned int*
horizontal_flip(unsigned int* buf, Image img) horizontal_flip(unsigned int* buf, const Image img)
{ {
unsigned int* flip = malloc(img.len * sizeof(unsigned int)); unsigned int* flip = malloc(img.len * sizeof(unsigned int));
if (!flip) return NULL; if (!flip) return nullptr;
int idx = 0; int idx = 0;
for (int i = 0; i < img.height; i++) for (int i = 0; i < img.height; i++)
{ {
for (int k = img.width - 1; k >= 0; k--) for (int k = img.width - 1; k >= 0; k--)
{ {
flip[idx] = buf[i * img.width + k]; flip[idx] = buf[(i * img.width) + k];
idx++; idx++;
} }
} }
@@ -231,18 +254,18 @@ horizontal_flip(unsigned int* buf, Image img)
return flip; return flip;
} }
unsigned int* static inline unsigned int*
vertical_flip(unsigned int* buf, Image img) vertical_flip(unsigned int* buf, Image img)
{ {
unsigned int* flip = malloc(img.len * sizeof(unsigned int)); unsigned int* flip = malloc(img.len * sizeof(unsigned int));
if (!flip) return NULL; if (!flip) return nullptr;
int idx = 0; int idx = 0;
for (int i = img.height - 1; i >= 0; i--) for (int i = img.height - 1; i >= 0; i--)
{ {
for (int k = 0; k < img.width; k++) for (int k = 0; k < img.width; k++)
{ {
flip[idx] = buf[i * img.width + k]; flip[idx] = buf[(i * img.width) + k];
idx++; idx++;
} }
} }
@@ -251,39 +274,34 @@ vertical_flip(unsigned int* buf, Image img)
return flip; return flip;
} }
unsigned int static inline unsigned int
constrast_adjustment(unsigned int clr, float factor) constrast_adjustment(unsigned int clr, float factor)
{ {
unsigned int mask = 0; unsigned int mask = 0;
int r = factor * (decoder(clr, 3) - 128) + 128; int red = CLAMP_MIN(CLAMP_MAX(
int g = factor * (decoder(clr, 2) - 128) + 128; (int)(factor * (float)(int)(decode_r(clr) - HALF_MAX)) + HALF_MAX));
int b = factor * (decoder(clr, 1) - 128) + 128; int green = CLAMP_MIN(CLAMP_MAX(
if (r > 255) r = 255; (int)(factor * (float)(int)(decode_g(clr) - HALF_MAX)) + HALF_MAX));
if (g > 255) g = 255; int blue = CLAMP_MIN(CLAMP_MAX(
if (b > 255) b = 255; (int)(factor * (float)(int)(decode_b(clr) - HALF_MAX)) + HALF_MAX));
if (r < 0) r = 0; return BYTE_A | (red << SHIFT_16) | (green << SHIFT_8) | blue;
if (g < 0) g = 0;
if (b < 0) b = 0;
mask = encoder(r, g, b);
mask = set_alpha(mask, decoder(clr, 4));
return mask;
} }
unsigned int* static inline unsigned int*
rotate(unsigned int* buf, Image* img, int len) rotate(unsigned int* buf, Image* img, int len)
{ {
unsigned int* mask = malloc(len * sizeof(unsigned int)); unsigned int* mask = malloc(len * sizeof(unsigned int));
int old_width = img->width; int old_width = img->width;
int old_height = img->height; int old_height = img->height;
for (int y = 0; y < old_height; y++) for (int row = 0; row < old_height; row++)
{ {
for (int x = 0; x < old_width; x++) for (int col = 0; col < old_width; col++)
{ {
int new_height = x; int new_height = col;
int new_width = (old_height - 1 - y); int new_width = (old_height - 1 - row);
mask[new_height * old_height + new_width] = mask[(new_height * old_height) + new_width] =
buf[y * old_width + x]; buf[(row * old_width) + col];
} }
} }
img->width = old_height; img->width = old_height;
@@ -292,52 +310,31 @@ rotate(unsigned int* buf, Image* img, int len)
return mask; return mask;
} }
Image
create_image(int w, int h, char* name, char* fmt)
{
Image image = {
.width = w,
.height = h,
.len = w * h,
.name = name,
};
image.magic_number[0] = fmt[0];
image.magic_number[1] = fmt[1];
image.magic_number[2] = '\0';
return image;
}
void
print_bits_int(unsigned int n)
{
for (int i = 31; i >= 0; i--)
{
if (i == 7 || i == 15 || i == 23) write(1, " ", 1);
char bit = (n & (1 << i)) ? '1' : '0';
write(1, &bit, 1);
}
write(1, "\n", 1);
}
int int
main() main()
{ {
Image image = create_image(3, 2, "../color.ppm", "P6"); Image img = { .width = 3,
.height = 2,
.name = "../color.ppm",
.fmt = "P3",
.len = 0 };
unsigned int* buf = ppm_encode("../assets/4ktest.ppm", &image); unsigned int* buf = ppm_encode("../assets/8ktest.ppm", &img);
if (buf) if (buf)
{ {
// ppm_apply_brightness(buf, image, 2); ppm_apply_brightness(buf, img, 2);
//
for (int i = 0; i < image.len; i++) for (int i = 0; i < img.len; i++)
{ {
// buf[i] = channel_mask(buf[i], 'b'); buf[i] = channel_mask(buf[i], 'r');
// buf[i] = chromatic_circular_shift(buf[i], (rand() % 10)); // buf[i] = chromatic_circular_shift(buf[i], (rand() %
// buf[i] = constrast_adjustment(buf[i], 2); // 5)); buf[i] = constrast_adjustment(buf[i], .1f);
buf[i] = to_grayscale(buf[i]); // buf[i] = adjust_brightness(buf[i], 1.5f);
// buf[i] = swap_rb(buf[i]);
// buf[i] = to_grayscale(buf[i]);
} }
// buf = rotate(buf, &image, image.len); // buf = rotate(buf, &image, image.len);
ppm_decode(buf, image); ppm_decode(buf, img);
free(buf); free(buf);
} }
return 0; return 0;