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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.4 static const char RCSid[] = "$Id: depthcodec.c,v 2.3 2019/07/26 18:52:32 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 greg 2.4 dcp->swapped = 0;
63 greg 2.1 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 greg 2.4 int rv;
77 greg 2.1
78     if (formatval(dcp->inpfmt, s)) /* don't pass format */
79     return 0;
80 greg 2.4
81     if ((rv = isbigendian(s)) >= 0) {
82     dcp->swapped = (nativebigendian() != rv);
83     return 0;
84     }
85 greg 2.1 /* 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
96     fputs(dcp->inpname, stderr);
97     fputs(": bad reference depth in input header\n",
98     stderr);
99     }
100 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
117     fputs(dcp->inpname, stderr);
118     fputs(": bad header\n", stderr);
119     }
120     return 0;
121 greg 2.1 }
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 greg 2.4 fputendian(stdout);
139 greg 2.1 fputformat("float", stdout);
140     break;
141     case 'd':
142 greg 2.4 fputendian(stdout);
143 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
151     fputs(dcp->inpname, stderr);
152     fputs(": bad resolution string\n", stderr);
153     }
154     return 0;
155 greg 2.1 }
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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
170     fputs(progname, stderr);
171     fputs(": wrong header mode for decode\n", stderr);
172     }
173 greg 2.1 return 0;
174     }
175     if (dcp->inpfmt[0] && strcmp(dcp->inpfmt, DEPTH16FMT)) {
176 greg 2.2 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 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
198     fputs(progname, stderr);
199     fputs(": missing map resolution\n", stderr);
200     }
201 greg 2.1 return 0;
202     }
203     if (!dcp->gotview) {
204 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
205     fputs(dcp->inpname, stderr);
206     fputs(": missing view\n", stderr);
207     }
208 greg 2.1 return 0;
209     }
210     if ((err = setview(&dcp->vw)) != NULL) {
211 greg 2.2 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 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
284     fputs(progname, stderr);
285     fputs(": need map resolution to seek\n", stderr);
286     }
287 greg 2.1 return -1;
288     }
289     if ((x < 0) | (y < 0) ||
290     (x >= scanlen(&dcp->res)) | (y >= numscans(&dcp->res))) {
291 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
292     fputs(dcp->inpname, stderr);
293     fputs(": warning - pixel index off map\n", stderr);
294     }
295 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
302     fputs(dcp->inpname, stderr);
303     fputs(": seek error\n", stderr);
304     }
305 greg 2.1 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     }