ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.21
Committed: Mon Mar 7 01:15:01 2016 UTC (8 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R1
Changes since 3.20: +7 -1 lines
Log Message:
Enable SCons windows build

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rhoptimize.c,v 3.20 2010/09/30 15:43:30 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 off_t 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 = 0; /* copy sections one by one */
76 while (nextipos != 0L) {
77 /* set input position; get next */
78 lseek(hdfd[0], 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 > 0) {
83 lseek(hdfd[1], 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 = 0; /* 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 #ifdef SIGINT
129 if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN);
130 #endif
131 #ifdef SIGHUP
132 if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN);
133 #endif
134 #ifdef SIGTERM
135 if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN);
136 #endif
137 #ifdef SIGXCPU
138 if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN);
139 if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN);
140 #endif
141 /* copy and verify header */
142 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
143 error(USER, "input not in holodeck format");
144 fputformat(HOLOFMT, outfp);
145 fputc('\n', outfp);
146 putw(HOLOMAGIC, outfp);
147 /* get descriptors and free stdio */
148 if ((hfd[0] = dup(fileno(infp))) < 0 ||
149 (hfd[1] = dup(fileno(outfp))) < 0)
150 error(SYSTEM, "dup call failed in rhinitcopy");
151 ifpos = ftell(infp);
152 fclose(infp);
153 if (fclose(outfp) == EOF)
154 error(SYSTEM, "file flushing error in rhinitcopy");
155 /* check cache size */
156 if (BKBSIZE*1024*1.5 > hdcachesize)
157 hdcachesize = BKBSIZE*1024*1.5;
158 /* return input position */
159 return(ifpos);
160 }
161
162
163 static int
164 nuniq( /* sort unique rays to front of beam list */
165 register RAYVAL *rva,
166 int n
167 )
168 {
169 register int i, j;
170 RAYVAL rtmp;
171
172 for (j = 0; j < n; j++)
173 for (i = j+1; i < n; i++)
174 if ( rva[i].d == rva[j].d &&
175 rva[i].r[0][0]==rva[j].r[0][0] &&
176 rva[i].r[0][1]==rva[j].r[0][1] &&
177 rva[i].r[1][0]==rva[j].r[1][0] &&
178 rva[i].r[1][1]==rva[j].r[1][1] ) {
179 n--; /* swap duplicate with end */
180 rtmp = *(rva+n);
181 *(rva+n) = *(rva+i);
182 *(rva+i) = rtmp;
183 i--; /* recheck one we swapped */
184 }
185 return(n);
186 }
187
188
189 static BEAMI *beamdir;
190
191 static int
192 bpcmp( /* compare beam positions on disk */
193 const void *b1p,
194 const void *b2p
195 )
196 {
197 register off_t pdif = beamdir[*(int*)b1p].fo - beamdir[*(int*)b2p].fo;
198
199 if (pdif < 0L) return(-1);
200 return(pdif > 0L);
201 }
202
203 static HOLO *hout;
204
205 static int
206 xferclump( /* transfer the given clump to hout and free */
207 HOLO *hp,
208 int *bq,
209 int nb
210 )
211 {
212 register int i;
213 register BEAM *bp;
214 int n;
215
216 beamdir = hp->bi; /* sort based on file position */
217 qsort((void *)bq, nb, sizeof(*bq), bpcmp);
218 /* transfer and free each beam */
219 for (i = 0; i < nb; i++) {
220 bp = hdgetbeam(hp, bq[i]);
221 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
222 n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
223 memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp),
224 n*sizeof(RAYVAL));
225 hdfreebeam(hp, bq[i]);
226 }
227 hdfreebeam(hout, 0); /* write & free clump */
228 return(0);
229 }
230
231 static void
232 copysect( /* copy holodeck section from ifd to ofd */
233 int ifd,
234 int ofd
235 )
236 {
237 HOLO *hinp;
238 /* load input section directory */
239 hinp = hdinit(ifd, NULL);
240 /* create output section directory */
241 hout = hdinit(ofd, (HDGRID *)hinp);
242 /* clump the beams */
243 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
244 /* clean up */
245 hddone(hinp);
246 hddone(hout);
247 }
248
249
250 void
251 eputs(s) /* put error message to stderr */
252 register char *s;
253 {
254 static int midline = 0;
255
256 if (!*s)
257 return;
258 if (!midline++) { /* prepend line with program name */
259 fputs(progname, stderr);
260 fputs(": ", stderr);
261 }
262 fputs(s, stderr);
263 if (s[strlen(s)-1] == '\n') {
264 fflush(stderr);
265 midline = 0;
266 }
267 }
268
269
270 void
271 quit(code) /* exit the program gracefully */
272 int code;
273 {
274 if (tempfile[0])
275 unlink(tempfile);
276 exit(code);
277 }