ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rcode_depth.c
Revision: 2.2
Committed: Thu Jul 18 19:13:44 2019 UTC (4 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +2 -2 lines
Log Message:
Following convention of leaving file names off in header command line detail

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: rcode_depth.c,v 2.1 2019/07/18 18:51:56 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Encode and decode depth values using 16-bit integers
6     */
7    
8     #include "copyright.h"
9    
10     #include <stdlib.h>
11     #include <math.h>
12     #include <ctype.h>
13     #include "platform.h"
14     #include "rtio.h"
15     #include "fvect.h"
16     #include "depthcodec.h"
17    
18     enum {CV_FWD, CV_REV, CV_PTS};
19    
20    
21     /* Report usage error and exit */
22     static void
23     usage_exit(int code)
24     {
25     fputs("Usage: ", stderr);
26     fputs(progname, stderr);
27     fputs(
28     " [-d ref_depth/unit][-h[io]][-H[io]][-f[afd]] [input [output]]\n",
29     stderr);
30     fputs(" Or: ", stderr);
31     fputs(progname, stderr);
32     fputs(
33     " {-r|-p} [-i][-u][-h[io]][-H[io]][-f[afd]] [input [output]]\n",
34     stderr);
35     exit(code);
36     }
37    
38    
39     /* Encode depths from input stream */
40     static int
41     encode_depths(DEPTHCODEC *dcp)
42     {
43     long nexpected = 0;
44    
45     if (dcp->inpfmt[0]) {
46     if (strcasestr(dcp->inpfmt, "ascii") != NULL)
47     dcp->format = 'a';
48     else if (strcasestr(dcp->inpfmt, "float") != NULL)
49     dcp->format = 'f';
50     else if (strcasestr(dcp->inpfmt, "double") != NULL)
51     dcp->format = 'd';
52     else {
53     fputs(dcp->inpname, stderr);
54     fputs(": unsupported input format: ", stderr);
55     fputs(dcp->inpfmt, stderr);
56     fputc('\n', stderr);
57     return 0;
58     }
59     }
60     if (dcp->hdrflags & HF_RESIN)
61     nexpected = (long)dcp->res.xr * dcp->res.yr;
62     do {
63     int ok = 0;
64     float f;
65     double d;
66    
67     switch (dcp->format) {
68     case 'a':
69     ok = (fscanf(dcp->finp, "%lf", &d) == 1);
70     break;
71     case 'f':
72     ok = (getbinary(&f, sizeof(f), 1, dcp->finp) == 1);
73     d = f;
74     break;
75     case 'd':
76     ok = (getbinary(&d, sizeof(d), 1, dcp->finp) == 1);
77     break;
78     }
79     if (!ok)
80     break;
81     putint(depth2code(d, dcp->refdepth), 2, stdout);
82     } while (--nexpected);
83    
84     if (nexpected > 0) {
85     fputs(dcp->inpname, stderr);
86     fputs(": fewer depths than expected\n", stderr);
87     return 0;
88     }
89     return 1;
90     }
91    
92    
93     /* Convert and output the given depth code to stdout */
94     static void
95     output_depth(DEPTHCODEC *dcp, double d)
96     {
97     float f;
98    
99     switch (dcp->format) {
100     case 'a':
101     printf("%.5e\n", d);
102     break;
103     case 'f':
104     f = d;
105     putbinary(&f, sizeof(f), 1, stdout);
106     break;
107     case 'd':
108     putbinary(&d, sizeof(d), 1, stdout);
109     break;
110     }
111     }
112    
113    
114     /* Decode depths from input stream */
115     static int
116     decode_depths(DEPTHCODEC *dcp)
117     {
118     long nexpected = 0;
119    
120     if (!check_decode_depths(dcp))
121     return 0;
122    
123     if (dcp->hdrflags & HF_RESIN)
124     nexpected = (long)dcp->res.xr * dcp->res.yr;
125     do {
126     double d = decode_depth_next(dcp);
127     if (d < -FTINY)
128     break;
129     output_depth(dcp, d);
130    
131     } while (--nexpected);
132    
133     if (nexpected > 0) {
134     fputs(dcp->inpname, stderr);
135     fputs(": unexpected EOF\n", stderr);
136     return 0;
137     }
138     return 1;
139     }
140    
141    
142     /* Decode depths at particular pixels given on standard input */
143     static int
144     pixel_depths(DEPTHCODEC *dcp, int unbuf)
145     {
146     int xy[2];
147     double d;
148    
149     if (dcp->finp == stdin) {
150     fputs(progname, stderr);
151     fputs(": <stdin> used for encoded depths\n", stderr);
152     return 0;
153     }
154     if (!check_decode_depths(dcp))
155     return 0;
156    
157     while (scanf("%d %d", &xy[0], &xy[1]) == 2) {
158     loc2pix(xy, &dcp->res,
159     (xy[0]+.5)/dcp->res.xr, (xy[1]+.5)/dcp->res.yr);
160     d = decode_depth_pix(dcp, xy[0], xy[1]);
161     if (d < -FTINY)
162     return 0;
163     output_depth(dcp, d);
164     if (unbuf && fflush(stdout) == EOF) {
165     fputs(progname, stderr);
166     fputs(": write error on output\n", stderr);
167     return 0;
168     }
169     }
170     if (!feof(stdin)) {
171     fputs(progname, stderr);
172     fputs(": non-integer as pixel index\n", stderr);
173     return 0;
174     }
175     return 1;
176     }
177    
178    
179     /* Output the given world position */
180     static void
181     output_worldpos(DEPTHCODEC *dcp, FVECT wpos)
182     {
183     switch (dcp->format) {
184     case 'a':
185     fprintf(stdout, "%.5e %.5e %.5e\n",
186     wpos[0], wpos[1], wpos[2]);
187     break;
188     #ifdef SMLFLT
189     case 'f':
190     putbinary(wpos, sizeof(*wpos), 3, stdout);
191     break;
192     case 'd': {
193     double wpd[3];
194     VCOPY(wpd, wpos);
195     putbinary(wpd, sizeof(*wpd), 3, stdout);
196     }
197     break;
198     #else
199     case 'f': {
200     float wpf[3];
201     VCOPY(wpf, wpos);
202     putbinary(wpf, sizeof(*wpf), 3, stdout);
203     }
204     break;
205     case 'd':
206     putbinary(wpos, sizeof(*wpos), 3, stdout);
207     break;
208     #endif
209     }
210     }
211    
212    
213     /* Decode world points from input stream */
214     static int
215     decode_points(DEPTHCODEC *dcp)
216     {
217     long n = (long)dcp->res.xr * dcp->res.yr;
218    
219     if (!check_decode_worldpos(dcp))
220     return 0;
221    
222     while (n-- > 0) {
223     FVECT wpos;
224     if (decode_worldpos_next(wpos, dcp) < 0) {
225     if (feof(dcp->finp)) {
226     fputs(dcp->inpname, stderr);
227     fputs(": unexpected EOF\n", stderr);
228     }
229     return 0;
230     }
231     output_worldpos(dcp, wpos);
232     }
233     return 1;
234     }
235    
236    
237     /* Decode world points at particular pixels given on standard input */
238     static int
239     pixel_points(DEPTHCODEC *dcp, int unbuf)
240     {
241     int xy[2];
242     FVECT wpos;
243    
244     if (dcp->finp == stdin) {
245     fputs(progname, stderr);
246     fputs(": <stdin> used for encoded depths\n", stderr);
247     return 0;
248     }
249     if (!check_decode_worldpos(dcp))
250     return 0;
251    
252     while (scanf("%d %d", &xy[0], &xy[1]) == 2) {
253     loc2pix(xy, &dcp->res,
254     (xy[0]+.5)/dcp->res.xr, (xy[1]+.5)/dcp->res.yr);
255     if (get_worldpos_pix(wpos, dcp, xy[0], xy[1]) < 0)
256     return 0;
257     output_worldpos(dcp, wpos);
258     if (unbuf && fflush(stdout) == EOF) {
259     fputs(progname, stderr);
260     fputs(": write error on output\n", stderr);
261     return 0;
262     }
263     }
264     if (!feof(stdin)) {
265     fputs(progname, stderr);
266     fputs(": non-integer as pixel index\n", stderr);
267     return 0;
268     }
269     return 1;
270     }
271    
272    
273     int
274     main(int argc, char *argv[])
275     {
276     int conversion = CV_FWD;
277     int bypixel = 0;
278     int unbuffered = 0;
279     DEPTHCODEC dc;
280     int a;
281    
282     progname = argv[0];
283     set_dc_defaults(&dc);
284     dc.hdrflags = HF_ALL;
285     for (a = 1; a < argc && argv[a][0] == '-'; a++)
286     switch (argv[a][1]) {
287     case 'd':
288     strlcpy(dc.depth_unit, argv[++a], sizeof(dc.depth_unit));
289     dc.refdepth = atof(dc.depth_unit);
290     if (dc.refdepth <= .0) {
291     fputs(progname, stderr);
292     fputs(": illegal -d reference depth\n", stderr);
293     return 1;
294     }
295     break;
296     case 'r':
297     conversion = CV_REV;
298     break;
299     case 'p':
300     conversion = CV_PTS;
301     break;
302     case 'f':
303     switch (argv[a][2]) {
304     case 'f':
305     case 'd':
306     case 'a':
307     dc.format = argv[a][2];
308     break;
309     default:
310     fputs(progname, stderr);
311     fputs(": unsupported -f? format\n", stderr);
312     usage_exit(1);
313     }
314     break;
315     case 'h':
316     switch (argv[a][2]) {
317     case '\0':
318     dc.hdrflags &= ~(HF_HEADIN|HF_HEADOUT);
319     break;
320     case 'i':
321     case 'I':
322     dc.hdrflags &= ~HF_HEADIN;
323     break;
324     case 'o':
325     case 'O':
326     dc.hdrflags &= ~HF_HEADOUT;
327     break;
328     default:
329     usage_exit(1);
330     }
331     break;
332     case 'H':
333     switch (argv[a][2]) {
334     case '\0':
335     dc.hdrflags &= ~(HF_RESIN|HF_RESOUT);
336     break;
337     case 'i':
338     case 'I':
339     dc.hdrflags &= ~HF_RESIN;
340     break;
341     case 'o':
342     case 'O':
343     dc.hdrflags &= ~HF_RESOUT;
344     break;
345     default:
346     usage_exit(1);
347     }
348     break;
349     case 'i':
350     bypixel++;
351     break;
352     case 'u':
353     unbuffered++;
354     break;
355     default:
356     usage_exit(1);
357     }
358     dc.hdrflags |= (conversion == CV_FWD) * HF_ENCODE;
359    
360     if ((dc.hdrflags & (HF_RESIN|HF_RESOUT)) == HF_RESOUT) {
361     fputs(progname, stderr);
362     fputs(": unknown resolution for output\n", stderr);
363     return 1;
364     }
365     if (bypixel) {
366     if (conversion == CV_FWD) {
367     fputs(progname, stderr);
368     fputs(": -i only supported with -r or -p option\n",
369     stderr);
370     usage_exit(1);
371     }
372     if (a >= argc) {
373     fputs(progname, stderr);
374     fputs(": -i option requires input file\n", stderr);
375     usage_exit(1);
376     }
377     if (!(dc.hdrflags & HF_RESIN)) {
378     fputs(progname, stderr);
379     fputs(": -i option requires input resolution\n", stderr);
380     usage_exit(1);
381     }
382     dc.hdrflags &= ~(HF_HEADOUT|HF_RESOUT);
383     }
384     if (a < argc-2) {
385     fputs(progname, stderr);
386     fputs(": too many file arguments\n", stderr);
387     usage_exit(1);
388     }
389     if (a < argc && !(dc.finp = fopen(dc.inpname=argv[a], "r"))) {
390     fputs(dc.inpname, stderr);
391     fputs(": cannot open for reading\n", stderr);
392     return 1;
393     }
394     if (a+1 < argc && !freopen(argv[a+1], "w", stdout)) {
395     fputs(argv[a+1], stderr);
396     fputs(": cannot open for writing\n", stderr);
397     return 1;
398     }
399     SET_FILE_BINARY(dc.finp);
400     SET_FILE_BINARY(stdout);
401     #ifdef getc_unlocked /* avoid stupid semaphores */
402     flockfile(dc.finp);
403     flockfile(stdout);
404     #endif
405     /* read/copy header */
406 greg 2.2 if (!process_dc_header(&dc, a, argv))
407 greg 2.1 return 1;
408     /* process data */
409     switch (conversion) {
410     case CV_FWD: /* distance -> depth code */
411     if (!encode_depths(&dc))
412     return 1;
413     break;
414     case CV_REV: /* depth code -> distance */
415     if (!(bypixel ? pixel_depths(&dc, unbuffered) :
416     decode_depths(&dc)))
417     return 1;
418     break;
419     case CV_PTS: /* depth code -> world points */
420     if (!(bypixel ? pixel_points(&dc, unbuffered) :
421     decode_points(&dc)))
422     return 1;
423     break;
424     }
425     if (fflush(stdout) == EOF) {
426     fputs(progname, stderr);
427     fputs(": error writing output\n", stderr);
428     return 1;
429     }
430     return 0;
431     }