ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/rsplit.c
Revision: 1.10
Committed: Wed Aug 14 21:00:14 2019 UTC (4 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +18 -3 lines
Log Message:
Added byte order to gendaymtx, rsplit, dctimestep, rcode_depth, and rcode_normal

File Contents

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