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 (2 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: normcodec.c,v 2.5 2019/11/07 23:20:28 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->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 int rv;
34
35 if (formatval(ncp->inpfmt, s)) /* don't pass format */
36 return 0;
37
38 if ((rv = isbigendian(s)) >= 0) {
39 ncp->swapped = (nativebigendian() != rv);
40 return 0;
41 }
42 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 if (ncp->hdrflags & HF_STDERR) {
55 fputs(ncp->inpname, stderr);
56 fputs(": bad header\n", stderr);
57 }
58 return 0;
59 }
60 /* 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 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 } 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 switch (ncp->format) {
82 case 'a':
83 fputformat("ascii", stdout);
84 break;
85 case 'f':
86 fputendian(stdout);
87 fputformat("float", stdout);
88 break;
89 case 'd':
90 fputendian(stdout);
91 fputformat("double", stdout);
92 break;
93 }
94 }
95 fputc('\n', stdout);
96 }
97 if (ncp->hdrflags & HF_RESOUT) /* put resolution string? */
98 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 if (ncp->hdrflags & HF_STDERR) {
111 fputs(progname, stderr);
112 fputs(": wrong header mode for decode\n", stderr);
113 }
114 return 0;
115 }
116 if (ncp->inpfmt[0] && strcmp(ncp->inpfmt, NORMAL32FMT)) {
117 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 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 static int32 lastc;
134 static FVECT lastv;
135 int32 c = getint(4, ncp->finp);
136
137 if (c == EOF && feof(ncp->finp))
138 return -1;
139
140 ncp->curpos += 4;
141
142 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 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 if (ncp->hdrflags & HF_STDERR) {
163 fputs(progname, stderr);
164 fputs(": need map resolution to seek\n", stderr);
165 }
166 return -1;
167 }
168 if ((x < 0) | (y < 0) ||
169 (x >= scanlen(&ncp->res)) | (y >= numscans(&ncp->res))) {
170 if (ncp->hdrflags & HF_STDERR) {
171 fputs(ncp->inpname, stderr);
172 fputs(": warning - pixel index off map\n", stderr);
173 }
174 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 if (ncp->hdrflags & HF_STDERR) {
181 fputs(ncp->inpname, stderr);
182 fputs(": seek error\n", stderr);
183 }
184 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 }