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, 9 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rcode_depth.c,v 2.3 2019/07/19 01:24:33 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]] [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 (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
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 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
83 putint(depth2code(d, dcp->refdepth), 2, stdout);
84
85 } 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 /* Convert and output the given depth to stdout */
97 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 long nexpected = (long)dcp->res.xr * dcp->res.yr;
122
123 if (!check_decode_depths(dcp))
124 return 0;
125
126 do {
127 double d = decode_depth_next(dcp);
128 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
160 loc2pix(xy, &dcp->res,
161 (xy[0]+.5)/dcp->res.xr, (xy[1]+.5)/dcp->res.yr);
162
163 d = decode_depth_pix(dcp, xy[0], xy[1]);
164 if (d < -FTINY)
165 return 0;
166
167 output_depth(dcp, d);
168
169 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 /* Output the given world position to stdout */
185 static void
186 output_worldpos(DEPTHCODEC *dcp, FVECT wpos)
187 {
188 switch (dcp->format) {
189 case 'a':
190 printf("%.5e %.5e %.5e\n", wpos[0], wpos[1], wpos[2]);
191 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 dc.hdrflags &= ~HF_RESOUT;
387 }
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 if ((conversion != CV_FWD) | (dc.format != 'a'))
405 SET_FILE_BINARY(stdout);
406 #ifdef getc_unlocked /* avoid stupid semaphores */
407 flockfile(dc.finp);
408 flockfile(stdout);
409 #endif
410 /* read/copy header */
411 if (!process_dc_header(&dc, a, argv))
412 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 }