ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rcode_depth.c
Revision: 2.4
Committed: Sat Jul 20 02:07:23 2019 UTC (4 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +4 -4 lines
Log Message:
Created man pages for rcode_depth, rcode_ident, and rcode_norm

File Contents

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