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, 9 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: depthcodec.c,v 2.1 2019/07/26 16:18:06 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     #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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
87     fputs(dcp->inpname, stderr);
88     fputs(": bad reference depth in input header\n",
89     stderr);
90     }
91 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
108     fputs(dcp->inpname, stderr);
109     fputs(": bad header\n", stderr);
110     }
111     return 0;
112 greg 2.1 }
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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
140     fputs(dcp->inpname, stderr);
141     fputs(": bad resolution string\n", stderr);
142     }
143     return 0;
144 greg 2.1 }
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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
159     fputs(progname, stderr);
160     fputs(": wrong header mode for decode\n", stderr);
161     }
162 greg 2.1 return 0;
163     }
164     if (dcp->inpfmt[0] && strcmp(dcp->inpfmt, DEPTH16FMT)) {
165 greg 2.2 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 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
187     fputs(progname, stderr);
188     fputs(": missing map resolution\n", stderr);
189     }
190 greg 2.1 return 0;
191     }
192     if (!dcp->gotview) {
193 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
194     fputs(dcp->inpname, stderr);
195     fputs(": missing view\n", stderr);
196     }
197 greg 2.1 return 0;
198     }
199     if ((err = setview(&dcp->vw)) != NULL) {
200 greg 2.2 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 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
273     fputs(progname, stderr);
274     fputs(": need map resolution to seek\n", stderr);
275     }
276 greg 2.1 return -1;
277     }
278     if ((x < 0) | (y < 0) ||
279     (x >= scanlen(&dcp->res)) | (y >= numscans(&dcp->res))) {
280 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
281     fputs(dcp->inpname, stderr);
282     fputs(": warning - pixel index off map\n", stderr);
283     }
284 greg 2.1 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 greg 2.2 if (dcp->hdrflags & HF_STDERR) {
291     fputs(dcp->inpname, stderr);
292     fputs(": seek error\n", stderr);
293     }
294 greg 2.1 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     }