ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rcode_depth.c
Revision: 2.6
Committed: Wed Aug 14 21:00:14 2019 UTC (4 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +5 -1 lines
Log Message:
Added byte order to gendaymtx, rsplit, dctimestep, rcode_depth, and rcode_normal

File Contents

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