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 (20 months, 1 week 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.8 static const char RCSid[] = "$Id: normcodec.c,v 2.7 2022/08/24 19:55:58 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.8 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 greg 2.1 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 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
73     fputs(ncp->inpname, stderr);
74     fputs(": bad header\n", stderr);
75     }
76     return 0;
77 greg 2.1 }
78 greg 2.6 /* get resolution string? */
79 greg 2.8 if (ncp->hdrflags & HF_RESIN &&
80     (ncp->res.xr <= 0) | (ncp->res.yr <= 0) &&
81     !fgetsresolu(&ncp->res, ncp->finp)) {
82 greg 2.6 if (ncp->hdrflags & HF_STDERR) {
83     fputs(ncp->inpname, stderr);
84     fputs(": bad resolution string\n", stderr);
85     }
86     return 0;
87     }
88 greg 2.1 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 greg 2.6 } 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 greg 2.1 switch (ncp->format) {
102     case 'a':
103     fputformat("ascii", stdout);
104     break;
105     case 'f':
106 greg 2.3 fputendian(stdout);
107 greg 2.1 fputformat("float", stdout);
108     break;
109     case 'd':
110 greg 2.3 fputendian(stdout);
111 greg 2.1 fputformat("double", stdout);
112     break;
113     }
114 greg 2.6 }
115 greg 2.1 fputc('\n', stdout);
116     }
117 greg 2.6 if (ncp->hdrflags & HF_RESOUT) /* put resolution string? */
118 greg 2.1 fputsresolu(&ncp->res, stdout);
119    
120 greg 2.7 ncp->dstart = ftell(ncp->finp);
121 greg 2.1 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 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
131     fputs(progname, stderr);
132     fputs(": wrong header mode for decode\n", stderr);
133     }
134 greg 2.1 return 0;
135     }
136     if (ncp->inpfmt[0] && strcmp(ncp->inpfmt, NORMAL32FMT)) {
137 greg 2.2 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 greg 2.1 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 greg 2.5 static int32 lastc;
154     static FVECT lastv;
155     int32 c = getint(4, ncp->finp);
156 greg 2.1
157     if (c == EOF && feof(ncp->finp))
158     return -1;
159    
160 greg 2.4 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 greg 2.1 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 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
179     fputs(progname, stderr);
180     fputs(": need map resolution to seek\n", stderr);
181     }
182 greg 2.1 return -1;
183     }
184     if ((x < 0) | (y < 0) ||
185     (x >= scanlen(&ncp->res)) | (y >= numscans(&ncp->res))) {
186 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
187     fputs(ncp->inpname, stderr);
188     fputs(": warning - pixel index off map\n", stderr);
189     }
190 greg 2.1 return 0;
191     }
192 greg 2.7 if (fseek(ncp->finp, ncp->dstart + 4*((long)y*scanlen(&ncp->res) + x),
193     SEEK_SET) == EOF) {
194 greg 2.2 if (ncp->hdrflags & HF_STDERR) {
195     fputs(ncp->inpname, stderr);
196     fputs(": seek error\n", stderr);
197     }
198 greg 2.1 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     }