add pgm loader
authorLaurent MAZET <laurent.mazet@thalesgroup.com>
Thu, 12 Sep 2024 17:18:09 +0000 (19:18 +0200)
committerLaurent MAZET <laurent.mazet@thalesgroup.com>
Thu, 12 Sep 2024 17:18:09 +0000 (19:18 +0200)
display.c
image.c
image.h
pgm.c [new file with mode: 0644]
pgm.h [new file with mode: 0644]
ppm.c

index d0f44c6be7b90ef8d7c23a44cfb4e63d1672296a..c11824bba2312b0eac2f628b696c616cbfa93be0 100644 (file)
--- a/display.c
+++ b/display.c
@@ -1,8 +1,8 @@
 /* depend: */
 /* cflags: */
-/* linker: color.o image.o ppm.o */
-/* doslnk: color.o image.o ppm.o */
-/* winlnk: color.o image.o ppm.o */
+/* linker: color.o image.o pgm.o ppm.o */
+/* doslnk: color.o image.o pgm.o ppm.o */
+/* winlnk: color.o image.o pgm.o ppm.o */
 
 #include <stdio.h>
 
@@ -12,6 +12,7 @@
 
 int main (int argc, char *argv[])
 {
+    float gamma = 1.;
     int i;
     for (i = 1; i < argc; i++) {
        image_t *image = readppm (argv[i]);
@@ -20,7 +21,7 @@ int main (int argc, char *argv[])
        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]);
+               color_t *color = findcolor (gamma * image->red[ind], gamma * image->green[ind], gamma * image->blue[ind]);
                cprint (color, " ");
            }
            printf ("\n");
diff --git a/image.c b/image.c
index 9efb3a47800127dd7309ff42de9bf3227794eab4..81ebbe3a5e15f32f83cb0694562c171e823fa5f1 100644 (file)
--- a/image.c
+++ b/image.c
@@ -22,4 +22,36 @@ void freeimage (image_t *image)
     }
 }
 
+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 getvalue (char *buffer, int maxvalue)
+{
+    float value = *(buffer++) / (float)maxvalue;
+    if (maxvalue > 255) {
+        value *= 256;
+        value += *buffer / (float)maxvalue;
+    }
+    return value;
+}
+
 /* vim: set ts=4 sw=4 et: */
diff --git a/image.h b/image.h
index 1cc6f2c0d7d3c3b0cb2031c58842bb335c7cc784..657424f6f78b90b171f96091b76dbdd19bddb62f 100644 (file)
--- a/image.h
+++ b/image.h
@@ -1,6 +1,8 @@
 #ifndef __IMAGE_H__
 #define __IMAGE_H__
 
+#include <stdio.h>
+
 typedef struct {
     float *red;
     float *green;
@@ -13,4 +15,10 @@ image_t *newimage (int width, int height);
 
 void freeimage (image_t *image);
 
+int contain (char *str, char c);
+
+int readnumber (FILE *fd);
+
+float getvalue (char *buffer, int maxvalue);
+
 #endif /* __IMAGE_H__ */
diff --git a/pgm.c b/pgm.c
new file mode 100644 (file)
index 0000000..7743520
--- /dev/null
+++ b/pgm.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "image.h"
+
+image_t *readpgm (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 ("5", 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 maxvalue */
+    int maxvalue = readnumber (fd);
+    if (maxvalue == 0) {
+        goto err;
+    }
+
+    /* read full image */
+    int size = width * height * ((maxvalue > 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 = (maxvalue > 255) ? 2 : 1;
+    while (i < width * height) {
+        image->red[i] = image->green[i] = image->blue[i] = getvalue (buffer + gap * i, maxvalue);
+        i++;
+    }
+
+err:
+    free (buffer);
+    fclose (fd);
+    return image;
+}
+
+/* vim: set ts=4 sw=4 et: */
diff --git a/pgm.h b/pgm.h
new file mode 100644 (file)
index 0000000..b634a8f
--- /dev/null
+++ b/pgm.h
@@ -0,0 +1,8 @@
+#ifndef __PGM_H__
+#define __PGM_H__
+
+#include "image.h"
+
+image_t *readpgm (char *filename);
+
+#endif /* __PPM_H__ */
diff --git a/ppm.c b/ppm.c
index 7d7ad1c15672ff951c4331bc9511cd3636371fed..538b1531668d610fd8779bbed3eb096c964b9ac7 100644 (file)
--- a/ppm.c
+++ b/ppm.c
@@ -3,38 +3,6 @@
 
 #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;
@@ -85,9 +53,9 @@ image_t *readppm (char *filename)
     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);
+        image->red[i] = getvalue (buffer + (3 * gap) * i, maxcolor);
+        image->green[i] = getvalue (buffer + (3 * gap) * i + gap, maxcolor);
+        image->blue[i] = getvalue (buffer + (3 * gap) * i + 2 * gap, maxcolor);
         i++;
     }