From 24ac40a17cffa5250060a55dd3b422ecabc8e1b6 Mon Sep 17 00:00:00 2001 From: Laurent MAZET Date: Thu, 12 Sep 2024 18:07:48 +0200 Subject: [PATCH] first version --- color.c | 49 ++++++++++++++++++++++++++ color.h | 17 ++++++++++ display.c | 59 ++++++++++---------------------- image.c | 25 ++++++++++++++ image.h | 16 +++++++++ makefile | 2 +- ppm.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ppm.h | 8 +++++ 8 files changed, 234 insertions(+), 42 deletions(-) create mode 100644 color.c create mode 100644 color.h create mode 100644 image.c create mode 100644 image.h create mode 100644 ppm.c create mode 100644 ppm.h diff --git a/color.c b/color.c new file mode 100644 index 0000000..38fb9c3 --- /dev/null +++ b/color.c @@ -0,0 +1,49 @@ +#include + +#include "color.h" + +#define nbcolors 16 + +color_t colors[nbcolors] = { + { 40, 0, 0, 0 }, + { 41, 0.5, 0, 0 }, + { 42, 0, 0.5, 0 }, + { 43, 0.5, 0.5, 0 }, + { 44, 0, 0, 0.5 }, + { 45, 0.5, 0, 0.5 }, + { 46, 0, 0.5, 0.5 }, + { 47, 0.5, 0.5, 0.5 }, + { 100, 0.25, 0.25, 0.25 }, + { 101, 0.75, 0, 0 }, + { 102, 0, 0.75, 0 }, + { 103, 0.75, 0.75, 0 }, + { 104, 0, 0, 0.75 }, + { 105, 0.75, 0, 0.75 }, + { 106, 0, 0.75, 0.75 }, + { 107, 0.75, 0.75, 0.75 }, +}; + +color_t *findcolor (float red, float green, float blue) +{ + color_t *color = NULL; + int i; + float dist = 3; + for (i = 0; i < nbcolors; i++) { + float r = (colors + i)->red - red; + float g = (colors + i)->green - green; + float b = (colors + i)->blue - blue; + float d = r * r + g * g + b * b; + if (d < dist) { + dist = d; + color = colors + i; + } + } + return color; +} + +void cprint (color_t *color, char *str) +{ + printf ("\e[%dm%s\e[0m", (color) ? color->code : 30, str); +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/color.h b/color.h new file mode 100644 index 0000000..65be10e --- /dev/null +++ b/color.h @@ -0,0 +1,17 @@ +#ifndef __COLOR_H__ +#define __COLOR_H__ + +typedef struct { + int code; + float red; + float green; + float blue; +} color_t; + +color_t *findcolor (float red, float green, float blue); + +void cprint (color_t *color, char *str); + +#endif /* __COLOR_H__ */ + +/* vim: set ts=4 sw=4 et: */ diff --git a/display.c b/display.c index 31e7a38..d0f44c6 100644 --- a/display.c +++ b/display.c @@ -1,54 +1,31 @@ /* depend: */ /* cflags: */ -/* linker: */ -/* doslnk: */ -/* winlnk: */ +/* linker: color.o image.o ppm.o */ +/* doslnk: color.o image.o ppm.o */ +/* winlnk: color.o image.o ppm.o */ #include -#include -typedef struct { - int code; - int red; - int green; - int blue; -} color_t; - -#define nbcolors 16 - -color_t colors[nbcolors] = { - { 40, 0, 0, 0 }, - { 41, 2, 0, 0 }, - { 42, 0, 2, 0 }, - { 43, 2, 2, 0 }, - { 44, 0, 0, 2 }, - { 45, 2, 0, 2 }, - { 46, 0, 2, 2 }, - { 47, 2, 2, 2 }, - { 100, 1, 1, 1 }, - { 101, 3, 0, 0 }, - { 102, 0, 3, 0 }, - { 103, 3, 3, 0 }, - { 104, 0, 0, 3 }, - { 105, 3, 0, 3 }, - { 106, 0, 3, 3 }, - { 107, 3, 3, 3 }, -}; - -void cprint (color_t *color, char *str) -{ - printf ("\e[%dm%s\e[0m", (color) ? color->code : 30, str); -} +#include "color.h" +#include "image.h" +#include "ppm.h" int main (int argc, char *argv[]) { int i; - - for (i = 0; i < nbcolors; i++) { - char *str = (argc > 1) ? argv[(i % (argc - 1)) + 1] : " "; - cprint (colors + i, str); + for (i = 1; i < argc; i++) { + image_t *image = readppm (argv[i]); + + int k, l; + for (k = 0; k < image->width; k++) { + for (l = 0; l < image->height; l++) { + int ind = k + image->width * l; + color_t *color = findcolor (image->red[ind], image->green[ind], image->blue[ind]); + cprint (color, " "); + } + printf ("\n"); + } } - printf ("\n"); return 0; } diff --git a/image.c b/image.c new file mode 100644 index 0000000..9efb3a4 --- /dev/null +++ b/image.c @@ -0,0 +1,25 @@ +#include + +#include "image.h" + +image_t *newimage (int width, int height) +{ + image_t *image = (image_t *) calloc (1, sizeof (image_t)); + image->red = (float *) calloc (width * height, sizeof (float)); + image->green = (float *) calloc (width * height, sizeof (float)); + image->blue = (float *) calloc (width * height, sizeof (float)); + image->width = width; + image->height = height; + return image; +} + +void freeimage (image_t *image) +{ + if (image) { + free (image->red); + free (image->green); + free (image->blue); + } +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/image.h b/image.h new file mode 100644 index 0000000..1cc6f2c --- /dev/null +++ b/image.h @@ -0,0 +1,16 @@ +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +typedef struct { + float *red; + float *green; + float *blue; + int width; + int height; +} image_t; + +image_t *newimage (int width, int height); + +void freeimage (image_t *image); + +#endif /* __IMAGE_H__ */ diff --git a/makefile b/makefile index 4885091..7c570fa 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ CC = gcc #INCLUDES = -I../debug -D__MEMORY_ALLOCATION__ INCLUDES = -OFLAGS = -O4 -Os +#OFLAGS = -O4 -Os #OFLAGS = -O4 -ffast-math -finline-functions #OFLAGS = -O4 -finline-functions #OFLAGS += -mtune=pentium3 -mmmx -msse -msse2 -m3dnow diff --git a/ppm.c b/ppm.c new file mode 100644 index 0000000..7d7ad1c --- /dev/null +++ b/ppm.c @@ -0,0 +1,100 @@ +#include +#include + +#include "image.h" + +int contain (char *str, char c) +{ + while (*str != c) { + if (*str++ == '\0') { + return 0; + } + } + return 1; +} + +int readnumber (FILE *fd) +{ + int num = 0; + fscanf (fd, "%d", &num); + char c = 0; + c = fgetc (fd); + if (!contain (" \t\n\r", c)) { + num = 0; + } + return num; +} + +float getcolor (char *buffer, int maxcolor) +{ + float color = *(buffer++) / (float)maxcolor; + if (maxcolor > 255) { + color *= 256; + color += *buffer / (float)maxcolor; + } + return color; +} + +image_t *readppm (char *filename) +{ + char *buffer = NULL; + image_t *image = NULL; + + /* open file */ + FILE *fd = fopen (filename, "rb"); + if (!fd) { + return NULL; + } + + /* check magic number */ + char magic[3] = {0}; + fread (magic, 3, 1, fd); + if ((!contain ("P", magic[0])) || + (!contain ("6", magic[1])) || + (!contain (" \t\n\r", magic[2]))) { + goto err; + } + + /* get width */ + int width = readnumber (fd); + if (width == 0) { + goto err; + } + + /* get height */ + int height = readnumber (fd); + if (height == 0) { + goto err; + } + + /* get maxcolor */ + int maxcolor = readnumber (fd); + if (maxcolor == 0) { + goto err; + } + + /* read full image */ + int size = 3 * width * height * ((maxcolor > 255) ? 2 : 1); + buffer = (char *) calloc (size, 1); + if (!fread (buffer, size, 1, fd)) { + goto err; + } + + /* create image */ + image = newimage (width, height); + int i = 0; + int gap = (maxcolor > 255) ? 2 : 1; + while (i < width * height) { + image->red[i] = getcolor (buffer + (3 * gap) * i, maxcolor); + image->green[i] = getcolor (buffer + (3 * gap) * i + gap, maxcolor); + image->blue[i] = getcolor (buffer + (3 * gap) * i + 2 * gap, maxcolor); + i++; + } + +err: + free (buffer); + fclose (fd); + return image; +} + +/* vim: set ts=4 sw=4 et: */ diff --git a/ppm.h b/ppm.h new file mode 100644 index 0000000..2a29bdd --- /dev/null +++ b/ppm.h @@ -0,0 +1,8 @@ +#ifndef __PPM_H__ +#define __PPM_H__ + +#include "image.h" + +image_t *readppm (char *filename); + +#endif /* __PPM_H__ */ -- 2.30.2