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