ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.12
Committed: Mon Jun 30 14:59:12 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.11: +9 -6 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rhoptimize.c,v 3.11 2003/06/13 15:27:04 greg Exp $";
3 #endif
4 /*
5 * Optimize holodeck for quick access.
6 *
7 * 11/4/98 Greg Ward Larson
8 */
9
10 #include <signal.h>
11 #include <string.h>
12 #ifdef _WIN32
13 #include <process.h> /* getpid() */
14 #endif
15
16 #include "holo.h"
17
18 #ifndef BKBSIZE
19 #define BKBSIZE 256 /* beam clump size (kilobytes) */
20 #endif
21
22 char *progname;
23 char tempfile[128];
24 int dupchecking = 0;
25
26 extern long rhinitcopy();
27
28
29 main(argc, argv)
30 int argc;
31 char *argv[];
32 {
33 char *inpname, *outname;
34 int hdfd[2];
35 long nextipos, lastopos, thisopos;
36
37 progname = argv[0];
38 argv++; argc--; /* duplicate checking flag? */
39 if (argc > 1 && !strcmp(argv[0], "-u")) {
40 dupchecking++;
41 argv++; argc--;
42 }
43 if (argc < 1 | argc > 2) {
44 fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
45 progname);
46 exit(1);
47 }
48 inpname = argv[0]; /* get input file */
49 argv++; argc--;
50 if (argc == 1) /* use given output file */
51 outname = argv[0];
52 else { /* else use temporary file */
53 if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */
54 sprintf(errmsg, "cannot access \"%s\"", inpname);
55 error(SYSTEM, errmsg);
56 }
57 strcpy(tempfile, inpname);
58 if ((outname = strrchr(tempfile, '/')) != NULL)
59 outname++;
60 else
61 outname = tempfile;
62 sprintf(outname, "rho%d.hdk", getpid());
63 outname = tempfile;
64 }
65 /* copy holodeck file header */
66 nextipos = rhinitcopy(hdfd, inpname, outname);
67 lastopos = 0L; /* copy sections one by one */
68 while (nextipos != 0L) {
69 /* set input position; get next */
70 lseek(hdfd[0], (off_t)nextipos, 0);
71 read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
72 /* get output position; set last */
73 thisopos = lseek(hdfd[1], (off_t)0, 2);
74 if (lastopos > 0L) {
75 lseek(hdfd[1], (off_t)lastopos, 0);
76 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
77 lseek(hdfd[1], (off_t)0, 2);
78 }
79 lastopos = thisopos;
80 thisopos = 0L; /* write place holder */
81 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
82 /* copy holodeck section */
83 copysect(hdfd[0], hdfd[1]);
84 }
85 /* clean up */
86 close(hdfd[0]);
87 close(hdfd[1]);
88 if (outname == tempfile && rename(outname, inpname) < 0) {
89 sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
90 outname, inpname);
91 error(SYSTEM, errmsg);
92 }
93 exit(0);
94 }
95
96
97 long
98 rhinitcopy(hfd, infn, outfn) /* open files and copy header */
99 int hfd[2]; /* returned file descriptors */
100 char *infn, *outfn;
101 {
102 FILE *infp, *outfp;
103 long ifpos;
104 /* open files for i/o */
105 if ((infp = fopen(infn, "r")) == NULL) {
106 sprintf(errmsg, "cannot open \"%s\" for reading", infn);
107 error(SYSTEM, errmsg);
108 }
109 if (access(outfn, F_OK) == 0) {
110 sprintf(errmsg, "output file \"%s\" already exists!", outfn);
111 error(USER, errmsg);
112 }
113 if ((outfp = fopen(outfn, "w+")) == NULL) {
114 sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
115 error(SYSTEM, errmsg);
116 }
117 /* set up signal handling */
118 if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN);
119 if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN);
120 if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN);
121 #ifdef SIGXCPU
122 if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN);
123 if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN);
124 #endif
125 /* copy and verify header */
126 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
127 error(USER, "input not in holodeck format");
128 fputformat(HOLOFMT, outfp);
129 fputc('\n', outfp);
130 putw(HOLOMAGIC, outfp);
131 /* get descriptors and free stdio */
132 if ((hfd[0] = dup(fileno(infp))) < 0 ||
133 (hfd[1] = dup(fileno(outfp))) < 0)
134 error(SYSTEM, "dup call failed in rhinitcopy");
135 ifpos = ftell(infp);
136 fclose(infp);
137 if (fclose(outfp) == EOF)
138 error(SYSTEM, "file flushing error in rhinitcopy");
139 /* check cache size */
140 if (BKBSIZE*1024*1.5 > hdcachesize)
141 hdcachesize = BKBSIZE*1024*1.5;
142 /* return input position */
143 return(ifpos);
144 }
145
146
147 int
148 nuniq(rva, n) /* sort unique rays to front of beam list */
149 register RAYVAL *rva;
150 int n;
151 {
152 register int i, j;
153 RAYVAL rtmp;
154
155 for (j = 0; j < n; j++)
156 for (i = j+1; i < n; i++)
157 if ( rva[i].d == rva[j].d &&
158 rva[i].r[0][0]==rva[j].r[0][0] &&
159 rva[i].r[0][1]==rva[j].r[0][1] &&
160 rva[i].r[1][0]==rva[j].r[1][0] &&
161 rva[i].r[1][1]==rva[j].r[1][1] ) {
162 n--; /* swap duplicate with end */
163 copystruct(&rtmp, rva+n);
164 copystruct(rva+n, rva+i);
165 copystruct(rva+i, &rtmp);
166 i--; /* recheck one we swapped */
167 }
168 return(n);
169 }
170
171
172 static BEAMI *beamdir;
173
174 static int
175 bpcmp(b1p, b2p) /* compare beam positions on disk */
176 int *b1p, *b2p;
177 {
178 register off_t pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
179
180 if (pdif < 0L) return(-1);
181 return(pdif > 0L);
182 }
183
184 static HOLO *hout;
185
186 static int
187 xferclump(hp, bq, nb) /* transfer the given clump to hout and free */
188 HOLO *hp;
189 int *bq, nb;
190 {
191 register int i;
192 register BEAM *bp;
193 int n;
194
195 beamdir = hp->bi; /* sort based on file position */
196 qsort((void *)bq, nb, sizeof(*bq), bpcmp);
197 /* transfer and free each beam */
198 for (i = 0; i < nb; i++) {
199 bp = hdgetbeam(hp, bq[i]);
200 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
201 n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
202 memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp),
203 n*sizeof(RAYVAL));
204 hdfreebeam(hp, bq[i]);
205 }
206 hdfreebeam(hout, 0); /* write & free clump */
207 return(0);
208 }
209
210 copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
211 int ifd, ofd;
212 {
213 HOLO *hinp;
214 /* load input section directory */
215 hinp = hdinit(ifd, NULL);
216 /* create output section directory */
217 hout = hdinit(ofd, (HDGRID *)hinp);
218 /* clump the beams */
219 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
220 /* clean up */
221 hddone(hinp);
222 hddone(hout);
223 }
224
225
226 void
227 eputs(s) /* put error message to stderr */
228 register char *s;
229 {
230 static int midline = 0;
231
232 if (!*s)
233 return;
234 if (!midline++) { /* prepend line with program name */
235 fputs(progname, stderr);
236 fputs(": ", stderr);
237 }
238 fputs(s, stderr);
239 if (s[strlen(s)-1] == '\n') {
240 fflush(stderr);
241 midline = 0;
242 }
243 }
244
245
246 void
247 quit(code) /* exit the program gracefully */
248 int code;
249 {
250 if (tempfile[0])
251 unlink(tempfile);
252 exit(code);
253 }