From 54f5dd35b730c93f38b8c05a941b01b1c8068c18 Mon Sep 17 00:00:00 2001 From: Laurent MAZET Date: Fri, 13 Sep 2024 18:38:44 +0200 Subject: [PATCH] reimplement PNM reading (partial) --- image.c | 3 +- image.h | 3 +- pnm.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 pnm.c diff --git a/image.c b/image.c index 98ff1bb..6cf8a29 100644 --- a/image.c +++ b/image.c @@ -2,7 +2,7 @@ #include "image.h" -image_t *newimage (int width, int height) +image_t *newimage (int width, int height, int maxvalue) { image_t *image = (image_t *) calloc (1, sizeof (image_t)); image->red = (float *) calloc (width * height, sizeof (float)); @@ -10,6 +10,7 @@ image_t *newimage (int width, int height) image->blue = (float *) calloc (width * height, sizeof (float)); image->width = width; image->height = height; + image->maxvalue = maxvalue; return image; } diff --git a/image.h b/image.h index 3d8eb26..c6d7f07 100644 --- a/image.h +++ b/image.h @@ -9,9 +9,10 @@ typedef struct { float *blue; int width; int height; + int maxvalue; } image_t; -image_t *newimage (int width, int height); +image_t *newimage (int width, int height, int maxvalue); void freeimage (image_t *image); diff --git a/pnm.c b/pnm.c new file mode 100644 index 0000000..06f0535 --- /dev/null +++ b/pnm.c @@ -0,0 +1,105 @@ +#include +#include + +#include "image.h" + +int testpnm (FILE *fd) +{ + int mode = 0; + /* check magic number */ + char magic[3] = {0}; + fread (magic, 3, 1, fd); + if ((contain ("P", magic[0])) && (contain (" \t\n\r", magic[2]))) { + if ((magic[1] >= '1') && (magic[1] <= '6')) { + mode = '0' - magic[2]; + } + } + return mode; +} + +int getvalue (FILE *fd, int nbbytes) +{ + int v = fgetc (fd); + if (v != EOF) { + if (nbbytes == 2) { + int v0 = fgetc (fd); + v = (v0 != EOF) ? v * 256 + v0 : EOF; + } + } + return v; +} + +int readpgm (FILE *fd, image_t *image) +{ + while (i < image->width * image->height) { + image->red[i] = image->green[i] = image->blue[i] = getvalue (fd, image->maxvalue); + } + return image->blue[image->width * image->height - 1]; +} + +int readppm (FILE *fd, image_t *image) +{ + while (i < image->width * image->height) { + image->red[i] = getvalue (fd, image->maxvalue); + image->green[i] = getvalue (fd, image->maxvalue); + image->blue[i] = getvalue (fd, image->maxvalue); + } + return image->blue[image->width * image->height - 1]; +} + +image_t *readpnm (char *filename) +{ + image_t *image = NULL; + + /* open file */ + FILE *fd = fopen (filename, "rb"); + if (!fd) { + goto err; + } + + /* test PNM type */ + int mode = testpnm (fd); + if (mode == 0) { + goto err; + } + + /* read parameters */ + int width = 0; + int height = 0; + int maxvalue = 0; + if (!getparam (fd, &width, &height, &maxvalue)) { + goto err; + } + + /* allocate image */ + image_t *image = newimage (width, height); + + /* read data */ + int rc = 0; + switch (mode) { + case 1: // PBM ascii + case 2: // PGM ascii + case 3: // PPM ascii + case 4: // PBM raw + break; + case 5: // PGM raw + rc = readpgm (fd, image); + break; + case 6: // PPM raw + rc = readppm (fd, image); + break; + } + if (rc == 0) { + freeimage (image); + image = NULL; + } + +err: + if (fd) { + fclose (fd); + } + + return image; +} + +/* vim: set ts=4 sw=4 et: */ -- 2.30.2