From ac66e2b7240be684901738a1624ae3da29cad654 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sat, 14 Sep 2024 01:11:35 +0200 Subject: [PATCH] reimplement PNM reading (raw) --- display.c | 25 +++++++++----- image.c | 22 ------------ image.h | 4 --- pgm.c | 66 ----------------------------------- pgm.h | 8 ----- pnm.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++-------- pnm.h | 8 +++++ ppm.c | 68 ------------------------------------- ppm.h | 8 ----- 9 files changed, 110 insertions(+), 199 deletions(-) delete mode 100644 pgm.c delete mode 100644 pgm.h create mode 100644 pnm.h delete mode 100644 ppm.c delete mode 100644 ppm.h diff --git a/display.c b/display.c index b2aa9e7..2ed3d9a 100644 --- a/display.c +++ b/display.c @@ -1,8 +1,8 @@ /* depend: */ /* cflags: */ -/* linker: color.o debug.o image.o pgm.o ppm.o -lm */ -/* doslnk: color.o debug.o image.o pgm.o ppm.o -lm */ -/* winlnk: color.o debug.o image.o pgm.o ppm.o -lm */ +/* linker: color.o debug.o image.o pnm.o -lm */ +/* doslnk: color.o debug.o image.o pnm.o -lm */ +/* winlnk: color.o debug.o image.o pnm.o -lm */ #include #include @@ -11,24 +11,24 @@ #include "color.h" #include "debug.h" #include "image.h" -#include "pgm.h" -#include "ppm.h" +#include "pnm.h" /* static variables */ char *progname = NULL; char *version = "0.1"; -float gf[3] = { 1.0, 1.0, 1.0 }; +float gf[3] = { 1.0f, 1.0f, 1.0f }; int mode = 0; /* help message */ int usage (int ret) { FILE *fd = ret ? stderr : stdout; - fprintf (fd, "usage: %s [-g gamma] [-h] [-t|-w] \n", progname); + fprintf (fd, "usage: %s [-g gamma] [-h] [-t|-w] [-v int] \n", progname); fprintf (fd, " -g: gamma correction (%.1f:%.1f:%.1f)\n", gf[0], gf[1], gf[2]); fprintf (fd, " -h: help message\n"); fprintf (fd, " -t: thin mode (%s)\n", (mode == 0) ? "on" : "off"); + fprintf (fd, " -v: verbose level (%d)\n", verbose); fprintf (fd, " -w: wide mode (%s)\n", (mode == 1) ? "on" : "off"); fprintf (fd, "%s version %s\n", progname, version); @@ -87,6 +87,14 @@ int main (int argc, char *argv[]) case 't': mode = 0; break; + case 'v': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ERROR, fprintf (stderr, "%s: missing verbose level\n", progname)); + return usage (1); + } + verbose = atoi (arg); + break; case 'w': mode = 1; break; @@ -107,7 +115,7 @@ int main (int argc, char *argv[]) } /* main process */ - image_t *image = readppm (filename); + image_t *image = readpnm (filename); int k, l; for (l = 0; l < image->height; l++) { @@ -126,5 +134,6 @@ int main (int argc, char *argv[]) /* test: display.exe -g 2>&1 | grep 'no gamma specified' */ /* test: display.exe -g -1.0 2>&1 | grep 'incorrect gamma' */ /* test: display.exe -h | grep usage */ +/* test: display.exe -v 2>&1 | grep missing */ /* vim: set ts=4 sw=4 et: */ diff --git a/image.c b/image.c index 6cf8a29..49cb9fb 100644 --- a/image.c +++ b/image.c @@ -33,26 +33,4 @@ int contain (char *str, char c) 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 (unsigned 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 c6d7f07..e6542aa 100644 --- a/image.h +++ b/image.h @@ -18,8 +18,4 @@ void freeimage (image_t *image); int contain (char *str, char c); -int readnumber (FILE *fd); - -float getvalue (unsigned char *buffer, int maxvalue); - #endif /* __IMAGE_H__ */ diff --git a/pgm.c b/pgm.c deleted file mode 100644 index 9dd11b0..0000000 --- a/pgm.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include - -#include "image.h" - -image_t *readpgm (char *filename) -{ - unsigned 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 = (unsigned 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 deleted file mode 100644 index b634a8f..0000000 --- a/pgm.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __PGM_H__ -#define __PGM_H__ - -#include "image.h" - -image_t *readpgm (char *filename); - -#endif /* __PPM_H__ */ diff --git a/pnm.c b/pnm.c index 06f0535..6c90bf4 100644 --- a/pnm.c +++ b/pnm.c @@ -1,6 +1,7 @@ #include #include +#include "debug.h" #include "image.h" int testpnm (FILE *fd) @@ -11,40 +12,96 @@ int testpnm (FILE *fd) 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]; + mode = magic[1] - '0'; } } return mode; } +int getparam (FILE *fd, int *value) +{ + int start = 0; + *value = 0; + while (!feof (fd)) { + int c = fgetc (fd); + if (contain ("#", c)) { + while (!feof (fd)) { + c = fgetc (fd); + if (contain ("\n\r", c)) { + break; + } + } + } + if (contain ("0123456789", c)) { + *value = 10 * *value + c - '0'; + start = 1; + } + if ((start) && (contain (" \n\r\t", c))) { + return 1; + } + } + return 0; +} + int getvalue (FILE *fd, int nbbytes) { - int v = fgetc (fd); - if (v != EOF) { + int value = fgetc (fd); + if (value != EOF) { if (nbbytes == 2) { - int v0 = fgetc (fd); - v = (v0 != EOF) ? v * 256 + v0 : EOF; + int value0 = fgetc (fd); + value = (value0 != EOF) ? value * 256 + value0 : EOF; + } + } + return value; +} + +int readpbm (FILE *fd, image_t *image) +{ + int i = 0; + int k = 0; + int value = EOF; + while (i < image->width * image->height) { + if (k == 0) { + value = fgetc (fd); + k = 8; + } + image->red[i] = image->green[i] = image->blue[i] = !((value >> --k) & 1); + i++; + if (i % image->width == 0) { + k = 0; } } - return v; + return (value != EOF); } int readpgm (FILE *fd, image_t *image) { + int i = 0; + int nbbytes = (image->maxvalue > 255) ? 2 : 1; + int value = EOF; while (i < image->width * image->height) { - image->red[i] = image->green[i] = image->blue[i] = getvalue (fd, image->maxvalue); + value = getvalue (fd, nbbytes); + image->red[i] = image->green[i] = image->blue[i] = value / (float)image->maxvalue; + i++; } - return image->blue[image->width * image->height - 1]; + return (value != EOF); } int readppm (FILE *fd, image_t *image) { + int i = 0; + int nbbytes = (image->maxvalue > 255) ? 2 : 1; + int value = EOF; 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); + value = getvalue (fd, nbbytes); + image->red[i] = value / (float)image->maxvalue; + value = getvalue (fd, nbbytes); + image->green[i] = value / (float)image->maxvalue; + value = getvalue (fd, nbbytes); + image->blue[i] = value / (float)image->maxvalue; + i++; } - return image->blue[image->width * image->height - 1]; + return (value != EOF); } image_t *readpnm (char *filename) @@ -62,17 +119,29 @@ image_t *readpnm (char *filename) if (mode == 0) { goto err; } + VERBOSE (DEBUG, printf ("mode: %d\n", mode)); /* read parameters */ int width = 0; + if (!getparam (fd, &width)) { + goto err; + } + VERBOSE (DEBUG, printf ("width: %d\n", width)); int height = 0; - int maxvalue = 0; - if (!getparam (fd, &width, &height, &maxvalue)) { + if (!getparam (fd, &height)) { goto err; } + VERBOSE (DEBUG, printf ("height: %d\n", height)); + int maxvalue = 1; + if ((mode != 1) && (mode != 4)) { + if (!getparam (fd, &maxvalue)) { + goto err; + } + } + VERBOSE (DEBUG, printf ("maxvalue: %d\n", maxvalue)); /* allocate image */ - image_t *image = newimage (width, height); + image = newimage (width, height, maxvalue); /* read data */ int rc = 0; @@ -81,6 +150,7 @@ image_t *readpnm (char *filename) case 2: // PGM ascii case 3: // PPM ascii case 4: // PBM raw + rc = readpbm (fd, image); break; case 5: // PGM raw rc = readpgm (fd, image); diff --git a/pnm.h b/pnm.h new file mode 100644 index 0000000..04fbfd8 --- /dev/null +++ b/pnm.h @@ -0,0 +1,8 @@ +#ifndef __PNM_H__ +#define __PNM_H__ + +#include "image.h" + +image_t *readpnm (char *filename); + +#endif /* __PNM_H__ */ diff --git a/ppm.c b/ppm.c deleted file mode 100644 index b5efcd3..0000000 --- a/ppm.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -#include "image.h" - -image_t *readppm (char *filename) -{ - unsigned 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 = (unsigned 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] = 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++; - } - -err: - free (buffer); - fclose (fd); - return image; -} - -/* vim: set ts=4 sw=4 et: */ diff --git a/ppm.h b/ppm.h deleted file mode 100644 index 2a29bdd..0000000 --- a/ppm.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __PPM_H__ -#define __PPM_H__ - -#include "image.h" - -image_t *readppm (char *filename); - -#endif /* __PPM_H__ */ -- 2.30.2