ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/normcodec.c
Revision: 2.6
Committed: Thu Mar 3 16:09:31 2022 UTC (3 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +17 -11 lines
Log Message:
feat(rcode_depth,rcode_norm): Output NROWS & NCOLS with -Ho

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id: normcodec.c,v 2.5 2019/11/07 23:20:28 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Routines to encode/decode 32-bit normals
6     */
7    
8     #include "copyright.h"
9    
10     #include "rtio.h"
11     #include "rtmath.h"
12     #include "normcodec.h"
13    
14    
15     /* Set codec defaults */
16     void
17     set_nc_defaults(NORMCODEC *ncp)
18     {
19     memset(ncp, 0, sizeof(NORMCODEC));
20     ncp->finp = stdin;
21     ncp->inpname = "<stdin>";
22     ncp->format = 'a';
23     ncp->res.rt = PIXSTANDARD;
24     if (!progname) progname = "norm_codec";
25     }
26    
27    
28     /* process header line */
29     static int
30     headline(char *s, void *p)
31     {
32     NORMCODEC *ncp = (NORMCODEC *)p;
33 greg 2.3 int rv;
34 greg 2.1
35     if (formatval(ncp->inpfmt, s)) /* don't pass format */
36     return 0;
37    
38 greg 2.3 if ((rv = isbigendian(s)) >= 0) {
39     ncp->swapped = (nativebigendian() != rv);
40     return 0;
41     }
42 greg 2.1 if (ncp->hdrflags & HF_HEADOUT)
43     fputs(s, stdout); /* copy to standard output */
44     return 1;
45     }
46    
47    
48     /* Load/copy header */
49     int
50     process_nc_header(NORMCODEC *ncp, int ac, char *av[])
51     {
52     if (ncp->hdrflags & HF_HEADIN &&
53     getheader(ncp->finp, headline, ncp) < 0) {
54 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
55     fputs(ncp->inpname, stderr);
56     fputs(": bad header\n", stderr);
57     }
58     return 0;
59 greg 2.1 }
60 greg 2.6 /* get resolution string? */
61     if (ncp->hdrflags & HF_RESIN && !fgetsresolu(&ncp->res, ncp->finp)) {
62     if (ncp->hdrflags & HF_STDERR) {
63     fputs(ncp->inpname, stderr);
64     fputs(": bad resolution string\n", stderr);
65     }
66     return 0;
67     }
68 greg 2.1 if (ncp->hdrflags & HF_HEADOUT) { /* finish header */
69     if (!(ncp->hdrflags & HF_HEADIN))
70     newheader("RADIANCE", stdout);
71     if (ac > 0)
72     printargs(ac, av, stdout);
73     if (ncp->hdrflags & HF_ENCODE) {
74     fputformat(NORMAL32FMT, stdout);
75 greg 2.6 } else {
76     fputs("NCOMP=3\n", stdout);
77     if ((ncp->hdrflags & (HF_RESIN|HF_RESOUT)) == HF_RESIN)
78     printf("NCOLS=%d\nNROWS=%d\n",
79     scanlen(&ncp->res),
80     numscans(&ncp->res));
81 greg 2.1 switch (ncp->format) {
82     case 'a':
83     fputformat("ascii", stdout);
84     break;
85     case 'f':
86 greg 2.3 fputendian(stdout);
87 greg 2.1 fputformat("float", stdout);
88     break;
89     case 'd':
90 greg 2.3 fputendian(stdout);
91 greg 2.1 fputformat("double", stdout);
92     break;
93     }
94 greg 2.6 }
95 greg 2.1 fputc('\n', stdout);
96     }
97 greg 2.6 if (ncp->hdrflags & HF_RESOUT) /* put resolution string? */
98 greg 2.1 fputsresolu(&ncp->res, stdout);
99    
100     ncp->dstart = ncp->curpos = ftell(ncp->finp);
101     return 1;
102     }
103    
104    
105     /* Check that we have what we need to decode normals */
106     int
107     check_decode_normals(NORMCODEC *ncp)
108     {
109     if (ncp->hdrflags & HF_ENCODE) {
110 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
111     fputs(progname, stderr);
112     fputs(": wrong header mode for decode\n", stderr);
113     }
114 greg 2.1 return 0;
115     }
116     if (ncp->inpfmt[0] && strcmp(ncp->inpfmt, NORMAL32FMT)) {
117 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
118     fputs(ncp->inpname, stderr);
119     fputs(": unexpected input format: ", stderr);
120     fputs(ncp->inpfmt, stderr);
121     fputc('\n', stderr);
122     }
123 greg 2.1 return 0;
124     }
125     return 1;
126     }
127    
128    
129     /* Decode next normal from input */
130     int
131     decode_normal_next(FVECT nrm, NORMCODEC *ncp)
132     {
133 greg 2.5 static int32 lastc;
134     static FVECT lastv;
135     int32 c = getint(4, ncp->finp);
136 greg 2.1
137     if (c == EOF && feof(ncp->finp))
138     return -1;
139    
140     ncp->curpos += 4;
141    
142 greg 2.4 if (c == lastc) { /* optimization */
143     VCOPY(nrm, lastv);
144     } else {
145     decodedir(nrm, c);
146     if (c) {
147     lastc = c;
148     VCOPY(lastv, nrm);
149     }
150     }
151 greg 2.1 return (c != 0);
152     }
153    
154    
155     /* Seek to the indicated pixel position */
156     int
157     seek_nc_pix(NORMCODEC *ncp, int x, int y)
158     {
159     long seekpos;
160    
161     if ((ncp->res.xr <= 0) | (ncp->res.yr <= 0)) {
162 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
163     fputs(progname, stderr);
164     fputs(": need map resolution to seek\n", stderr);
165     }
166 greg 2.1 return -1;
167     }
168     if ((x < 0) | (y < 0) ||
169     (x >= scanlen(&ncp->res)) | (y >= numscans(&ncp->res))) {
170 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
171     fputs(ncp->inpname, stderr);
172     fputs(": warning - pixel index off map\n", stderr);
173     }
174 greg 2.1 return 0;
175     }
176     seekpos = ncp->dstart + 4*((long)y*scanlen(&ncp->res) + x);
177    
178     if (seekpos != ncp->curpos &&
179     fseek(ncp->finp, seekpos, SEEK_SET) == EOF) {
180 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
181     fputs(ncp->inpname, stderr);
182     fputs(": seek error\n", stderr);
183     }
184 greg 2.1 return -1;
185     }
186     ncp->curpos = seekpos;
187     return 1;
188     }
189    
190    
191     /* Read and decode normal for the given pixel */
192     int
193     decode_normal_pix(FVECT nrm, NORMCODEC *ncp, int x, int y)
194     {
195     int rval = seek_nc_pix(ncp, x, y);
196    
197     if (rval < 0)
198     return -1;
199    
200     if (!rval) {
201     nrm[0] = nrm[1] = nrm[2] = .0;
202     return 0;
203     }
204     return decode_normal_next(nrm, ncp);
205     }