ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/rsplit.c
Revision: 1.6
Committed: Fri Jul 19 17:37:55 2019 UTC (4 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +2 -4 lines
Log Message:
Moved declarations and definitions for header.c from resolu.h to rtio.h

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rsplit.c,v 1.5 2019/07/16 15:59:49 greg Exp $";
3 #endif
4 /*
5 * rsplit.c - split input into multiple output streams
6 *
7 * 7/4/19 Greg Ward
8 */
9
10 #include <stdlib.h>
11 #include <ctype.h>
12
13 #include "rtio.h"
14 #include "platform.h"
15 #include "resolu.h"
16
17 #define DOHEADER 1
18 #define DORESOLU 2
19
20 #define MAXFILE 512 /* maximum number of files */
21
22 FILE *output[MAXFILE];
23 int bytsiz[MAXFILE];
24 short hdrflags[MAXFILE];
25 const char *format[MAXFILE];
26 int termc[MAXFILE];
27 int nfiles = 0;
28
29 int outheader = 0; /* output header to each stream? */
30
31 RESOLU ourres = {PIXSTANDARD, 0, 0};
32
33 char buf[16384];
34
35
36 /* process header line */
37 static int
38 headline(char *s, void *p)
39 {
40 extern const char FMTSTR[];
41 int i = nfiles;
42
43 if (strstr(s, FMTSTR) == s)
44 return(0); /* don't copy format */
45 if (!strncmp(s, "NROWS=", 6))
46 return(0);
47 if (!strncmp(s, "NCOLS=", 6))
48 return(0);
49 if (!strncmp(s, "NCOMP=", 6))
50 return(0);
51 while (i--) /* else copy line to output streams */
52 if (hdrflags[i] & DOHEADER)
53 fputs(s, output[i]);
54 return(1);
55 }
56
57
58 /* scan field into buffer up to and including terminating byte */
59 static int
60 scanOK(int termc)
61 {
62 char *cp = buf;
63 int c;
64
65 while ((c = getchar()) != EOF) {
66 *cp++ = c;
67 if (cp-buf >= sizeof(buf))
68 break;
69 if (c == termc) {
70 *cp = '\0';
71 return(cp-buf);
72 }
73 }
74 return(0);
75 }
76
77
78 int
79 main(int argc, char *argv[])
80 {
81 int inpheader = 0;
82 int inpres = 0;
83 int outres = 0;
84 int force = 0;
85 int append = 0;
86 long outcnt = 0;
87 int bininp = 0;
88 int curterm = '\n';
89 int curbytes = 0;
90 int curflags = 0;
91 const char *curfmt = "ascii";
92 int i;
93
94 for (i = 1; i < argc; i++) {
95 if (argv[i][0] == '-') {
96 switch (argv[i][1]) {
97 case 't':
98 curterm = argv[i][2];
99 if (!curterm) curterm = '\n';
100 break;
101 case 'i':
102 switch (argv[i][2]) {
103 case 'h':
104 inpheader = !inpheader;
105 break;
106 case 'H':
107 inpres = !inpres;
108 break;
109 default:
110 goto badopt;
111 }
112 break;
113 case 'f':
114 ++force;
115 append = 0;
116 break;
117 case 'a':
118 if (outheader | outres) {
119 fputs(argv[0], stderr);
120 fputs(": -a option incompatible with -oh and -oH\n",
121 stderr);
122 return(1);
123 }
124 append = 1;
125 break;
126 case 'x':
127 ourres.xr = atoi(argv[++i]);
128 outres = 1;
129 break;
130 case 'y':
131 ourres.yr = atoi(argv[++i]);
132 outres = 1;
133 break;
134 case 'o':
135 switch (argv[i][2]) {
136 case 'n':
137 outcnt = atol(argv[++i]);
138 continue;
139 case 'h':
140 curflags ^= DOHEADER;
141 continue;
142 case 'H':
143 curflags ^= DORESOLU;
144 continue;
145 case 'f':
146 curfmt = "float";
147 curbytes = sizeof(float);
148 break;
149 case 'd':
150 curfmt = "double";
151 curbytes = sizeof(double);
152 break;
153 case 'i':
154 curfmt = "int";
155 curbytes = sizeof(int);
156 break;
157 case 'w':
158 curfmt = "16-bit";
159 curbytes = 2;
160 break;
161 case 'b':
162 curfmt = "byte";
163 curbytes = 1;
164 break;
165 case 'a':
166 curfmt = "ascii";
167 curbytes = argv[i][3] ? -1 : 0;
168 break;
169 default:
170 goto badopt;
171 }
172 if (isdigit(argv[i][3]))
173 curbytes *= atoi(argv[i]+3);
174 curbytes += (curbytes == -1);
175 if (curbytes > (int)sizeof(buf)) {
176 fputs(argv[0], stderr);
177 fputs(": output size too big\n", stderr);
178 return(1);
179 }
180 if (curbytes > 0) {
181 curterm = '\0';
182 ++bininp;
183 }
184 break;
185 case '\0':
186 outres |= (curflags & DORESOLU);
187 termc[nfiles] = curterm;
188 hdrflags[nfiles] = curflags;
189 output[nfiles] = stdout;
190 if (curbytes > 0)
191 SET_FILE_BINARY(output[nfiles]);
192 format[nfiles] = curfmt;
193 bytsiz[nfiles++] = curbytes;
194 break;
195 badopt:;
196 default:
197 fputs(argv[0], stderr);
198 fputs(": bad option\n", stderr);
199 return(1);
200 }
201 } else if (argv[i][0] == '!') {
202 outres |= (curflags & DORESOLU);
203 termc[nfiles] = curterm;
204 hdrflags[nfiles] = curflags;
205 if ((output[nfiles] = popen(argv[i]+1, "w")) == NULL) {
206 fputs(argv[i], stderr);
207 fputs(": cannot start command\n", stderr);
208 return(1);
209 }
210 if (curbytes > 0)
211 SET_FILE_BINARY(output[nfiles]);
212 format[nfiles] = curfmt;
213 bytsiz[nfiles++] = curbytes;
214 } else {
215 outres |= (curflags & DORESOLU);
216 termc[nfiles] = curterm;
217 hdrflags[nfiles] = curflags;
218 if (!append & !force && access(argv[i], F_OK) == 0) {
219 fputs(argv[i], stderr);
220 fputs(": file exists -- use -f to overwrite\n",
221 stderr);
222 return(1);
223 }
224 output[nfiles] = fopen(argv[i], append ? "a" : "w");
225 if (output[nfiles] == NULL) {
226 fputs(argv[i], stderr);
227 fputs(": cannot open for output\n", stderr);
228 return(1);
229 }
230 if (curbytes > 0)
231 SET_FILE_BINARY(output[nfiles]);
232 format[nfiles] = curfmt;
233 bytsiz[nfiles++] = curbytes;
234 }
235 if (nfiles >= MAXFILE) {
236 fputs(argv[0], stderr);
237 fputs(": too many output streams\n", stderr);
238 return(1);
239 }
240 }
241 if (!nfiles) {
242 fputs(argv[0], stderr);
243 fputs(": no output streams\n", stderr);
244 return(1);
245 }
246 if (bininp) /* binary input? */
247 SET_FILE_BINARY(stdin);
248 #ifdef getc_unlocked /* avoid lock/unlock overhead */
249 flockfile(stdin);
250 for (i = nfiles; i--; )
251 flockfile(output[i]);
252 #endif
253 /* load/copy header */
254 if (inpheader && getheader(stdin, headline, NULL) < 0) {
255 fputs(argv[0], stderr);
256 fputs(": cannot get header from standard input\n",
257 stderr);
258 return(1);
259 }
260 /* handle resolution string */
261 if (inpres && !fgetsresolu(&ourres, stdin)) {
262 fputs(argv[0], stderr);
263 fputs(": cannot get resolution string from standard input\n",
264 stderr);
265 return(1);
266 }
267 if (outres && (ourres.xr <= 0) | (ourres.yr <= 0)) {
268 fputs(argv[0], stderr);
269 fputs(": -oH option requires -iH or -x and -y options\n", stderr);
270 return(1);
271 }
272 if ((ourres.xr > 0) & (ourres.yr > 0)) {
273 if (outcnt <= 0) {
274 outcnt = ourres.xr * ourres.yr;
275 } else if (outcnt != ourres.xr*ourres.yr) {
276 fputs(argv[0], stderr);
277 fputs(": warning: -on option does not agree with resolution\n",
278 stderr);
279 }
280 }
281 for (i = 0; i < nfiles; i++) { /* complete headers */
282 if (hdrflags[i] & DOHEADER) {
283 if (!inpheader)
284 newheader("RADIANCE", output[i]);
285 printargs(argc, argv, output[i]);
286 if (format[i] != NULL)
287 fputformat(format[i], output[i]);
288 fputc('\n', output[i]);
289 }
290 if (hdrflags[i] & DORESOLU)
291 fputsresolu(&ourres, output[i]);
292 }
293 do { /* main loop */
294 for (i = 0; i < nfiles; i++) {
295 if (bytsiz[i] > 0) { /* binary output */
296 if (getbinary(buf, bytsiz[i], 1, stdin) < 1)
297 break;
298 if (putbinary(buf, bytsiz[i], 1, output[i]) != 1)
299 break;
300 } else if (bytsiz[i] < 0) { /* N-field output */
301 int n = -bytsiz[i];
302 while (n--) {
303 if (!scanOK(termc[i]))
304 break;
305 if (fputs(buf, output[i]) == EOF)
306 break;
307 }
308 if (n >= 0) /* fell short? */
309 break;
310 if (termc[i] != '\n') /* add EOL if none */
311 fputc('\n', output[i]);
312 } else { /* 1-field output */
313 if (!scanOK(termc[i]))
314 break;
315 if (fputs(buf, output[i]) == EOF)
316 break;
317 if (termc[i] != '\n') /* add EOL if none */
318 fputc('\n', output[i]);
319 }
320 }
321 if (i < nfiles)
322 break;
323 } while (--outcnt);
324 /* check ending */
325 if (fflush(NULL) == EOF) {
326 fputs(argv[0], stderr);
327 fputs(": write error on one or more outputs\n", stderr);
328 return(1);
329 }
330 if (outcnt > 0) {
331 fputs(argv[0], stderr);
332 fputs(": warning: premature EOD\n", stderr);
333 }
334 return(0);
335 }