ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/rsplit.c
(Generate patch)

Comparing ray/src/cal/rsplit.c (file contents):
Revision 1.1 by greg, Fri Jul 5 00:20:57 2019 UTC vs.
Revision 1.14 by greg, Sun Apr 5 02:25:22 2020 UTC

# Line 7 | Line 7 | static const char      RCSid[] = "$Id$";
7   *      7/4/19          Greg Ward
8   */
9  
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdio.h>
10   #include <ctype.h>
11  
12 + #include "rtio.h"
13   #include "platform.h"
14 + #include "paths.h"
15   #include "resolu.h"
17 #include "rtio.h"
16  
17   #define DOHEADER        1
18   #define DORESOLU        2
19  
20   #define MAXFILE         512             /* maximum number of files */
21  
22 < FILE            *output[MAXFILE];
25 < int             bytsiz[MAXFILE];
26 < short           hdrflags[MAXFILE];
27 < const char      *format[MAXFILE];
28 < int             termc[MAXFILE];
29 < int             nfiles = 0;
22 > static int              swapped = 0;    /* input is byte-swapped */
23  
24 < int             outheader = 0;          /* output header to each stream? */
24 > static FILE             *output[MAXFILE];
25 > static int              ncomp[MAXFILE];
26 > static int              bytsiz[MAXFILE];
27 > static int              hdrflags[MAXFILE];
28 > static const char       *format[MAXFILE];
29 > static int              termc[MAXFILE];
30 > static int              nfiles = 0;
31  
32 < RESOLU          ourres = {PIXSTANDARD, 0, 0};
32 > static RESOLU   ourres = {PIXSTANDARD, 0, 0};
33  
34 < char            buf[16384];
34 > static char     buf[16384];             /* input buffer used in scanOK() */
35  
36  
37   /* process header line */
# Line 40 | Line 39 | static int
39   headline(char *s, void *p)
40   {
41          extern const char       FMTSTR[];
42 <        int                     i = nfiles;
42 >        int                     i;
43  
44          if (strstr(s, FMTSTR) == s)
45                  return(0);              /* don't copy format */
# Line 50 | Line 49 | headline(char *s, void *p)
49                  return(0);
50          if (!strncmp(s, "NCOMP=", 6))
51                  return(0);
52 +        if ((i = isbigendian(s)) >= 0) {
53 +                swapped = (nativebigendian() != i);
54 +                return(0);
55 +        }
56 +        i = nfiles;
57          while (i--)                     /* else copy line to output streams */
58                  if (hdrflags[i] & DOHEADER)
59                          fputs(s, output[i]);
# Line 61 | Line 65 | headline(char *s, void *p)
65   static int
66   scanOK(int termc)
67   {
68 +        int     skip_white = (termc == ' ');
69          char    *cp = buf;
70          int     c;
71  
72          while ((c = getchar()) != EOF) {
73 +                if (skip_white && isspace(c))
74 +                        continue;
75 +                skip_white = 0;
76 +                if (c == '\n' && isspace(termc))
77 +                        c = termc;      /* forgiving assumption */
78                  *cp++ = c;
79                  if (cp-buf >= sizeof(buf))
80                          break;
81 <                if (c == termc) {
81 >                if ((termc == ' ') ? isspace(c) : (c == termc)) {
82                          *cp = '\0';
83                          return(cp-buf);
84                  }
# Line 80 | Line 90 | scanOK(int termc)
90   int
91   main(int argc, char *argv[])
92   {
93 <        int             inpheader = 0;
94 <        int             inpres = 0;
85 <        int             outres = 0;
93 >        int             inpflags = 0;
94 >        int             needres = 0;
95          int             force = 0;
96          int             append = 0;
97          long            outcnt = 0;
98          int             bininp = 0;
99 +        int             nstdoutcomp = 0;
100          int             curterm = '\n';
101 +        int             curncomp = 1;
102          int             curbytes = 0;
103          int             curflags = 0;
104          const char      *curfmt = "ascii";
# Line 98 | Line 109 | main(int argc, char *argv[])
109                          switch (argv[i][1]) {
110                          case 't':
111                                  curterm = argv[i][2];
112 +                                if (!curterm) curterm = '\n';
113                                  break;
114                          case 'i':
115                                  switch (argv[i][2]) {
116                                  case 'h':
117 <                                        inpheader = !inpheader;
117 >                                        inpflags ^= DOHEADER;
118                                          break;
119                                  case 'H':
120 <                                        inpres = !inpres;
120 >                                        inpflags ^= DORESOLU;
121                                          break;
122                                  default:
123                                          goto badopt;
124                                  }
125                                  break;
126                          case 'f':
127 <                                ++force;
116 <                                append = 0;
127 >                                force = !force;
128                                  break;
129                          case 'a':
130 <                                if (outheader | outres) {
120 <                                        fputs(argv[0], stderr);
121 <                                        fputs(": -a option incompatible with -oh and -oH\n",
122 <                                                        stderr);
123 <                                        return(1);
124 <                                }
125 <                                append = 1;
130 >                                append = !append;
131                                  break;
132                          case 'x':
133                                  ourres.xr = atoi(argv[++i]);
129                                outres = 1;
134                                  break;
135                          case 'y':
136                                  ourres.yr = atoi(argv[++i]);
133                                outres = 1;
137                                  break;
138                          case 'o':
139                                  switch (argv[i][2]) {
# Line 165 | Line 168 | main(int argc, char *argv[])
168                                          break;
169                                  case 'a':
170                                          curfmt = "ascii";
171 <                                        curbytes = argv[i][3] ? -1 : 0;
171 >                                        curbytes = 0;
172                                          break;
173                                  default:
174                                          goto badopt;
175                                  }
176 <                                if (isdigit(argv[i][3]))
177 <                                        curbytes *= atoi(argv[i]+3);
178 <                                curbytes += (curbytes == -1);
176 <                                if (curbytes > (int)sizeof(buf)) {
176 >                                curncomp = isdigit(argv[i][3]) ?
177 >                                                        atoi(argv[i]+3) : 1 ;
178 >                                if (curbytes*curncomp > (int)sizeof(buf)) {
179                                          fputs(argv[0], stderr);
180                                          fputs(": output size too big\n", stderr);
181                                          return(1);
182                                  }
183 <                                if (curbytes > 0) {
182 <                                        curterm = '\0';
183 <                                        ++bininp;
184 <                                }
183 >                                bininp += (curbytes > 0);
184                                  break;
185 <                        case '\0':
186 <                                outres |= (curflags & DORESOLU);
187 <                                termc[nfiles] = curterm;
188 <                                hdrflags[nfiles] = curflags;
185 >                        case '\0':                      /* stdout */
186 >                                if (!nstdoutcomp) {     /* first use? */
187 >                                        needres |= (curflags & DORESOLU);
188 >                                        hdrflags[nfiles] = curflags;
189 >                                }
190                                  output[nfiles] = stdout;
191                                  if (curbytes > 0)
192                                          SET_FILE_BINARY(output[nfiles]);
193 +                                termc[nfiles] = curterm;
194                                  format[nfiles] = curfmt;
195 +                                nstdoutcomp +=
196 +                                        ncomp[nfiles] = curncomp;
197                                  bytsiz[nfiles++] = curbytes;
198                                  break;
199                          badopt:;
# Line 199 | Line 202 | main(int argc, char *argv[])
202                                  fputs(": bad option\n", stderr);
203                                  return(1);
204                          }
205 <                } else if (argv[i][0] == '!') {
206 <                        outres |= (curflags & DORESOLU);
205 >                } else if (argv[i][0] == '.' && !argv[i][1]) {
206 >                        output[nfiles] = NULL;          /* discard data */
207                          termc[nfiles] = curterm;
208 +                        format[nfiles] = curfmt;
209 +                        ncomp[nfiles] = curncomp;
210 +                        bytsiz[nfiles++] = curbytes;
211 +                } else if (argv[i][0] == '!') {
212 +                        needres |= (curflags & DORESOLU);
213                          hdrflags[nfiles] = curflags;
214 +                        termc[nfiles] = curterm;
215                          if ((output[nfiles] = popen(argv[i]+1, "w")) == NULL) {
216                                  fputs(argv[i], stderr);
217                                  fputs(": cannot start command\n", stderr);
# Line 211 | Line 220 | main(int argc, char *argv[])
220                          if (curbytes > 0)
221                                  SET_FILE_BINARY(output[nfiles]);
222                          format[nfiles] = curfmt;
223 +                        ncomp[nfiles] = curncomp;
224                          bytsiz[nfiles++] = curbytes;
225                  } else {
226 <                        outres |= (curflags & DORESOLU);
227 <                        termc[nfiles] = curterm;
226 >                        if (append & (curflags != 0)) {
227 >                                fputs(argv[0], stderr);
228 >                                fputs(": -a option incompatible with -oh and -oH\n",
229 >                                                stderr);
230 >                                return(1);
231 >                        }
232 >                        needres |= (curflags & DORESOLU);
233                          hdrflags[nfiles] = curflags;
234 +                        termc[nfiles] = curterm;
235                          if (!append & !force && access(argv[i], F_OK) == 0) {
236                                  fputs(argv[i], stderr);
237                                  fputs(": file exists -- use -f to overwrite\n",
# Line 231 | Line 247 | main(int argc, char *argv[])
247                          if (curbytes > 0)
248                                  SET_FILE_BINARY(output[nfiles]);
249                          format[nfiles] = curfmt;
250 +                        ncomp[nfiles] = curncomp;
251                          bytsiz[nfiles++] = curbytes;
252                  }
253                  if (nfiles >= MAXFILE) {
# Line 249 | Line 266 | main(int argc, char *argv[])
266   #ifdef getc_unlocked                            /* avoid lock/unlock overhead */
267          flockfile(stdin);
268          for (i = nfiles; i--; )
269 <                flockfile(output[i]);
269 >                if (output[i] != NULL)
270 >                        ftrylockfile(output[i]);
271   #endif
272                                                  /* load/copy header */
273 <        if (inpheader && getheader(stdin, headline, NULL) < 0) {
273 >        if (inpflags & DOHEADER && getheader(stdin, headline, NULL) < 0) {
274                  fputs(argv[0], stderr);
275 <                fputs(": cannot get header from standard input\n",
275 >                fputs(": cannot read header from standard input\n",
276                                  stderr);
277                  return(1);
278          }
279                                                  /* handle resolution string */
280 <        if (inpres && !fgetsresolu(&ourres, stdin)) {
280 >        if (inpflags & DORESOLU && !fgetsresolu(&ourres, stdin)) {
281                  fputs(argv[0], stderr);
282 <                fputs(": cannot get resolution string from standard input\n",
265 <                                stderr);
282 >                fputs(": bad resolution string on standard input\n", stderr);
283                  return(1);
284          }
285 <        if (outres && (ourres.xr <= 0) | (ourres.yr <= 0)) {
285 >        if (needres && (ourres.xr <= 0) | (ourres.yr <= 0)) {
286                  fputs(argv[0], stderr);
287                  fputs(": -oH option requires -iH or -x and -y options\n", stderr);
288                  return(1);
# Line 281 | Line 298 | main(int argc, char *argv[])
298          }
299          for (i = 0; i < nfiles; i++) {          /* complete headers */
300                  if (hdrflags[i] & DOHEADER) {
301 <                        if (!inpheader)
301 >                        if (!(inpflags & DOHEADER))
302                                  newheader("RADIANCE", output[i]);
303                          printargs(argc, argv, output[i]);
304 <                        if (format[i] != NULL)
304 >                        fprintf(output[i], "NCOMP=%d\n", output[i]==stdout ?
305 >                                                nstdoutcomp : ncomp[i]);
306 >                        if (format[i] != NULL) {
307 >                                extern const char  BIGEND[];
308 >                                if (format[i][0] != 'a') {
309 >                                        fputs(BIGEND, output[i]);
310 >                                        fputs(nativebigendian() ^ swapped ?
311 >                                                "1\n" : "0\n", output[i]);
312 >                                }
313                                  fputformat(format[i], output[i]);
314 +                        }
315                          fputc('\n', output[i]);
316                  }
317                  if (hdrflags[i] & DORESOLU)
# Line 294 | Line 320 | main(int argc, char *argv[])
320          do {                                    /* main loop */
321                  for (i = 0; i < nfiles; i++) {
322                          if (bytsiz[i] > 0) {            /* binary output */
323 <                                if (getbinary(buf, bytsiz[i], 1, stdin) < 1)
323 >                                if (getbinary(buf, bytsiz[i], ncomp[i],
324 >                                                        stdin) < ncomp[i])
325                                          break;
326 <                                putbinary(buf, bytsiz[i], 1, output[i]);
327 <                        } else if (bytsiz[i] < 0) {     /* N-field output */
328 <                                int     n = -bytsiz[i];
326 >                                if (output[i] != NULL &&
327 >                                            putbinary(buf, bytsiz[i], ncomp[i],
328 >                                                        output[i]) < ncomp[i])
329 >                                        break;
330 >                        } else if (ncomp[i] > 1) {      /* N-field output */
331 >                                int     n = ncomp[i];
332                                  while (n--) {
333                                          if (!scanOK(termc[i]))
334                                                  break;
335 <                                        fputs(buf, output[i]);
335 >                                        if (output[i] != NULL &&
336 >                                                    fputs(buf, output[i]) == EOF)
337 >                                                break;
338                                  }
339                                  if (n >= 0)             /* fell short? */
340                                          break;
341 +                                if ((output[i] != NULL) &  /* add EOL if none */
342 +                                                (termc[i] != '\n'))
343 +                                        fputc('\n', output[i]);
344                          } else {                        /* 1-field output */
345                                  if (!scanOK(termc[i]))
346                                          break;
347 <                                fputs(buf, output[i]);
347 >                                if (output[i] != NULL) {
348 >                                        if (fputs(buf, output[i]) == EOF)
349 >                                                break;
350 >                                        if (termc[i] != '\n')   /* add EOL? */
351 >                                                fputc('\n', output[i]);
352 >                                }
353                          }
354 +                                                        /* skip input EOL? */
355 +                        if (!bininp && termc[nfiles-1] != '\n') {
356 +                                int     c = getchar();
357 +                                if ((c != '\n') & (c != EOF))
358 +                                        ungetc(c, stdin);
359 +                        }
360                  }
361                  if (i < nfiles)
362                          break;
363          } while (--outcnt);
364 +                                                        /* check ending */
365 +        if (fflush(NULL) == EOF) {
366 +                fputs(argv[0], stderr);
367 +                fputs(": write error on one or more outputs\n", stderr);
368 +                return(1);
369 +        }
370 +        if (outcnt > 0) {
371 +                fputs(argv[0], stderr);
372 +                fputs(": warning: premature EOD\n", stderr);
373 +        }
374          return(0);
375   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines