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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rcode_depth.c,v 2.5 2019/08/13 16:31:35 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 (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 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 dc.hdrflags &= ~HF_RESOUT;
391 }
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 if ((conversion != CV_FWD) | (dc.format != 'a'))
409 SET_FILE_BINARY(stdout);
410 #ifdef getc_unlocked /* avoid stupid semaphores */
411 flockfile(dc.finp);
412 flockfile(stdout);
413 #endif
414 /* read/copy header */
415 if (!process_dc_header(&dc, a, argv))
416 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 }