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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.10 static const char RCSid[] = "$Id: rsplit.c,v 1.9 2019/08/13 16:31:35 greg Exp $";
3 greg 1.1 #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 greg 1.6 #include "rtio.h"
13 greg 1.1 #include "platform.h"
14 greg 1.9 #include "paths.h"
15 greg 1.1 #include "resolu.h"
16    
17     #define DOHEADER 1
18     #define DORESOLU 2
19    
20     #define MAXFILE 512 /* maximum number of files */
21    
22 greg 1.10 static int swapped = 0; /* input is byte-swapped */
23    
24 greg 1.7 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 greg 1.1
31 greg 1.7 static RESOLU ourres = {PIXSTANDARD, 0, 0};
32 greg 1.1
33 greg 1.7 static char buf[16384]; /* input buffer used in scanOK() */
34 greg 1.1
35    
36     /* process header line */
37     static int
38     headline(char *s, void *p)
39     {
40     extern const char FMTSTR[];
41 greg 1.10 int i;
42 greg 1.1
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 greg 1.10 if ((i = isbigendian(s)) >= 0) {
52     swapped = (nativebigendian() != i);
53     return(0);
54     }
55     i = nfiles;
56 greg 1.1 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 greg 1.8 int inpflags = 0;
87     int needres = 0;
88 greg 1.1 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 greg 1.5 if (!curterm) curterm = '\n';
104 greg 1.1 break;
105     case 'i':
106     switch (argv[i][2]) {
107     case 'h':
108 greg 1.8 inpflags ^= DOHEADER;
109 greg 1.1 break;
110     case 'H':
111 greg 1.8 inpflags ^= DORESOLU;
112 greg 1.1 break;
113     default:
114     goto badopt;
115     }
116     break;
117     case 'f':
118 greg 1.8 force = !force;
119 greg 1.1 break;
120     case 'a':
121 greg 1.8 append = !append;
122 greg 1.1 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 greg 1.7 curbytes = -1;
163 greg 1.1 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 greg 1.7 bininp += (curbytes > 0);
176 greg 1.1 break;
177     case '\0':
178 greg 1.8 needres |= (curflags & DORESOLU);
179 greg 1.1 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 greg 1.8 needres |= (curflags & DORESOLU);
195 greg 1.1 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 greg 1.8 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 greg 1.1 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 greg 1.8 if (inpflags & DOHEADER && getheader(stdin, headline, NULL) < 0) {
253 greg 1.1 fputs(argv[0], stderr);
254     fputs(": cannot get header from standard input\n",
255     stderr);
256     return(1);
257     }
258     /* handle resolution string */
259 greg 1.8 if (inpflags & DORESOLU && !fgetsresolu(&ourres, stdin)) {
260 greg 1.1 fputs(argv[0], stderr);
261     fputs(": cannot get resolution string from standard input\n",
262     stderr);
263     return(1);
264     }
265 greg 1.8 if (needres && (ourres.xr <= 0) | (ourres.yr <= 0)) {
266 greg 1.1 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 greg 1.8 if (!(inpflags & DOHEADER))
282 greg 1.1 newheader("RADIANCE", output[i]);
283     printargs(argc, argv, output[i]);
284 greg 1.10 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 greg 1.1 fputformat(format[i], output[i]);
293 greg 1.10 }
294 greg 1.1 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 greg 1.7 if (putbinary(buf, bytsiz[i], 1, output[i]) < 1)
305 greg 1.4 break;
306 greg 1.1 } else if (bytsiz[i] < 0) { /* N-field output */
307     int n = -bytsiz[i];
308     while (n--) {
309     if (!scanOK(termc[i]))
310     break;
311 greg 1.4 if (fputs(buf, output[i]) == EOF)
312     break;
313 greg 1.1 }
314     if (n >= 0) /* fell short? */
315     break;
316 greg 1.4 if (termc[i] != '\n') /* add EOL if none */
317     fputc('\n', output[i]);
318 greg 1.1 } else { /* 1-field output */
319     if (!scanOK(termc[i]))
320     break;
321 greg 1.4 if (fputs(buf, output[i]) == EOF)
322     break;
323     if (termc[i] != '\n') /* add EOL if none */
324     fputc('\n', output[i]);
325 greg 1.1 }
326 greg 1.7 /* 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 greg 1.1 }
333     if (i < nfiles)
334     break;
335     } while (--outcnt);
336 greg 1.2 /* check ending */
337 greg 1.3 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 greg 1.4 if (outcnt > 0) {
343     fputs(argv[0], stderr);
344     fputs(": warning: premature EOD\n", stderr);
345     }
346 greg 1.1 return(0);
347     }