first version
authorLaurent MAZET <laurent.mazet@thalesgroup.com>
Thu, 12 Sep 2024 16:07:48 +0000 (18:07 +0200)
committerLaurent MAZET <laurent.mazet@thalesgroup.com>
Thu, 12 Sep 2024 16:07:48 +0000 (18:07 +0200)
color.c [new file with mode: 0644]
color.h [new file with mode: 0644]
display.c
image.c [new file with mode: 0644]
image.h [new file with mode: 0644]
makefile
ppm.c [new file with mode: 0644]
ppm.h [new file with mode: 0644]

diff --git a/color.c b/color.c
new file mode 100644 (file)
index 0000000..38fb9c3
--- /dev/null
+++ b/color.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+
+#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 (file)
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: */
index 31e7a3885582751656a39106bcf05808ee4a5161..d0f44c6be7b90ef8d7c23a44cfb4e63d1672296a 100644 (file)
--- 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 <stdio.h>
-#include <stdlib.h>
 
-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 (file)
index 0000000..9efb3a4
--- /dev/null
+++ b/image.c
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+
+#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 (file)
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__ */
index 488509102ef33abf2d3e5516238a68e7d9de340e..7c570fa68e99359546738c7a4b2a0d852b9fcc25 100644 (file)
--- 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 (file)
index 0000000..7d7ad1c
--- /dev/null
+++ b/ppm.c
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#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 (file)
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__ */