ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rcode_depth.c
Revision: 2.8
Committed: Wed Nov 13 18:20:47 2019 UTC (4 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +2 -2 lines
Log Message:
Fixed usage statement corresponding to previous addition

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rcode_depth.c,v 2.7 2019/11/13 18:17:05 greg Exp $";
3 #endif
4 /*
5 * Encode and decode depth map 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 char *progname; /* set in main() */
19
20 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 " [-d ref_depth/unit][-h[io]][-H[io]][-f[afd]][-x xr -y yr] [input [output.dpt]]\n",
31 stderr);
32 fputs(" Or: ", stderr);
33 fputs(progname, stderr);
34 fputs(
35 " {-r|-p} [-i][-u][-h[io]][-H[io]][-f[afd]] [input.dpt [output]]\n",
36 stderr);
37 exit(code);
38 }
39
40
41 /* Encode depths from input stream */
42 static int
43 encode_depths(DEPTHCODEC *dcp)
44 {
45 long nexpected = (long)dcp->res.xr * dcp->res.yr;
46
47 if (dcp->inpfmt[0]) {
48 if (strstr(dcp->inpfmt, "ascii") != NULL)
49 dcp->format = 'a';
50 else if (strstr(dcp->inpfmt, "float") != NULL)
51 dcp->format = 'f';
52 else if (strstr(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
63 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 if (dcp->swapped)
75 swap32((char *)&f, 1);
76 d = f;
77 break;
78 case 'd':
79 ok = (getbinary(&d, sizeof(d), 1, dcp->finp) == 1);
80 if (dcp->swapped)
81 swap64((char *)&d, 1);
82 break;
83 }
84 if (!ok)
85 break;
86
87 putint(depth2code(d, dcp->refdepth), 2, stdout);
88
89 } 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 /* Convert and output the given depth to stdout */
101 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 long nexpected = (long)dcp->res.xr * dcp->res.yr;
126
127 if (!check_decode_depths(dcp))
128 return 0;
129
130 do {
131 double d = decode_depth_next(dcp);
132 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
164 loc2pix(xy, &dcp->res,
165 (xy[0]+.5)/dcp->res.xr, (xy[1]+.5)/dcp->res.yr);
166
167 d = decode_depth_pix(dcp, xy[0], xy[1]);
168 if (d < -FTINY)
169 return 0;
170
171 output_depth(dcp, d);
172
173 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 /* Output the given world position to stdout */
189 static void
190 output_worldpos(DEPTHCODEC *dcp, FVECT wpos)
191 {
192 switch (dcp->format) {
193 case 'a':
194 printf("%.5e %.5e %.5e\n", wpos[0], wpos[1], wpos[2]);
195 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 xres=0, yres=0;
285 int conversion = CV_FWD;
286 int bypixel = 0;
287 int unbuffered = 0;
288 DEPTHCODEC dc;
289 int a;
290
291 progname = argv[0];
292 set_dc_defaults(&dc);
293 dc.hdrflags = HF_ALL;
294 for (a = 1; a < argc && argv[a][0] == '-'; a++)
295 switch (argv[a][1]) {
296 case 'd':
297 strlcpy(dc.depth_unit, argv[++a], sizeof(dc.depth_unit));
298 dc.refdepth = atof(dc.depth_unit);
299 if (dc.refdepth <= .0) {
300 fputs(progname, stderr);
301 fputs(": illegal -d reference depth\n", stderr);
302 return 1;
303 }
304 break;
305 case 'r':
306 conversion = CV_REV;
307 break;
308 case 'p':
309 conversion = CV_PTS;
310 break;
311 case 'f':
312 switch (argv[a][2]) {
313 case 'f':
314 case 'd':
315 case 'a':
316 dc.format = argv[a][2];
317 break;
318 default:
319 fputs(progname, stderr);
320 fputs(": unsupported -f? format\n", stderr);
321 usage_exit(1);
322 }
323 break;
324 case 'h':
325 switch (argv[a][2]) {
326 case '\0':
327 dc.hdrflags &= ~(HF_HEADIN|HF_HEADOUT);
328 break;
329 case 'i':
330 case 'I':
331 dc.hdrflags &= ~HF_HEADIN;
332 break;
333 case 'o':
334 case 'O':
335 dc.hdrflags &= ~HF_HEADOUT;
336 break;
337 default:
338 usage_exit(1);
339 }
340 break;
341 case 'H':
342 switch (argv[a][2]) {
343 case '\0':
344 dc.hdrflags &= ~(HF_RESIN|HF_RESOUT);
345 break;
346 case 'i':
347 case 'I':
348 dc.hdrflags &= ~HF_RESIN;
349 break;
350 case 'o':
351 case 'O':
352 dc.hdrflags &= ~HF_RESOUT;
353 break;
354 default:
355 usage_exit(1);
356 }
357 break;
358 case 'x':
359 xres = atoi(argv[++a]);
360 break;
361 case 'y':
362 yres = atoi(argv[++a]);
363 break;
364 case 'i':
365 bypixel++;
366 break;
367 case 'u':
368 unbuffered++;
369 break;
370 default:
371 usage_exit(1);
372 }
373 dc.hdrflags |= (conversion == CV_FWD) * HF_ENCODE;
374
375 if ((xres > 0) & (yres > 0)) {
376 dc.hdrflags &= ~HF_RESIN;
377 dc.res.rt = PIXSTANDARD;
378 dc.res.xr = xres;
379 dc.res.yr = yres;
380 } else if ((dc.hdrflags & (HF_RESIN|HF_RESOUT)) == HF_RESOUT) {
381 fputs(progname, stderr);
382 fputs(": unknown resolution for output\n", stderr);
383 return 1;
384 }
385 if (bypixel) {
386 if (conversion == CV_FWD) {
387 fputs(progname, stderr);
388 fputs(": -i only supported with -r or -p option\n",
389 stderr);
390 usage_exit(1);
391 }
392 if (a >= argc) {
393 fputs(progname, stderr);
394 fputs(": -i option requires input file\n", stderr);
395 usage_exit(1);
396 }
397 if (!(dc.hdrflags & HF_RESIN)) {
398 fputs(progname, stderr);
399 fputs(": -i option requires input resolution\n", stderr);
400 usage_exit(1);
401 }
402 dc.hdrflags &= ~HF_RESOUT;
403 }
404 if (a < argc-2) {
405 fputs(progname, stderr);
406 fputs(": too many file arguments\n", stderr);
407 usage_exit(1);
408 }
409 if (a < argc && !(dc.finp = fopen(dc.inpname=argv[a], "r"))) {
410 fputs(dc.inpname, stderr);
411 fputs(": cannot open for reading\n", stderr);
412 return 1;
413 }
414 if (a+1 < argc && !freopen(argv[a+1], "w", stdout)) {
415 fputs(argv[a+1], stderr);
416 fputs(": cannot open for writing\n", stderr);
417 return 1;
418 }
419 SET_FILE_BINARY(dc.finp);
420 if ((conversion != CV_FWD) | (dc.format != 'a'))
421 SET_FILE_BINARY(stdout);
422 #ifdef getc_unlocked /* avoid stupid semaphores */
423 flockfile(dc.finp);
424 flockfile(stdout);
425 #endif
426 /* read/copy header */
427 if (!process_dc_header(&dc, a, argv))
428 return 1;
429 /* process data */
430 switch (conversion) {
431 case CV_FWD: /* distance -> depth code */
432 if (!encode_depths(&dc))
433 return 1;
434 break;
435 case CV_REV: /* depth code -> distance */
436 if (!(bypixel ? pixel_depths(&dc, unbuffered) :
437 decode_depths(&dc)))
438 return 1;
439 break;
440 case CV_PTS: /* depth code -> world points */
441 if (!(bypixel ? pixel_points(&dc, unbuffered) :
442 decode_points(&dc)))
443 return 1;
444 break;
445 }
446 if (fflush(stdout) == EOF) {
447 fputs(progname, stderr);
448 fputs(": error writing output\n", stderr);
449 return 1;
450 }
451 return 0;
452 }