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, 9 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.3 static const char RCSid[] = "$Id: idmap.c,v 2.2 2019/07/23 17:20:20 greg Exp $";
3 greg 2.1 #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 greg 2.2 /* Read the next ID index from input */
138     int
139     idmap_next_i(IDMAP *idmp)
140 greg 2.1 {
141     int ndx = getint(idmp->bytespi, idmp->finp);
142    
143     if (ndx == EOF && feof(idmp->finp))
144 greg 2.2 return -1;
145 greg 2.1
146     idmp->curpos += idmp->bytespi;
147    
148     ndx &= (1<<(idmp->bytespi<<3)) - 1; /* undo sign extension */
149    
150 greg 2.2 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 greg 2.1 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     }