Canvas Solution
#include "canvas.h"
#include <stdio.h>
#include <stdlib.h>
static Canvas make_empty_canvas(void)
{
Canvas c;
c.width = 0;
c.height = 0;
c.pixels = NULL;
return c;
}
Canvas init_canvas(int width, int height)
{
Canvas c;
int y;
c.width = 0;
c.height = 0;
c.pixels = NULL;
if (width <= 0 || height <= 0)
{
return c;
}
c.pixels = malloc(height * sizeof(Pixel *));
for (y = 0; y < height; ++y)
{
c.pixels[y] = malloc(width * sizeof(Pixel));
if (!c.pixels[y])
{
int i;
for (i = 0; i < y; ++i)
{
free(c.pixels[i]);
}
free(c.pixels);
c.pixels = NULL;
return make_empty_canvas();
}
}
c.width = width;
c.height = height;
return c;
}
Canvas load_asset(const char *filename)
{
Canvas c = make_empty_canvas();
FILE *f = fopen(filename, "r");
int w, h;
int x, y;
if (!f)
{
return c;
}
if (fscanf(f, "%d %d", &w, &h) != 2)
{
fclose(f);
return c;
}
c = init_canvas(w, h);
if (!c.pixels)
{
fclose(f);
return c;
}
for (y = 0; y < c.height; ++y)
{
for (x = 0; x < c.width; ++x)
{
int r, g, b;
if (fscanf(f, "%d %d %d", &r, &g, &b) != 3)
{
/* on bad input just free and return empty */
free_canvas(c);
fclose(f);
return make_empty_canvas();
}
c.pixels[y][x].r = (unsigned char)r;
c.pixels[y][x].g = (unsigned char)g;
c.pixels[y][x].b = (unsigned char)b;
}
}
fclose(f);
return c;
}
void free_canvas(Canvas c)
{
int y;
if (!c.pixels)
{
return;
}
for (y = 0; y < c.height; ++y)
{
free(c.pixels[y]);
}
free(c.pixels);
}
void invert_colors(Canvas *c)
{
int x, y;
if (!c || !c->pixels)
{
return;
}
for (y = 0; y < c->height; ++y)
{
for (x = 0; x < c->width; ++x)
{
Pixel *p = &c->pixels[y][x];
p->r = 255 - p->r;
p->g = 255 - p->g;
p->b = 255 - p->b;
}
}
}
Canvas get_brightest_canvas(Canvas canvases[], int size)
{
int i, x, y;
double best_brightness = -1.0;
Canvas best = make_empty_canvas();
if (!canvases || size <= 0)
{
return best;
}
for (i = 0; i < size; ++i)
{
Canvas c = canvases[i];
long sum = 0;
long count;
if (!c.pixels || c.width <= 0 || c.height <= 0)
{
continue;
}
for (y = 0; y < c.height; ++y)
{
for (x = 0; x < c.width; ++x)
{
Pixel p = c.pixels[y][x];
sum += p.r + p.g + p.b;
}
}
count = (long)c.width * (long)c.height * 3L;
if (count == 0)
{
continue;
}
double avg = (double)sum / (double)count;
if (avg > best_brightness)
{
best_brightness = avg;
best = c;
}
}
return best;
}
#ifndef CANVAS_H
#define CANVAS_H
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
} Pixel;
typedef struct
{
int width;
int height;
Pixel **pixels; /* pixels[y][x] */
} Canvas;
Canvas init_canvas(int width, int height);
Canvas load_asset(const char *filename);
void free_canvas(Canvas c);
void invert_colors(Canvas *c);
Canvas get_brightest_canvas(Canvas canvases[], int size);
#endif
#include <stdio.h>
#include <stdlib.h>
#include "canvas.h"
void print_canvas(Canvas c){
printf("\n--- Canvas (%dx%d) ---\n", c.width, c.height);
for (int y = 0; y < c.height; y++){
for (int x = 0; x < c.width; x++){
Pixel p = c.pixels[y][x];
printf("\033[38;2;%d;%d;%dm", p.r, p.g, p.b);
printf("@@");
printf("\033[0m");
}
printf("\n");
}
printf("---------------------\n");
}
Canvas* load_all_canvases(){
int capacity = 4;
Canvas *canvas_array = malloc(capacity * sizeof(Canvas));
Canvas c = load_asset("assets/cat.txt");
canvas_array[0] = c;
c = load_asset("assets/dog.txt");
canvas_array[1] = c;
c = load_asset("assets/fish.txt");
canvas_array[2] = c;
c = load_asset("assets/star.txt");
canvas_array[3] = c;
return canvas_array;
}
int main()
{
int choice = 0;
Canvas *canvases = load_all_canvases();
for (;;) {
printf("\n=== Menu ===\n");
printf("1) Print an image\n");
printf("2) Invert an image\n");
printf("3) Get the brightest image\n");
printf("4) Exit\n");
printf("Your choice: ");
scanf("%d", &choice);
if (choice == 4) {
for (int i = 0; i < 4; i++) {
free_canvas(canvases[i]);
}
free(canvases);
break;
}
if (!canvases) {
printf("No images are loaded. Put images in ./assets and restart.\n");
continue;
}
switch (choice) {
case 1: {
printf("Which image do you want to print?\n");
printf("0 : Cat\n");
printf("1 : Dog\n");
printf("2 : Fish\n");
printf("3 : Star\n");
printf("Your choice: ");
scanf("%d", &choice);
if (choice < 0 || choice > 3) {
printf("Invalid choice, please try again!\n");
break;
}
print_canvas(canvases[choice]);
break;
}
case 2: {
printf("Which image do you want to invert?\n");
printf("0 : Cat\n");
printf("1 : Dog\n");
printf("2 : Fish\n");
printf("3 : Star\n");
printf("Your choice: ");
scanf("%d", &choice);
if (choice < 0 || choice > 3) {
printf("Invalid choice, please try again!\n");
break;
}
invert_colors(&canvases[choice]);
print_canvas(canvases[choice]);
break;
}
case 3: {
Canvas brightest = get_brightest_canvas(canvases, 4);
print_canvas(brightest);
break;
}
default:
printf("Wrong choice, please try again!\n");
break;
}
}
return 0;
}