ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/normcodec.c
Revision: 2.8
Committed: Thu Sep 22 21:45:28 2022 UTC (19 months, 3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +22 -2 lines
Log Message:
feat(rcode_depth,rcode_norm): Allow NROWS,NCOLS in header rather than res string

File Contents

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