From 5cb374c2b5d928ebb39eb802030987648c5ddb3d Mon Sep 17 00:00:00 2001 From: Sven-Bodo Scholz Date: Wed, 3 Dec 2025 09:38:30 +0100 Subject: [PATCH 1/3] moved the implementation of PPM to SaC entirely. --- src/PPM.sac | 205 ++++++++++++++++++++++++++++++++-------- src/src/PPM/array2ppm.c | 58 ------------ src/src/PPM/ppm2array.c | 137 --------------------------- 3 files changed, 164 insertions(+), 236 deletions(-) delete mode 100644 src/src/PPM/array2ppm.c delete mode 100644 src/src/PPM/ppm2array.c diff --git a/src/PPM.sac b/src/PPM.sac index a7ba7b3..258e6c9 100644 --- a/src/PPM.sac +++ b/src/PPM.sac @@ -1,42 +1,20 @@ module PPM; -use Color8: { Color8, dim, shape }; -use File: { File, fopen, fclose }; -use ScalarArith: { == }; -use String: { string }; -use TermFile: { TermFile, stdin, stdout }; - -export { readPPM, printPPM }; - -external Color8[.,.] readStream(TermFile &stream); - #pragma effect Terminal::TheTerminal - #pragma linkobj "src/PPM/ppm2array.o" - #pragma linkname "SAC_PPM_ppm2array" - #pragma refcounting [0] - #pragma linksign [1,2] - -external Color8[.,.] readStream(File &stream); - #pragma effect FileSystem::TheFileSystem - #pragma linkobj "src/PPM/ppm2array.o" - #pragma linkname "SAC_PPM_ppm2array" - #pragma refcounting [0] - #pragma linksign [1,2] - -external void writeStream(TermFile &stream, Color8[.,.] image, - int[2] shp, bool binary); - #pragma effect Terminal::TheTerminal - #pragma linkobj "src/PPM/array2ppm.o" - #pragma linkname "SAC_PPM_array2ppm" - -external void writeStream(File &stream, Color8[.,.] image, - int[2] shp, bool binary); - #pragma effect FileSystem::TheFileSystem - #pragma linkobj "src/PPM/array2ppm.o" - #pragma linkname "SAC_PPM_array2ppm" +use Structures: all; +import File: all; +import TermFile: all; + +export { readPPM, writePPM }; + +/******************************************************************************* + * + * readPPM + * + ******************************************************************************/ inline Color8[.,.] readPPM() { - return readStream(stdin); + return readPPMf(stdin, "stdin"); } inline Color8[.,.] readPPM(string name) @@ -48,25 +26,170 @@ inline Color8[.,.] readPPM(string name) name); } - ret = readStream(fp); + ret = readPPMf(fp, name); fclose(fp); return(ret); } -inline void printPPM(Color8[2:shp] img) +#define READ_LINE_F(TF) \ +string fgetLine (TF &fp, string name) \ +{ \ + err, line = fgetl (fp); \ + if (SysErr::fail(err)) { \ + RuntimeError::error((int)err, \ + "Error when trying to read a line from %s", \ + name); \ + } \ + return line; \ +} + +READ_LINE_F(File) + +READ_LINE_F(TermFile) + + + + +#define READ_PPM_F(TF) \ +Color8[h,w] readPPMf (TF &fp, string name) \ +{ \ + int c, h, w, max; \ + /* \ + * Check for a valid header \ + */ \ + line = fgetLine (fp, name); \ + if ( (strsel (line, 0) != 'P') \ + || ((strsel (line, 1) != '3') \ + && (strsel (line, 1) != '6')) ) { \ + RuntimeError::error(0, \ + "Neither header P3 nor P6 found. Not a .ppm file"); \ + } \ + binary = (strsel (line, 1) == '6'); \ + \ + /* \ + * Check for comment (and ignore it) \ + */ \ + comment = true; \ + while (comment) { \ + line = fgetLine (fp, name); \ + comment = (strsel (line, 0) == '#'); \ + } \ + \ + /* \ + * Get the dimensions of the image \ + * and allocate an array of sufficient size \ + */ \ + num_read, w, h = sscanf (line, "%d %d"); \ + if (num_read != 2) \ + RuntimeError::error(0, \ + "Failed to read width and height of the image");\ + data = genarray ([w,h,3], 0); \ + \ + /* \ + * Read out the maximum value \ + */ \ + line = fgetLine (fp, name); \ + num_read, max = sscanf (line, "%d"); \ + if (num_read != 1) \ + RuntimeError::error(0, \ + "Failed to read max value of the image"); \ + \ + /* \ + * Readout the image \ + */ \ + for (i = 0; i < h; i++) { \ + for (j = 0; j < w; j++) { \ + for (k = 0; k < 3; k++) { \ + if (binary) \ + c = toi (fgetc (fp)); \ + else \ + num, c = fscanf (fp, "%d"); \ + data[i,j,k] = c * (255/max); \ + } \ + } \ + } \ + cols = {[i,j] -> newColor (data[i,j]) | [i,j] < [h,w]}; \ + return cols; \ +} + +READ_PPM_F( File) + +READ_PPM_F( TermFile) + +/******************************************************************************* + * + * writePPM + * + ******************************************************************************/ + +void writePPM (Color8[2:shp] img) { - writeStream(stdout, img, shp, false); + writePPMf (stdout, img, false); } -inline void printPPM(Color8[2:shp] img, string name, bool binary) + +void writePPM (Color8[2:shp] img, string name, bool binary) { err, fp = fopen(name, "w+"); - if (SysErr::fail(err)) { + if (SysErr::fail (err)) { RuntimeError::error((int)err, "Error occured when trying to open file %s for writing", name); } - writeStream(fp, img, shp, binary); - fclose(fp); + writePPMf (fp, img, binary); + fclose (fp); +} + + +#define WRITE_PPM_F( TF) \ +void writePPMf (TF &fp, Color8[h,w] img, bool binary) \ +{ \ + if ( binary == false) { \ + /* \ + * ASCII output \ + */ \ + fprintf(fp, "P3\n"); \ + \ + fprintf(fp, "%d %d\n", w, h); \ + fprintf(fp, "255\n"); \ + \ + for(i = 0; i < h; i++) { \ + for (j = 0; j < w; j++) { \ + fprintf(fp, "%d %d %d", toi (img[i,j])[0], \ + toi (img[i,j])[1], \ + toi (img[i,j])[2]); \ + \ + if (j != w-1) { \ + fprintf(fp, " "); \ + } \ + } \ + fprintf(fp, "\n"); \ + } \ + \ + } \ + else { \ + /* \ + * Binary output \ + */ \ + fprintf(fp, "P6\n"); \ + \ + fprintf(fp, "%d %d\n", w, h); \ + fprintf(fp, "255\n"); \ + \ + for(i = 0; i < h; i++) { \ + for (j = 0; j < w; j++) { \ + fprintf(fp, "%c%c%c", tochar (toi (img[i,j])[0]), \ + tochar (toi (img[i,j])[1]), \ + tochar (toi (img[i,j])[2])); \ + \ + } \ + } \ + } \ } + +WRITE_PPM_F(File) + +WRITE_PPM_F(TermFile) + + diff --git a/src/src/PPM/array2ppm.c b/src/src/PPM/array2ppm.c deleted file mode 100644 index 28a0e4d..0000000 --- a/src/src/PPM/array2ppm.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include - -#include "sac.h" - -typedef char* string; - -#define array_nt (array, T_OLD((AKD, (NHD, (NUQ, ))))) - -void SAC_PPM_array2ppm( FILE *fp, - SAC_ND_PARAM_in_nodesc( array_nt, int), - int shape[2], - bool binary) -{ - const int w = shape[1]; - const int h = shape[0]; - int i, j; - - /* - * ASCII output - */ - if ( binary == false) { - fprintf(fp, "P3\n"); - - fprintf(fp, "%d %d\n", w, h); - fprintf(fp, "255\n"); - - for(i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - fprintf(fp, "%d %d %d", SAC_ND_A_FIELD(array_nt)[(i*w+j)*3], - SAC_ND_A_FIELD(array_nt)[(i*w+j)*3+1], - SAC_ND_A_FIELD(array_nt)[(i*w+j)*3+2]); - - if (j != w-1) { - fprintf(fp, " "); - } - } - fprintf(fp, "\n"); - } - - } - /* - * Binary output - */ - else { - fprintf(fp, "P6\n"); - - fprintf(fp, "%d %d\n", w, h); - fprintf(fp, "255\n"); - - for(i = 0; i < h * w * 3; i++) { - fprintf(fp, "%c", SAC_ND_A_FIELD(array_nt)[i]); - } - } -} - diff --git a/src/src/PPM/ppm2array.c b/src/src/PPM/ppm2array.c deleted file mode 100644 index f482000..0000000 --- a/src/src/PPM/ppm2array.c +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include - -#include "sac.h" - -typedef char* string; - -#define array_nt (array, T_OLD((AKD, (NHD, (NUQ, ))))) -#define ret_nt (ret, T_OLD((AKD, (NHD, (NUQ, ))))) - -#define MAXLINE 80 - -/* - * Read a ppm (ascii or binary) image. - */ -void SAC_PPM_ppm2array( SAC_ND_PARAM_out( array_nt, int), - FILE *fp) -{ - char line[MAXLINE]; - int w; - int h; - int i; - int max; - int *data; - unsigned int c; - bool binary; - bool comment; - - /* - * Check for a valid header - */ - if (fgets(line, MAXLINE, fp) == NULL) { - SAC_RuntimeError( "Unexpected error when reading file"); - } - if ( (line[0] != 'P' && line[1] != '3') || (line[0] != 'P' && line[1] != '6') ) { - SAC_RuntimeError( "Not reading a PPM file!"); - } - - /* - * Check if we are reading an ascii or binary file - */ - if (line[1] == '3') { - binary = false; - } else { - binary = true; - } - - /* - * Check for comment (and ignore it) - */ - while(true) { - if (fgets(line, MAXLINE, fp) == NULL) { - SAC_RuntimeError( "Unexpected error when reading file"); - } - - /* - * Check for a comment line - */ - if (line[0] == '#') { - comment = true; - - while(comment == true) { - for(i = 0; i < MAXLINE; i++) { - if (line[i] == '\n') { - comment = false; - break; - } - } - - if (comment == true) { - if (NULL == fgets(line, MAXLINE, fp)) - break; - } - } - } else { - break; - } - } - - /* - * Get the dimensions of the image - * and allocate an array of sufficient size - */ - if (sscanf(line, "%d %d", &w, &h) != 2) { - SAC_RuntimeError( "Unexpected error when reading file"); - } - data = malloc(sizeof(int) * w * h * 3); - if (data == NULL) { - SAC_RuntimeError( "Could not allocate data for image array"); - } - - /* - * Read out the maximum value - */ - if (fgets(line, MAXLINE, fp) == NULL) { - SAC_RuntimeError( "Unexpected error when reading file"); - } - if (sscanf(line, "%d", &max) != 1) { - SAC_RuntimeError( "Unexpected error when reading file"); - } - - /* - * Readout the image - */ - if (binary == true) { - for (i = 0; i < h*w*3; i++) { - c = 0; - if(fread(&c, 1, 1, fp) != 1) { - SAC_RuntimeError( "Unexpected end of file" ); - } - data[i] = c * (255/max); - } - } else { - for (i = 0; i < h*w*3; i++) { - if( fscanf(fp, "%u", &c) != 1) { - SAC_RuntimeError( "Unexpected end of file"); - } - data[i] = c * (255/max); - } - } - - /* - * Create the SAC resturn array & descriptor - */ - SAC_ND_DECL__DATA( ret_nt, int, ) - SAC_ND_DECL__DESC( ret_nt, ) - int SAC_ND_A_MIRROR_DIM( ret_nt) = 3; - SAC_ND_ALLOC__DESC( ret_nt, dims) - SAC_ND_SET__RC( ret_nt, 1) - SAC_ND_A_DESC_SHAPE( ret_nt, 0) = h; - SAC_ND_A_DESC_SHAPE( ret_nt, 1) = w; - SAC_ND_A_DESC_SHAPE( ret_nt, 2) = 3; - SAC_ND_A_FIELD( ret_nt) = data; - SAC_ND_RET_out( array_nt, ret_nt) -} From b8d892c8e9d8ad13b595fa30886cdc165409da89 Mon Sep 17 00:00:00 2001 From: Sven-Bodo Scholz Date: Wed, 3 Dec 2025 09:51:35 +0100 Subject: [PATCH 2/3] extended Jprdy's ugly cmake hack. --- src/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d1fb1b..217bf71 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,8 +11,6 @@ SET (C_DEPS_SRC src/PNG/array2png.c src/PNG/imshow.c src/PNG/png2array.c - src/PPM/array2ppm.c - src/PPM/ppm2array.c ) # SaC files @@ -99,7 +97,7 @@ FOREACH (name ${SAC_SRC}) # The current system cannot find Stdlib files. This is a really ugly solution: # we manually remove known Stdlib dependencies, and assume they exist. # I don't know how to fix this... - LIST(FILTER deps_list EXCLUDE REGEX ".*(Array|Color8|File|FileSystem|Process|RuntimeError|ScalarArith|String|SysErr|TermFile|Terminal|World)") + LIST(FILTER deps_list EXCLUDE REGEX ".*(Structures|Array|Color8|File|FileSystem|Process|RuntimeError|ScalarArith|String|SysErr|TermFile|Terminal|World)") # Make sure that we have the directory we are changing to. FILE (MAKE_DIRECTORY "${dir}") From 1faea9370994b23a83ce5e1ca36247d18fdd2d13 Mon Sep 17 00:00:00 2001 From: Sven-Bodo Scholz Date: Wed, 3 Dec 2025 10:07:38 +0100 Subject: [PATCH 3/3] fixed issues spotted by Jordy --- src/PPM.sac | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/PPM.sac b/src/PPM.sac index 258e6c9..1e0ecd6 100644 --- a/src/PPM.sac +++ b/src/PPM.sac @@ -83,7 +83,7 @@ Color8[h,w] readPPMf (TF &fp, string name) \ if (num_read != 2) \ RuntimeError::error(0, \ "Failed to read width and height of the image");\ - data = genarray ([w,h,3], 0); \ + data = genarray ([h,w,3], 0); \ \ /* \ * Read out the maximum value \ @@ -156,9 +156,9 @@ void writePPMf (TF &fp, Color8[h,w] img, bool binary) \ \ for(i = 0; i < h; i++) { \ for (j = 0; j < w; j++) { \ - fprintf(fp, "%d %d %d", toi (img[i,j])[0], \ - toi (img[i,j])[1], \ - toi (img[i,j])[2]); \ + fprintf(fp, "%d %d %d", red (img[i,j])[0], \ + green (img[i,j])[1], \ + blue (img[i,j])[2]); \ \ if (j != w-1) { \ fprintf(fp, " "); \ @@ -179,9 +179,9 @@ void writePPMf (TF &fp, Color8[h,w] img, bool binary) \ \ for(i = 0; i < h; i++) { \ for (j = 0; j < w; j++) { \ - fprintf(fp, "%c%c%c", tochar (toi (img[i,j])[0]), \ - tochar (toi (img[i,j])[1]), \ - tochar (toi (img[i,j])[2])); \ + fprintf(fp, "%c%c%c", tochar (red (img[i,j])[0]), \ + tochar (green (img[i,j])[1]), \ + tochar (blue (img[i,j])[2])); \ \ } \ } \