ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/idmap.c
Revision: 2.3
Committed: Fri Jul 26 16:18:07 2019 UTC (4 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.2: +1 -1 lines
State: FILE REMOVED
Log Message:
Moved rcode map support to common directory

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: idmap.c,v 2.2 2019/07/23 17:20:20 greg Exp $";
3 #endif
4 /*
5 * Routines for loading identifier maps
6 *
7 */
8
9 #include <stdlib.h>
10 #include "platform.h"
11 #include "rtio.h"
12 #include "idmap.h"
13
14
15 /* Open ID map file for reading, copying info to stdout based on hflags */
16 IDMAP *
17 idmap_ropen(const char *fname, int hflags)
18 {
19 IDMAP idinit, *idmp = NULL;
20 char infmt[MAXFMTLEN];
21 int gotfmt;
22 int tablength;
23 int i;
24
25 if (!fname || !*fname)
26 return NULL;
27
28 memset(&idinit, 0, sizeof(IDMAP));
29
30 idinit.finp = fopen(fname, "rb");
31
32 if (!idinit.finp) {
33 fputs(fname, stderr);
34 fputs(": cannot open for reading\n", stderr);
35 return NULL;
36 }
37 SET_FILE_BINARY(idinit.finp);
38 #ifdef getc_unlocked /* avoid stupid semaphores */
39 flockfile(idinit.finp);
40 #endif
41 strcpy(infmt, IDMAPFMT); /* read/copy header */
42 gotfmt = checkheader(idinit.finp, infmt,
43 (hflags & HF_HEADOUT) ? stdout : (FILE *)NULL);
44 if (gotfmt <= 0) {
45 fputs(fname, stderr);
46 fputs(": bad or missing header format\n", stderr);
47 fclose(idinit.finp);
48 return NULL;
49 }
50 if (hflags & HF_HEADOUT) {
51 fputformat("ascii", stdout);
52 fputc('\n', stdout);
53 }
54 switch (atoi(infmt)) { /* get index size */
55 case 8:
56 idinit.bytespi = 1;
57 break;
58 case 16:
59 idinit.bytespi = 2;
60 break;
61 case 24:
62 idinit.bytespi = 3;
63 break;
64 default:
65 fputs(fname, stderr);
66 fputs(": unsupported index size: ", stderr);
67 fputs(infmt, stderr);
68 fputc('\n', stderr);
69 fclose(idinit.finp);
70 return NULL;
71 }
72 /* get/copy resolution string */
73 if (!fgetsresolu(&idinit.res, idinit.finp)) {
74 fputs(fname, stderr);
75 fputs(": missing map resolution\n", stderr);
76 fclose(idinit.finp);
77 return NULL;
78 }
79 if (hflags & HF_RESOUT)
80 fputsresolu(&idinit.res, stdout);
81 /* set up identifier table */
82 idinit.dstart = ftell(idinit.finp);
83 if (fseek(idinit.finp, 0, SEEK_END) < 0)
84 goto seekerr;
85 tablength = ftell(idinit.finp) - idinit.dstart -
86 (long)idinit.res.xr*idinit.res.yr*idinit.bytespi;
87 if (tablength < 2) {
88 fputs(fname, stderr);
89 fputs(": truncated file\n", stderr);
90 fclose(idinit.finp);
91 return NULL;
92 }
93 /* allocate and load table */
94 idmp = (IDMAP *)malloc(sizeof(IDMAP)+tablength);
95 if (idmp == NULL) {
96 fputs("Out of memory allocating ID table!\n", stderr);
97 fclose(idinit.finp);
98 return NULL;
99 }
100 *idmp = idinit; /* initialize allocated struct */
101 idmp->idtable[tablength] = '\0';
102 if (fseek(idmp->finp, -tablength, SEEK_END) < 0)
103 goto seekerr;
104 if (fread(idmp->idtable, 1, tablength, idmp->finp) != tablength) {
105 fputs(fname, stderr);
106 fputs(": error reading identifier table\n", stderr);
107 fclose(idmp->finp);
108 free(idmp);
109 return NULL;
110 }
111 if (fseek(idmp->finp, idmp->curpos = idmp->dstart, SEEK_SET) < 0)
112 goto seekerr;
113 while (tablength > 0) /* create index */
114 idmp->nids += !idmp->idtable[--tablength];
115 idmp->idoffset = (int *)malloc(sizeof(int)*idmp->nids);
116 if (!idmp->idoffset) {
117 fputs("Out of memory in idmap_ropen!\n", stderr);
118 fclose(idmp->finp);
119 free(idmp);
120 return NULL;
121 }
122 for (i = 0; i < idmp->nids; i++) {
123 idmp->idoffset[i] = tablength;
124 while (idmp->idtable[tablength++])
125 ;
126 }
127 return idmp;
128 seekerr:
129 fputs(fname, stderr);
130 fputs(": cannot seek on file\n", stderr);
131 fclose(idinit.finp);
132 if (idmp) free(idmp);
133 return NULL;
134 }
135
136
137 /* Read the next ID index from input */
138 int
139 idmap_next_i(IDMAP *idmp)
140 {
141 int ndx = getint(idmp->bytespi, idmp->finp);
142
143 if (ndx == EOF && feof(idmp->finp))
144 return -1;
145
146 idmp->curpos += idmp->bytespi;
147
148 ndx &= (1<<(idmp->bytespi<<3)) - 1; /* undo sign extension */
149
150 return ndx;
151 }
152
153
154 /* Read the next ID from input */
155 const char *
156 idmap_next(IDMAP *idmp)
157 {
158 int ndx = idmap_next_i(idmp);
159
160 if (ndx < 0)
161 return NULL;
162
163 return mapID(idmp, ndx);
164 }
165
166
167 /* Seek to a specific pixel position in ID map */
168 int
169 idmap_seek(IDMAP *idmp, int x, int y)
170 {
171 long seekto;
172
173 if ((x < 0) | (y < 0) | (x >= idmp->res.xr) | (y >= idmp->res.yr))
174 return 0;
175
176 seekto = idmp->dstart + ((long)y*idmp->res.xr + x)*idmp->bytespi;
177
178 if (seekto != idmp->curpos && fseek(idmp->finp, seekto, SEEK_SET) < 0)
179 return -1;
180
181 idmp->curpos = seekto;
182
183 return 1;
184 }
185
186
187 /* Read ID at a pixel position */
188 const char *
189 idmap_pix(IDMAP *idmp, int x, int y)
190 {
191 if (idmap_seek(idmp, x, y) <= 0)
192 return NULL;
193
194 return idmap_next(idmp);
195 }
196
197
198 /* Close ID map and free resources */
199 void
200 idmap_close(IDMAP *idmp)
201 {
202 fclose(idmp->finp);
203 free(idmp->idoffset);
204 free(idmp);
205 }