ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/idmap.c
Revision: 2.1
Committed: Fri Jul 19 22:25:03 2019 UTC (4 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Created rcode_ident file to create indexed identifier files

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
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 from input */
138 const char *
139 idmap_next(IDMAP *idmp)
140 {
141 int ndx = getint(idmp->bytespi, idmp->finp);
142
143 if (ndx == EOF && feof(idmp->finp))
144 return NULL;
145
146 idmp->curpos += idmp->bytespi;
147
148 ndx &= (1<<(idmp->bytespi<<3)) - 1; /* undo sign extension */
149
150 return mapID(idmp, ndx);
151 }
152
153
154 /* Seek to a specific pixel position in ID map */
155 int
156 idmap_seek(IDMAP *idmp, int x, int y)
157 {
158 long seekto;
159
160 if ((x < 0) | (y < 0) | (x >= idmp->res.xr) | (y >= idmp->res.yr))
161 return 0;
162
163 seekto = idmp->dstart + ((long)y*idmp->res.xr + x)*idmp->bytespi;
164
165 if (seekto != idmp->curpos && fseek(idmp->finp, seekto, SEEK_SET) < 0)
166 return -1;
167
168 idmp->curpos = seekto;
169
170 return 1;
171 }
172
173
174 /* Read ID at a pixel position */
175 const char *
176 idmap_pix(IDMAP *idmp, int x, int y)
177 {
178 if (idmap_seek(idmp, x, y) <= 0)
179 return NULL;
180
181 return idmap_next(idmp);
182 }
183
184
185 /* Close ID map and free resources */
186 void
187 idmap_close(IDMAP *idmp)
188 {
189 fclose(idmp->finp);
190 free(idmp->idoffset);
191 free(idmp);
192 }