# Solution Solution to canvas Date: 2026-01-22 URL: https://elte.darthdemono.com/Imperative-programming-L+Pr/canvas/Solution Tags: IP-18fIMPROGEG, Sample, Solution --- Canvas Solution canvas.c: #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; } canvas.h: #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 main.c: #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; }