ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/depthcodec.c
Revision: 2.3
Committed: Fri Jul 26 18:52:32 2019 UTC (4 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +6 -4 lines
Log Message:
Made macro for code2depth() and made both it and depth2code() macros optional

File Contents

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