ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.18
Committed: Thu Jan 1 11:21:55 2004 UTC (20 years, 3 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 3.17: +41 -22 lines
Log Message:
Ansification and prototypes.

File Contents

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