ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/depthcodec.c
Revision: 2.2
Committed: Fri Jul 26 17:04:12 2019 UTC (4 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +52 -29 lines
Log Message:
Added control for stderr output

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: depthcodec.c,v 2.1 2019/07/26 16:18:06 greg Exp $";
3 #endif
4 /*
5 * Routines to encode/decoded 16-bit depths
6 */
7
8 #include "copyright.h"
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <math.h>
13 #include <ctype.h>
14 #include "rtio.h"
15 #include "fvect.h"
16 #include "depthcodec.h"
17
18
19 #if 0 /* defined as macro in depthcodec.h */
20 /* Encode depth as 16-bit signed integer */
21 int
22 depth2code(double d, double dref)
23 {
24 if (d <= .0)
25 return -32768;
26
27 if (d > dref)
28 return (int)(32768 - 32768*dref/d) - 1;
29
30 return (int)(32767*d/dref - 32768);
31 }
32 #endif
33
34
35 /* Decode depth from 16-bit signed integer */
36 double
37 code2depth(int c, double dref)
38 {
39 if (c <= -32768)
40 return .0;
41
42 if (c >= 32767)
43 return FHUGE;
44
45 if (c < 0)
46 return dref*(32767.5 + c)*(1./32767.);
47
48 return dref*32768./(32766.5 - c);
49 }
50
51
52 /* Set codec defaults */
53 void
54 set_dc_defaults(DEPTHCODEC *dcp)
55 {
56 memset(dcp, 0, sizeof(DEPTHCODEC));
57 dcp->finp = stdin;
58 dcp->inpname = "<stdin>";
59 dcp->format = 'a';
60 dcp->refdepth = 1.;
61 dcp->depth_unit[0] = '1';
62 dcp->vw = stdview;
63 dcp->res.rt = PIXSTANDARD;
64 if (!progname) progname = "depth_codec";
65 }
66
67
68 /* process header line */
69 static int
70 headline(char *s, void *p)
71 {
72 DEPTHCODEC *dcp = (DEPTHCODEC *)p;
73
74 if (formatval(dcp->inpfmt, s)) /* don't pass format */
75 return 0;
76 /* check for reference depth */
77 if (!strncmp(s, DEPTHSTR, LDEPTHSTR)) {
78 char *cp;
79 strlcpy(dcp->depth_unit, s+LDEPTHSTR, sizeof(dcp->depth_unit));
80 cp = dcp->depth_unit;
81 while (*cp) cp++;
82 while (cp > dcp->depth_unit && isspace(cp[-1])) cp--;
83 *cp = '\0';
84 dcp->refdepth = atof(dcp->depth_unit);
85 if (dcp->refdepth <= .0) {
86 if (dcp->hdrflags & HF_STDERR) {
87 fputs(dcp->inpname, stderr);
88 fputs(": bad reference depth in input header\n",
89 stderr);
90 }
91 return -1;
92 }
93 } else if (isview(s)) /* get view params */
94 dcp->gotview += (sscanview(&dcp->vw, s) > 0);
95 if (dcp->hdrflags & HF_HEADOUT)
96 fputs(s, stdout); /* copy to standard output */
97 return 1;
98 }
99
100
101 /* Load/copy header */
102 int
103 process_dc_header(DEPTHCODEC *dcp, int ac, char *av[])
104 {
105 if (dcp->hdrflags & HF_HEADIN &&
106 getheader(dcp->finp, headline, dcp) < 0) {
107 if (dcp->hdrflags & HF_STDERR) {
108 fputs(dcp->inpname, stderr);
109 fputs(": bad header\n", stderr);
110 }
111 return 0;
112 }
113 if (dcp->hdrflags & HF_HEADOUT) { /* finish header */
114 if (!(dcp->hdrflags & HF_HEADIN))
115 newheader("RADIANCE", stdout);
116 if (ac > 0)
117 printargs(ac, av, stdout);
118 if (dcp->hdrflags & HF_ENCODE) {
119 fputs(DEPTHSTR, stdout);
120 fputs(dcp->depth_unit, stdout);
121 fputc('\n', stdout);
122 fputformat(DEPTH16FMT, stdout);
123 } else
124 switch (dcp->format) {
125 case 'a':
126 fputformat("ascii", stdout);
127 break;
128 case 'f':
129 fputformat("float", stdout);
130 break;
131 case 'd':
132 fputformat("double", stdout);
133 break;
134 }
135 fputc('\n', stdout);
136 }
137 /* get/put resolution string */
138 if (dcp->hdrflags & HF_RESIN && !fgetsresolu(&dcp->res, dcp->finp)) {
139 if (dcp->hdrflags & HF_STDERR) {
140 fputs(dcp->inpname, stderr);
141 fputs(": bad resolution string\n", stderr);
142 }
143 return 0;
144 }
145 if (dcp->hdrflags & HF_RESOUT)
146 fputsresolu(&dcp->res, stdout);
147
148 dcp->dstart = dcp->curpos = ftell(dcp->finp);
149 return 1;
150 }
151
152
153 /* Check that we have what we need to decode depths */
154 int
155 check_decode_depths(DEPTHCODEC *dcp)
156 {
157 if (dcp->hdrflags & HF_ENCODE) {
158 if (dcp->hdrflags & HF_STDERR) {
159 fputs(progname, stderr);
160 fputs(": wrong header mode for decode\n", stderr);
161 }
162 return 0;
163 }
164 if (dcp->inpfmt[0] && strcmp(dcp->inpfmt, DEPTH16FMT)) {
165 if (dcp->hdrflags & HF_STDERR) {
166 fputs(dcp->inpname, stderr);
167 fputs(": unexpected input format: ", stderr);
168 fputs(dcp->inpfmt, stderr);
169 fputc('\n', stderr);
170 }
171 return 0;
172 }
173 return 1;
174 }
175
176
177 /* Check that we have what we need to decode world positions */
178 int
179 check_decode_worldpos(DEPTHCODEC *dcp)
180 {
181 char *err;
182
183 if (!check_decode_depths(dcp))
184 return 0;
185 if ((dcp->res.xr <= 0) | (dcp->res.yr <= 0)) {
186 if (dcp->hdrflags & HF_STDERR) {
187 fputs(progname, stderr);
188 fputs(": missing map resolution\n", stderr);
189 }
190 return 0;
191 }
192 if (!dcp->gotview) {
193 if (dcp->hdrflags & HF_STDERR) {
194 fputs(dcp->inpname, stderr);
195 fputs(": missing view\n", stderr);
196 }
197 return 0;
198 }
199 if ((err = setview(&dcp->vw)) != NULL) {
200 if (dcp->hdrflags & HF_STDERR) {
201 fputs(dcp->inpname, stderr);
202 fputs(": input view error: ", stderr);
203 fputs(err, stderr);
204 fputc('\n', stderr);
205 }
206 return 0;
207 }
208 return 1;
209 }
210
211
212 /* Decode next depth pixel */
213 double
214 decode_depth_next(DEPTHCODEC *dcp)
215 {
216 int c = getint(2, dcp->finp);
217
218 if (c == EOF && feof(dcp->finp))
219 return -1.;
220
221 dcp->curpos += 2;
222
223 return code2depth(c, dcp->refdepth);
224 }
225
226
227 /* Compute world position from depth */
228 int
229 compute_worldpos(FVECT wpos, DEPTHCODEC *dcp, int x, int y, double d)
230 {
231 RREAL loc[2];
232 FVECT rdir;
233
234 pix2loc(loc, &dcp->res, x, y);
235
236 if (viewray(wpos, rdir, &dcp->vw, loc[0], loc[1]) < -FTINY) {
237 VCOPY(wpos, dcp->vw.vp);
238 return 0;
239 }
240 VSUM(wpos, wpos, rdir, d);
241 return 1;
242 }
243
244
245 /* Decode the next world position */
246 int
247 decode_worldpos_next(FVECT wpos, DEPTHCODEC *dcp)
248 {
249 const long n = (dcp->curpos - dcp->dstart)>>1;
250 int x, y;
251 double d;
252
253 d = decode_depth_next(dcp);
254 if (d < -FTINY)
255 return -1;
256
257 x = scanlen(&dcp->res);
258 y = n / x;
259 x = n - (long)y*x;
260
261 return compute_worldpos(wpos, dcp, x, y, d);
262 }
263
264
265 /* Seek to the indicated pixel position */
266 int
267 seek_dc_pix(DEPTHCODEC *dcp, int x, int y)
268 {
269 long seekpos;
270
271 if ((dcp->res.xr <= 0) | (dcp->res.yr <= 0)) {
272 if (dcp->hdrflags & HF_STDERR) {
273 fputs(progname, stderr);
274 fputs(": need map resolution to seek\n", stderr);
275 }
276 return -1;
277 }
278 if ((x < 0) | (y < 0) ||
279 (x >= scanlen(&dcp->res)) | (y >= numscans(&dcp->res))) {
280 if (dcp->hdrflags & HF_STDERR) {
281 fputs(dcp->inpname, stderr);
282 fputs(": warning - pixel index off map\n", stderr);
283 }
284 return 0;
285 }
286 seekpos = dcp->dstart + 2*((long)y*scanlen(&dcp->res) + x);
287
288 if (seekpos != dcp->curpos &&
289 fseek(dcp->finp, seekpos, SEEK_SET) == EOF) {
290 if (dcp->hdrflags & HF_STDERR) {
291 fputs(dcp->inpname, stderr);
292 fputs(": seek error\n", stderr);
293 }
294 return -1;
295 }
296 dcp->curpos = seekpos;
297 return 1;
298 }
299
300
301 /* Read and decode depth for the given pixel */
302 double
303 decode_depth_pix(DEPTHCODEC *dcp, int x, int y)
304 {
305 int rval = seek_dc_pix(dcp, x, y);
306
307 if (rval < 0)
308 return -1.;
309 if (!rval)
310 return .0;
311
312 return decode_depth_next(dcp);
313 }
314
315
316 /* Read and decode the world position at the given pixel */
317 int
318 get_worldpos_pix(FVECT wpos, DEPTHCODEC *dcp, int x, int y)
319 {
320 double d = decode_depth_pix(dcp, x, y);
321
322 if (d < -FTINY)
323 return -1;
324
325 return compute_worldpos(wpos, dcp, x, y, d);
326 }