update
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
BasedOnStyle: Google
|
||||||
|
Standard: Latest
|
||||||
|
UseTab: Always
|
||||||
|
TabWidth: 8
|
||||||
|
IndentWidth: 8
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SeparateDefinitionBlocks: Always
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
BreakAfterReturnType: TopLevel
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
ReflowComments: Always
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
IndentAccessModifiers: false # Indent access specifiers by one level
|
||||||
|
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
.cache/
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
set(CMAKE_C_STANDARD 23)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
include_directories(include)
|
||||||
|
project(ppm_image_processor LANGUAGES C)
|
||||||
|
|
||||||
|
add_executable(ppm_image_processor src/main.c)
|
||||||
+267
@@ -0,0 +1,267 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
encoder(unsigned char r, unsigned char g, unsigned char b)
|
||||||
|
{
|
||||||
|
unsigned int color = 0;
|
||||||
|
color |= b << 0;
|
||||||
|
color |= g << 8;
|
||||||
|
color |= r << 16;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char
|
||||||
|
decoder(unsigned int clr, int byte)
|
||||||
|
{
|
||||||
|
if (byte == 1) return (clr & 0x000000FF) >> 0;
|
||||||
|
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
|
||||||
|
// decoder_int(unsigned int clr, int byte)
|
||||||
|
// {
|
||||||
|
// if (byte == 1) return (clr & 0x000000FF) >> 0;
|
||||||
|
// 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
|
||||||
|
set_alpha(unsigned int clr, unsigned char alpha_value)
|
||||||
|
{
|
||||||
|
return (clr & 0x00FFFFFF) | alpha_value << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
invert_rgb(unsigned int clr)
|
||||||
|
{
|
||||||
|
unsigned char alpha = (clr & 0xFF000000) >> 24;
|
||||||
|
|
||||||
|
return ((~clr) & 0x00FFFFFF) | alpha << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
swap_rb(unsigned int clr)
|
||||||
|
{
|
||||||
|
return (((clr & 0xFF00FF00) | ((decoder(clr, 3)) << 0) |
|
||||||
|
((decoder(clr, 1) >> 0) << 16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
to_grayscale(unsigned int clr)
|
||||||
|
{
|
||||||
|
unsigned char alpha = decoder(clr, 4);
|
||||||
|
unsigned char red = decoder(clr, 3);
|
||||||
|
unsigned char green = decoder(clr, 2);
|
||||||
|
unsigned char blue = decoder(clr, 1);
|
||||||
|
|
||||||
|
int average = (red + green + blue) / 3;
|
||||||
|
unsigned int mask = encoder(average, average, average);
|
||||||
|
mask = set_alpha(mask, alpha);
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
apply_threshold(unsigned int clr, unsigned char limit)
|
||||||
|
{
|
||||||
|
unsigned int mask = 0;
|
||||||
|
unsigned char average = decoder(to_grayscale(clr), 1);
|
||||||
|
if (average < limit) mask = encoder(0, 0, 0);
|
||||||
|
else mask = encoder(255, 255, 255);
|
||||||
|
mask = set_alpha(mask, decoder(clr, 4));
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
adjust_brightness(unsigned int clr, float factor)
|
||||||
|
{
|
||||||
|
unsigned int red = decoder(clr, 3) * factor;
|
||||||
|
unsigned int green = decoder(clr, 2) * factor;
|
||||||
|
unsigned int blue = decoder(clr, 1) * factor;
|
||||||
|
if (red > 255) red = 255;
|
||||||
|
if (green > 255) green = 255;
|
||||||
|
if (blue > 255) blue = 255;
|
||||||
|
unsigned int mask = encoder(red, green, blue);
|
||||||
|
mask = set_alpha(mask, decoder(clr, 4));
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
apply_tint(unsigned int clr_a, unsigned int clr_b)
|
||||||
|
{
|
||||||
|
unsigned char blue = (decoder(clr_a, 1) + decoder(clr_b, 1)) / 2;
|
||||||
|
unsigned char green = (decoder(clr_a, 2) + decoder(clr_b, 2)) / 2;
|
||||||
|
unsigned char red = (decoder(clr_a, 3) + decoder(clr_b, 3)) / 2;
|
||||||
|
|
||||||
|
return set_alpha(encoder(red, green, blue), decoder(clr_a, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
apply_opacity(unsigned clr_a, unsigned int clr_b, float ratio)
|
||||||
|
{
|
||||||
|
unsigned char blue =
|
||||||
|
(decoder(clr_a, 1) * (1 - ratio) + (decoder(clr_b, 1) * ratio));
|
||||||
|
unsigned char green =
|
||||||
|
(decoder(clr_a, 2) * (1 - ratio) + (decoder(clr_b, 2) * ratio));
|
||||||
|
unsigned char red =
|
||||||
|
(decoder(clr_a, 3) * (1 - ratio) + (decoder(clr_b, 3) * ratio));
|
||||||
|
return set_alpha(encoder(red, green, blue), decoder(clr_a, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int*
|
||||||
|
ppm_encode(char* file, int* w, int* h, int* max_val, char* magic_number)
|
||||||
|
{
|
||||||
|
unsigned char r, g, b;
|
||||||
|
FILE* fptr;
|
||||||
|
fptr = fopen(file, "r");
|
||||||
|
if (!fptr) return NULL;
|
||||||
|
fscanf(fptr, "%s", magic_number);
|
||||||
|
fscanf(fptr, "%d %d", w, h);
|
||||||
|
fscanf(fptr, "%d", max_val);
|
||||||
|
unsigned int* buf = malloc((*w) * (*h) * sizeof(unsigned int));
|
||||||
|
if (!buf) return NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < (*w * *h); i++)
|
||||||
|
{
|
||||||
|
fscanf(fptr, "%hhu %hhu %hhu", &r, &g, &b);
|
||||||
|
unsigned int packed = encoder(r, g, b);
|
||||||
|
buf[i] = set_alpha(packed, 255);
|
||||||
|
}
|
||||||
|
fclose(fptr);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ppm_apply_brightness(unsigned int* buf, int buf_size, float factor)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < buf_size; i++)
|
||||||
|
{
|
||||||
|
buf[i] = adjust_brightness(buf[i], factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ppm_decode(unsigned int* buf, int buf_size, char* name, int* w, int* h)
|
||||||
|
{
|
||||||
|
unsigned char red, green, blue;
|
||||||
|
FILE* fptr = fopen(name, "w");
|
||||||
|
if (!fptr) return;
|
||||||
|
fprintf(fptr, "P3\n%d %d\n255\n", *w, *h);
|
||||||
|
for (int i = 0; i < buf_size; i++)
|
||||||
|
{
|
||||||
|
red = decoder(buf[i], 3);
|
||||||
|
green = decoder(buf[i], 2);
|
||||||
|
blue = decoder(buf[i], 1);
|
||||||
|
fprintf(fptr, "%d %d %d ", red, green, blue);
|
||||||
|
if ((i + 1) % *w == 0)
|
||||||
|
{
|
||||||
|
fprintf(fptr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
channel_mask(unsigned int clr, char keep)
|
||||||
|
{
|
||||||
|
unsigned int mask = 0;
|
||||||
|
switch (keep)
|
||||||
|
{
|
||||||
|
case 'r':
|
||||||
|
mask = encoder(decoder(clr, 3), 0, 0);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
mask = encoder(0, decoder(clr, 2), 0);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
mask = encoder(0, 0, decoder(clr, 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mask = set_alpha(mask, decoder(clr, 4));
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
chromatic_circular_shift(unsigned int clr, int n)
|
||||||
|
{
|
||||||
|
unsigned int mask = 0;
|
||||||
|
unsigned char r, g, b;
|
||||||
|
r = decoder(clr, 3);
|
||||||
|
g = decoder(clr, 2);
|
||||||
|
b = decoder(clr, 1);
|
||||||
|
|
||||||
|
r = (r << n) | (r >> (8 - n));
|
||||||
|
g = (g << n) | (g >> (8 - n));
|
||||||
|
b = (b << n) | (b >> (8 - n));
|
||||||
|
mask = encoder(r, g, b);
|
||||||
|
mask = set_alpha(mask, decoder(clr, 4));
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int*
|
||||||
|
horizontal_flip(unsigned int* buf, int size, int w) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int*
|
||||||
|
vertical_flip(unsigned int* buf, int size, int w, int h) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_bits_char(unsigned char n)
|
||||||
|
{
|
||||||
|
for (int i = 7; i >= 0; i--)
|
||||||
|
{
|
||||||
|
char bit = (n & (1 << i)) ? '1' : '0';
|
||||||
|
write(1, &bit, 1);
|
||||||
|
}
|
||||||
|
write(1, "\n", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
// unsigned int test = 40;
|
||||||
|
// print_bits_int(test);
|
||||||
|
// test = (test << 3) | (test >> (8 - 3));
|
||||||
|
// print_bits_int(test);
|
||||||
|
|
||||||
|
unsigned int color = encoder(200, 10, 50);
|
||||||
|
color = set_alpha(color, 100);
|
||||||
|
print_bits_int(color);
|
||||||
|
// unsigned int channelled_color = channel_mask(color, 'g');
|
||||||
|
color = chromatic_circular_shift(color, 3);
|
||||||
|
print_bits_int(color);
|
||||||
|
// int width, height;
|
||||||
|
// char magic_number[3];
|
||||||
|
// int max_val;
|
||||||
|
//
|
||||||
|
// unsigned int* buf =
|
||||||
|
// ppm_encode("../test.ppm", &width, &height, &max_val,
|
||||||
|
// magic_number);
|
||||||
|
// ppm_apply_brightness(buf, (width * height), .5);
|
||||||
|
// ppm_decode(buf, (width * height), "../new.ppm", &width, &height);
|
||||||
|
// free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user