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, 10 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.6 static const char RCSid[] = "$Id: rsplit.c,v 1.5 2019/07/16 15:59:49 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 <stdlib.h>
11     #include <ctype.h>
12    
13 greg 1.6 #include "rtio.h"
14 greg 1.1 #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 greg 1.5 if (!curterm) curterm = '\n';
100 greg 1.1 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 greg 1.4 if (putbinary(buf, bytsiz[i], 1, output[i]) != 1)
299     break;
300 greg 1.1 } else if (bytsiz[i] < 0) { /* N-field output */
301     int n = -bytsiz[i];
302     while (n--) {
303     if (!scanOK(termc[i]))
304     break;
305 greg 1.4 if (fputs(buf, output[i]) == EOF)
306     break;
307 greg 1.1 }
308     if (n >= 0) /* fell short? */
309     break;
310 greg 1.4 if (termc[i] != '\n') /* add EOL if none */
311     fputc('\n', output[i]);
312 greg 1.1 } else { /* 1-field output */
313     if (!scanOK(termc[i]))
314     break;
315 greg 1.4 if (fputs(buf, output[i]) == EOF)
316     break;
317     if (termc[i] != '\n') /* add EOL if none */
318     fputc('\n', output[i]);
319 greg 1.1 }
320     }
321     if (i < nfiles)
322     break;
323     } while (--outcnt);
324 greg 1.2 /* check ending */
325 greg 1.3 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 greg 1.4 if (outcnt > 0) {
331     fputs(argv[0], stderr);
332     fputs(": warning: premature EOD\n", stderr);
333     }
334 greg 1.1 return(0);
335     }