ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rcode_ident.c
Revision: 2.2
Committed: Fri Jul 19 22:57:12 2019 UTC (4 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +8 -3 lines
Log Message:
Fixed issue with -x and -y option still expecting resolution string

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: rcode_ident.c,v 2.1 2019/07/19 22:25:03 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Create or read identifier index map
6     *
7     */
8    
9     #include <stdlib.h>
10     #include <ctype.h>
11     #include "rtio.h"
12     #include "platform.h"
13     #include "lookup.h"
14     #include "idmap.h"
15    
16     #ifndef MAXIDLEN
17     #define MAXIDLEN 256 /* longest ID length supported */
18     #endif
19    
20     char *progname; /* global argv[0] */
21    
22     static int unbuffered = 0;
23     static int sepc = '\n';
24    
25    
26     /* Report usage error and exit */
27     static void
28     usage_exit(int code)
29     {
30     fputs("Usage: ", stderr);
31     fputs(progname, stderr);
32     fputs(" [-8|-16|-24][-h][-tS][-x xr -y yr] [input.txt [output.idx]]\n",
33     stderr);
34     fputs(" Or: ", stderr);
35     fputs(progname, stderr);
36     fputs(" -r [-i][-u][-h][-H][-tS] input.idx [output.txt]\n", stderr);
37     exit(code);
38     }
39    
40    
41     /* read identifier from input, trimming white space on either end */
42     static int
43     scan_ident(char ident[MAXIDLEN], FILE *fp)
44     {
45     char *cp = ident;
46     int c;
47    
48     while ((c = getc(fp)) != EOF) {
49     if (cp == ident && isspace(c))
50     continue;
51     if (c == sepc) {
52     while (cp > ident && isspace(cp[-1]))
53     cp--;
54     *cp = '\0';
55     return cp - ident; /* return string length */
56     }
57     if (cp - ident >= MAXIDLEN-1) {
58     fputs(progname, stderr);
59     fputs(": identifier too long in scan_ident()\n", stderr);
60     return -1;
61     }
62     *cp++ = c;
63     }
64     return -1;
65     }
66    
67    
68     /* elide format from header lines */
69     static int
70     headline(char *s, void *p)
71     {
72     extern const char FMTSTR[];
73    
74     if (strstr(s, FMTSTR) == s)
75     return 0;
76    
77     fputs(s, stdout);
78     return 1;
79     }
80    
81    
82     /* Create an identifier index from the given input file (stdin if NULL) */
83     int
84     create_index(const char *fname, int hdrflags, int ndxbytes, int xres, int yres)
85     {
86     FILE *fp = stdin;
87     char **idmap;
88     int idmlen;
89     int nextID = 0;
90     LUTAB hashtab = LU_SINIT(free,NULL);
91     RESOLU rs;
92     long n;
93     int ndx;
94     /* open file if not stdin */
95 greg 2.2 if (!fname)
96     fname = "<stdin>";
97     else if (!(fp = fopen(fname, "r"))) {
98 greg 2.1 fputs(fname, stderr);
99     fputs(": cannot open for input\n", stderr);
100     return 0;
101     }
102     #ifdef getc_unlocked /* avoid stupid semaphores */
103     flockfile(fp);
104     #endif
105     /* load/copy header */
106     if (hdrflags & HF_HEADOUT && getheader(fp, headline, NULL) < 0) {
107     fputs(fname, stderr);
108     fputs(": bad header or wrong input format\n", stderr);
109     fclose(fp);
110     return 0;
111     }
112     if (!(hdrflags & HF_HEADOUT))
113     newheader("RADIANCE", stdout);
114     /* finish & allocate ID table */
115     switch (ndxbytes) {
116     case 1:
117     fputformat(IDMAP8FMT, stdout);
118     idmap = (char **)malloc((idmlen=256)*sizeof(char *));
119     break;
120     case 2:
121     fputformat(IDMAP16FMT, stdout);
122     idmap = (char **)malloc((idmlen=4096)*sizeof(char *));
123     break;
124     case 3:
125     fputformat(IDMAP24FMT, stdout);
126     idmap = (char **)malloc((idmlen=1L<<17)*sizeof(char *));
127     break;
128     default:
129     fputs(progname, stderr);
130     fputs(": unsupported bits/pixel\n", stderr);
131     return 0;
132     }
133     if (!idmap || !lu_init(&hashtab, idmlen))
134     goto memerr;
135     fputc('\n', stdout); /* end of info header */
136    
137     rs.rt = PIXSTANDARD; /* get/write map resolution */
138     if (hdrflags & HF_RESOUT) {
139     if (!fgetsresolu(&rs, fp)) {
140     fputs(fname, stderr);
141     fputs(": bad resolution string\n", stderr);
142     return 0;
143     }
144     } else if (((rs.xr = xres) <= 0) | ((rs.yr = yres) <= 0)) {
145     fputs(fname, stderr);
146     fputs(": missing/illegal resolution\n", stderr);
147     return 0;
148     }
149     fputsresolu(&rs, stdout);
150     /* read/assign/write each ID */
151     for (n = (long)rs.xr*rs.yr; n-- > 0; ) {
152     LUENT *lep;
153     char ident[MAXIDLEN];
154     int len = scan_ident(ident, fp);
155     if (len < 0) {
156     if (feof(fp)) {
157     fputs(fname, stderr);
158     fputs(": unexpected EOF\n", stderr);
159     }
160     return 0;
161     }
162     lep = lu_find(&hashtab, ident);
163     if (!lep->key) { /* new entry */
164     if (nextID >= 1<<(ndxbytes<<3)) {
165     fputs(progname, stderr);
166     fputs(
167     ": too many unique identifiers for index size\n",
168     stderr);
169     return 0;
170     }
171     if (nextID >= idmlen) { /* reallocate? */
172     idmlen += idmlen>>2; /* +25% growth */
173     idmap = (char **)realloc(idmap, idmlen);
174     if (!idmap)
175     goto memerr;
176     }
177     lep->key = (char *)malloc(len+1);
178     if (!lep->key)
179     goto memerr;
180     idmap[nextID] = strcpy(lep->key, ident);
181     lep->data = (char *)nextID++;
182     }
183     /* write this id index */
184     putint((int)lep->data, ndxbytes, stdout);
185     }
186     while ((ndx = getc(fp)) != EOF) /* verify we got them all */
187     if (!isspace(ndx)) {
188     fputs(fname, stderr);
189     fputs(": warning - non-white characters past end\n",
190     stderr);
191     break;
192     }
193 greg 2.2 if (fp != stdin) /* done with input */
194     fclose(fp);
195 greg 2.1 for (ndx = 0; ndx < nextID; ndx++) { /* append string table */
196     fputs(idmap[ndx], stdout);
197     putchar('\0'); /* nul-terminated IDs */
198     }
199     free(idmap); /* clean up */
200     lu_done(&hashtab);
201     return 1;
202     memerr:
203     fputs(progname, stderr);
204     fputs(": out of memory!\n", stderr);
205     return 0;
206     }
207    
208    
209     /* Load selected pixels from identifier index file */
210     int
211     decode_select(const char *fname, int hdrflags)
212     {
213     IDMAP *idmp = idmap_ropen(fname, hdrflags);
214     int x, y;
215    
216     if (!idmp)
217     return 0;
218    
219     if (idmp->res.rt != PIXSTANDARD) {
220     fputs(progname, stderr);
221     fputs(": can only handle standard pixel ordering\n", stderr);
222     idmap_close(idmp);
223     return 0;
224     }
225     while (scanf("%d %d", &x, &y) == 2) {
226     const char *id;
227    
228     if ((x < 0) | (y < 0) |
229     (x >= idmp->res.xr) | (y >= idmp->res.yr)) {
230     fputs(progname, stderr);
231     fputs(": warning - pixel index is off map\n", stderr);
232     continue;
233     }
234     y = idmp->res.yr-1 - y;
235    
236     if (!(id = idmap_pix(idmp, x, y))) {
237     idmap_close(idmp);
238     return 0;
239     }
240     fputs(id, stdout);
241     putchar(sepc);
242     if (unbuffered && fflush(stdout) == EOF) {
243     fputs(progname, stderr);
244     fputs(": write error on output\n", stderr);
245     idmap_close(idmp);
246     return 0;
247     }
248     }
249     idmap_close(idmp);
250    
251     if (!feof(stdin)) {
252     fputs(progname, stderr);
253     fputs(": non-numeric input for pixel index\n", stderr);
254     return 0;
255     }
256     return 1;
257     }
258    
259    
260     /* Load and convert identifier index file to ASCII */
261     int
262     decode_all(const char *fname, int hdrflags)
263     {
264     IDMAP *idmp = idmap_ropen(fname, hdrflags);
265     long n;
266    
267     if (!idmp)
268     return 0;
269    
270     for (n = idmp->res.xr*idmp->res.yr; n-- > 0; ) {
271     const char *id = idmap_next(idmp);
272     if (!id) {
273     fputs(fname, stderr);
274     fputs(": unexpected EOF\n", stderr);
275     idmap_close(idmp);
276     return 0;
277     }
278     fputs(id, stdout);
279     putchar(sepc);
280     }
281     idmap_close(idmp);
282     return 1;
283     }
284    
285    
286     int
287     main(int argc, char *argv[])
288     {
289     char *inpfname = NULL;
290     int reverse = 0;
291     int bypixel = 0;
292     int hdrflags = HF_HEADOUT|HF_RESOUT;
293     int xres=0, yres=0;
294     int ndxbytes = 2;
295     int a;
296    
297     progname = argv[0];
298     for (a = 1; a < argc && argv[a][0] == '-'; a++)
299     switch (argv[a][1]) {
300     case 'r':
301     reverse++;
302     break;
303     case 'i':
304     bypixel++;
305     break;
306     case 'u':
307     unbuffered++;
308     break;
309     case 'h':
310     hdrflags &= ~HF_HEADOUT;
311     break;
312     case 'H':
313     hdrflags &= ~HF_RESOUT;
314     break;
315     case 't':
316     if (!(sepc = argv[a][2]))
317     sepc = '\n';
318     break;
319     case 'x':
320     xres = atoi(argv[++a]);
321     break;
322     case 'y':
323     yres = atoi(argv[++a]);
324     break;
325     case '8':
326     case '1':
327     case '2':
328     switch (atoi(argv[a]+1)) {
329     case 8:
330     ndxbytes = 1;
331     break;
332     case 16:
333     ndxbytes = 2;
334     break;
335     case 24:
336     ndxbytes = 3;
337     break;
338     default:
339     usage_exit(1);
340     }
341     break;
342     default:
343     usage_exit(1);
344     }
345 greg 2.2 if ((xres > 0) & (yres > 0)) /* user specified resolution? */
346     hdrflags &= ~HF_RESOUT;
347 greg 2.1 if (reverse && a >= argc) {
348     fputs(progname, stderr);
349     fputs(": -r option requires named input file\n", stderr);
350     return 1;
351     }
352     if (a < argc-2) {
353     fputs(progname, stderr);
354     fputs(": too many file arguments\n", stderr);
355     return 1;
356     }
357     if (a < argc)
358     inpfname = argv[a];
359     if (a+1 < argc && !freopen(argv[a+1], "w", stdout)) {
360     fputs(argv[a+1], stderr);
361     fputs(": cannot open output\n", stderr);
362     return 1;
363     }
364     if (!reverse)
365     SET_FILE_BINARY(stdout);
366     #ifdef getc_unlocked /* avoid stupid semaphores */
367     flockfile(stdout);
368     #endif
369     if (reverse) {
370     if (!(bypixel ? decode_select(inpfname, hdrflags) :
371     decode_all(inpfname, hdrflags)))
372     return 1;
373     } else if (!create_index(inpfname, hdrflags, ndxbytes, xres, yres))
374     return 1;
375    
376     if (fflush(stdout) == EOF) {
377     fputs(progname, stderr);
378     fputs(": error writing output\n", stderr);
379     return 1;
380     }
381     return 0;
382     }