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

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 schorsch 3.12 static const char RCSid[] = "$Id: rhoptimize.c,v 3.11 2003/06/13 15:27:04 greg Exp $";
3 gwlarson 3.1 #endif
4     /*
5     * Optimize holodeck for quick access.
6     *
7     * 11/4/98 Greg Ward Larson
8     */
9    
10 schorsch 3.12 #include <signal.h>
11     #include <string.h>
12     #ifdef _WIN32
13     #include <process.h> /* getpid() */
14     #endif
15    
16 gwlarson 3.1 #include "holo.h"
17    
18     #ifndef BKBSIZE
19 gwlarson 3.2 #define BKBSIZE 256 /* beam clump size (kilobytes) */
20 gwlarson 3.1 #endif
21    
22     char *progname;
23 gwlarson 3.3 char tempfile[128];
24 gwlarson 3.6 int dupchecking = 0;
25 gwlarson 3.1
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 gwlarson 3.6 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 gwlarson 3.1 exit(1);
47     }
48 gwlarson 3.6 inpname = argv[0]; /* get input file */
49     argv++; argc--;
50     if (argc == 1) /* use given output file */
51     outname = argv[0];
52 gwlarson 3.3 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 schorsch 3.12 if ((outname = strrchr(tempfile, '/')) != NULL)
59 gwlarson 3.1 outname++;
60     else
61 gwlarson 3.3 outname = tempfile;
62 gwlarson 3.1 sprintf(outname, "rho%d.hdk", getpid());
63 gwlarson 3.3 outname = tempfile;
64 gwlarson 3.1 }
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 greg 3.8 lseek(hdfd[0], (off_t)nextipos, 0);
71 gwlarson 3.1 read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
72     /* get output position; set last */
73 greg 3.11 thisopos = lseek(hdfd[1], (off_t)0, 2);
74 gwlarson 3.1 if (lastopos > 0L) {
75 greg 3.8 lseek(hdfd[1], (off_t)lastopos, 0);
76 gwlarson 3.1 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
77 greg 3.11 lseek(hdfd[1], (off_t)0, 2);
78 gwlarson 3.1 }
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 gwlarson 3.3 if (outname == tempfile && rename(outname, inpname) < 0) {
89 gwlarson 3.1 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 greg 3.8 if (access(outfn, F_OK) == 0) {
110     sprintf(errmsg, "output file \"%s\" already exists!", outfn);
111     error(USER, errmsg);
112     }
113 gwlarson 3.1 if ((outfp = fopen(outfn, "w+")) == NULL) {
114     sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
115     error(SYSTEM, errmsg);
116     }
117 gwlarson 3.3 /* 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 gwlarson 3.1 /* copy and verify header */
126 gwlarson 3.3 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
127 gwlarson 3.1 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 gwlarson 3.4 /* check cache size */
140     if (BKBSIZE*1024*1.5 > hdcachesize)
141     hdcachesize = BKBSIZE*1024*1.5;
142 gwlarson 3.1 /* return input position */
143     return(ifpos);
144     }
145    
146    
147 gwlarson 3.6 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 gwlarson 3.5 static BEAMI *beamdir;
173 gwlarson 3.1
174 gwlarson 3.4 static int
175 gwlarson 3.5 bpcmp(b1p, b2p) /* compare beam positions on disk */
176     int *b1p, *b2p;
177 gwlarson 3.1 {
178 greg 3.10 register off_t pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
179 gwlarson 3.5
180     if (pdif < 0L) return(-1);
181 gwlarson 3.6 return(pdif > 0L);
182 gwlarson 3.2 }
183    
184 gwlarson 3.5 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 gwlarson 3.6 int n;
194 gwlarson 3.5
195     beamdir = hp->bi; /* sort based on file position */
196 greg 3.9 qsort((void *)bq, nb, sizeof(*bq), bpcmp);
197 gwlarson 3.5 /* transfer and free each beam */
198     for (i = 0; i < nb; i++) {
199     bp = hdgetbeam(hp, bq[i]);
200 gwlarson 3.6 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
201     n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
202 schorsch 3.12 memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp),
203 gwlarson 3.6 n*sizeof(RAYVAL));
204 gwlarson 3.5 hdfreebeam(hp, bq[i]);
205     }
206 gwlarson 3.7 hdfreebeam(hout, 0); /* write & free clump */
207 gwlarson 3.5 return(0);
208     }
209    
210 gwlarson 3.1 copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
211     int ifd, ofd;
212     {
213 gwlarson 3.4 HOLO *hinp;
214 gwlarson 3.1 /* load input section directory */
215     hinp = hdinit(ifd, NULL);
216     /* create output section directory */
217     hout = hdinit(ofd, (HDGRID *)hinp);
218 gwlarson 3.4 /* clump the beams */
219 gwlarson 3.5 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
220 gwlarson 3.4 /* clean up */
221 gwlarson 3.1 hddone(hinp);
222     hddone(hout);
223     }
224    
225    
226 greg 3.8 void
227 gwlarson 3.1 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 greg 3.8 void
247 gwlarson 3.1 quit(code) /* exit the program gracefully */
248     int code;
249     {
250 gwlarson 3.3 if (tempfile[0])
251     unlink(tempfile);
252 gwlarson 3.1 exit(code);
253     }