ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/normcodec.c
Revision: 2.4
Committed: Mon Aug 26 23:33:24 2019 UTC (4 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +12 -3 lines
Log Message:
Optimization for repeated normal directions

File Contents

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