11module PPM;
22
3- use Color8: { Color8, dim, shape };
4- use File: { File, fopen, fclose };
5- use ScalarArith: { == };
6- use String: { string };
7- use TermFile: { TermFile, stdin, stdout };
8-
9- export { readPPM, printPPM };
10-
11- external Color8[.,.] readStream(TermFile &stream);
12- #pragma effect Terminal::TheTerminal
13- #pragma linkobj "src/PPM/ppm2array.o"
14- #pragma linkname "SAC_PPM_ppm2array"
15- #pragma refcounting [0]
16- #pragma linksign [1,2]
17-
18- external Color8[.,.] readStream(File &stream);
19- #pragma effect FileSystem::TheFileSystem
20- #pragma linkobj "src/PPM/ppm2array.o"
21- #pragma linkname "SAC_PPM_ppm2array"
22- #pragma refcounting [0]
23- #pragma linksign [1,2]
24-
25- external void writeStream(TermFile &stream, Color8[.,.] image,
26- int[2] shp, bool binary);
27- #pragma effect Terminal::TheTerminal
28- #pragma linkobj "src/PPM/array2ppm.o"
29- #pragma linkname "SAC_PPM_array2ppm"
30-
31- external void writeStream(File &stream, Color8[.,.] image,
32- int[2] shp, bool binary);
33- #pragma effect FileSystem::TheFileSystem
34- #pragma linkobj "src/PPM/array2ppm.o"
35- #pragma linkname "SAC_PPM_array2ppm"
3+ use Structures: all;
4+ import File: all;
5+ import TermFile: all;
6+
7+ export { readPPM, writePPM };
8+
9+ /*******************************************************************************
10+ *
11+ * readPPM
12+ *
13+ ******************************************************************************/
3614
3715inline Color8[.,.] readPPM()
3816{
39- return readStream (stdin);
17+ return readPPMf (stdin, "stdin" );
4018}
4119
4220inline Color8[.,.] readPPM(string name)
@@ -48,25 +26,170 @@ inline Color8[.,.] readPPM(string name)
4826 name);
4927 }
5028
51- ret = readStream (fp);
29+ ret = readPPMf (fp, name );
5230 fclose(fp);
5331 return(ret);
5432}
5533
56- inline void printPPM(Color8[2:shp] img)
34+ #define READ_LINE_F(TF) \
35+ string fgetLine (TF &fp, string name) \
36+ { \
37+ err, line = fgetl (fp); \
38+ if (SysErr::fail(err)) { \
39+ RuntimeError::error((int)err, \
40+ "Error when trying to read a line from %s", \
41+ name); \
42+ } \
43+ return line; \
44+ }
45+
46+ READ_LINE_F(File)
47+
48+ READ_LINE_F(TermFile)
49+
50+
51+
52+
53+ #define READ_PPM_F(TF) \
54+ Color8[h,w] readPPMf (TF &fp, string name) \
55+ { \
56+ int c, h, w, max; \
57+ /* \
58+ * Check for a valid header \
59+ */ \
60+ line = fgetLine (fp, name); \
61+ if ( (strsel (line, 0) != 'P') \
62+ || ((strsel (line, 1) != '3') \
63+ && (strsel (line, 1) != '6')) ) { \
64+ RuntimeError::error(0, \
65+ "Neither header P3 nor P6 found. Not a .ppm file"); \
66+ } \
67+ binary = (strsel (line, 1) == '6'); \
68+ \
69+ /* \
70+ * Check for comment (and ignore it) \
71+ */ \
72+ comment = true; \
73+ while (comment) { \
74+ line = fgetLine (fp, name); \
75+ comment = (strsel (line, 0) == '#'); \
76+ } \
77+ \
78+ /* \
79+ * Get the dimensions of the image \
80+ * and allocate an array of sufficient size \
81+ */ \
82+ num_read, w, h = sscanf (line, "%d %d"); \
83+ if (num_read != 2) \
84+ RuntimeError::error(0, \
85+ "Failed to read width and height of the image");\
86+ data = genarray ([h,w,3], 0); \
87+ \
88+ /* \
89+ * Read out the maximum value \
90+ */ \
91+ line = fgetLine (fp, name); \
92+ num_read, max = sscanf (line, "%d"); \
93+ if (num_read != 1) \
94+ RuntimeError::error(0, \
95+ "Failed to read max value of the image"); \
96+ \
97+ /* \
98+ * Readout the image \
99+ */ \
100+ for (i = 0; i < h; i++) { \
101+ for (j = 0; j < w; j++) { \
102+ for (k = 0; k < 3; k++) { \
103+ if (binary) \
104+ c = toi (fgetc (fp)); \
105+ else \
106+ num, c = fscanf (fp, "%d"); \
107+ data[i,j,k] = c * (255/max); \
108+ } \
109+ } \
110+ } \
111+ cols = {[i,j] -> newColor (data[i,j]) | [i,j] < [h,w]}; \
112+ return cols; \
113+ }
114+
115+ READ_PPM_F( File)
116+
117+ READ_PPM_F( TermFile)
118+
119+ /*******************************************************************************
120+ *
121+ * writePPM
122+ *
123+ ******************************************************************************/
124+
125+ void writePPM (Color8[2:shp] img)
57126{
58- writeStream (stdout, img, shp , false);
127+ writePPMf (stdout, img, false);
59128}
60129
61- inline void printPPM(Color8[2:shp] img, string name, bool binary)
130+
131+ void writePPM (Color8[2:shp] img, string name, bool binary)
62132{
63133 err, fp = fopen(name, "w+");
64- if (SysErr::fail(err)) {
134+ if (SysErr::fail (err)) {
65135 RuntimeError::error((int)err,
66136 "Error occured when trying to open file %s for writing",
67137 name);
68138 }
69139
70- writeStream(fp, img, shp, binary);
71- fclose(fp);
140+ writePPMf (fp, img, binary);
141+ fclose (fp);
142+ }
143+
144+
145+ #define WRITE_PPM_F( TF) \
146+ void writePPMf (TF &fp, Color8[h,w] img, bool binary) \
147+ { \
148+ if ( binary == false) { \
149+ /* \
150+ * ASCII output \
151+ */ \
152+ fprintf(fp, "P3\n"); \
153+ \
154+ fprintf(fp, "%d %d\n", w, h); \
155+ fprintf(fp, "255\n"); \
156+ \
157+ for(i = 0; i < h; i++) { \
158+ for (j = 0; j < w; j++) { \
159+ fprintf(fp, "%d %d %d", red (img[i,j])[0], \
160+ green (img[i,j])[1], \
161+ blue (img[i,j])[2]); \
162+ \
163+ if (j != w-1) { \
164+ fprintf(fp, " "); \
165+ } \
166+ } \
167+ fprintf(fp, "\n"); \
168+ } \
169+ \
170+ } \
171+ else { \
172+ /* \
173+ * Binary output \
174+ */ \
175+ fprintf(fp, "P6\n"); \
176+ \
177+ fprintf(fp, "%d %d\n", w, h); \
178+ fprintf(fp, "255\n"); \
179+ \
180+ for(i = 0; i < h; i++) { \
181+ for (j = 0; j < w; j++) { \
182+ fprintf(fp, "%c%c%c", tochar (red (img[i,j])[0]), \
183+ tochar (green (img[i,j])[1]), \
184+ tochar (blue (img[i,j])[2])); \
185+ \
186+ } \
187+ } \
188+ } \
72189}
190+
191+ WRITE_PPM_F(File)
192+
193+ WRITE_PPM_F(TermFile)
194+
195+
0 commit comments