ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapio.c
Revision: 2.12
Committed: Thu Aug 2 18:33:49 2018 UTC (5 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad5R3
Changes since 2.11: +3 -3 lines
Log Message:
Created MAXFMTLEN to guard against buffer overrun attacks in header input

File Contents

# User Rev Content
1 greg 2.6 #ifndef lint
2 greg 2.12 static const char RCSid[] = "$Id: pmapio.c,v 2.11 2018/02/08 19:55:02 rschregle Exp $";
3 greg 2.6 #endif
4 rschregle 2.9
5 greg 2.1 /*
6 rschregle 2.9 ======================================================================
7 greg 2.1 Photon map file I/O
8    
9     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10     (c) Fraunhofer Institute for Solar Energy Systems,
11 rschregle 2.2 (c) Lucerne University of Applied Sciences and Arts,
12 rschregle 2.9 supported by the Swiss National Science Foundation (SNSF, #147053)
13     ======================================================================
14 greg 2.1
15 greg 2.12 $Id: pmapio.c,v 2.11 2018/02/08 19:55:02 rschregle Exp $
16 greg 2.1 */
17    
18    
19    
20     #include "pmapio.h"
21     #include "pmapdiag.h"
22     #include "resolu.h"
23    
24    
25    
26     void savePhotonMap (const PhotonMap *pmap, const char *fname,
27 greg 2.5 int argc, char **argv)
28 greg 2.1 {
29 rschregle 2.9 unsigned long i, j;
30     FILE *file;
31 greg 2.1
32 rschregle 2.9 if (!pmap || !pmap -> numPhotons || !validPmapType(pmap -> type)) {
33 greg 2.1 error(INTERNAL, "attempt to save empty or invalid photon map");
34     return;
35     }
36    
37 rschregle 2.10 if (verbose) {
38 rschregle 2.9 if (pmap -> numPrimary)
39 rschregle 2.10 sprintf(errmsg, "Saving %s (%ld photons, %d primaries)\n",
40 rschregle 2.9 fname, pmap -> numPhotons, pmap -> numPrimary);
41 rschregle 2.10 else sprintf(errmsg, "Saving %s (%ld photons)\n", fname,
42 rschregle 2.9 pmap -> numPhotons);
43    
44 greg 2.1 eputs(errmsg);
45     fflush(stderr);
46     }
47    
48     if (!(file = fopen(fname, "wb"))) {
49     sprintf(errmsg, "can't open photon map file %s", fname);
50     error(SYSTEM, errmsg);
51     }
52    
53     /* Write header */
54     newheader("RADIANCE", file);
55    
56     /* Write command line */
57     printargs(argc, argv, file);
58    
59     /* Include statistics in info text */
60 rschregle 2.9 fprintf(file, "NumPhotons\t= %ld\n"
61     "AvgFlux\t\t= [%.2e, %.2e, %.2e]\n"
62     "Bbox\t\t= [%.3f, %.3f, %.3f] [%.3f, %.3f, %.3f]\n"
63     "CoG\t\t= [%.3f, %.3f, %.3f]\n"
64     "MaxDist^2\t= %.3f\n",
65     pmap -> numPhotons, pmap -> photonFlux [0],
66 greg 2.1 pmap -> photonFlux [1], pmap -> photonFlux [2],
67     pmap -> minPos [0], pmap -> minPos [1], pmap -> minPos [2],
68 rschregle 2.9 pmap -> maxPos [0], pmap -> maxPos [1], pmap -> maxPos [2],
69     pmap -> CoG [0], pmap -> CoG [1], pmap -> CoG [2],
70     pmap -> CoGdist);
71    
72     if (pmap -> primaries)
73     fprintf(file, "%d primary rays\n", pmap -> numPrimary);
74 greg 2.1
75     /* Write format */
76 greg 2.5 fputformat((char*)pmapFormat [pmap -> type], file);
77 rschregle 2.9 fprintf(file, "VERSION=%s\n", PMAP_FILEVER);
78 greg 2.1
79     /* Empty line = end of header */
80     putc('\n', file);
81    
82     /* Write file format version */
83 rschregle 2.9 putstr(PMAP_FILEVER, file);
84 greg 2.1
85     /* Write number of photons */
86 rschregle 2.9 putint(pmap -> numPhotons, sizeof(pmap -> numPhotons), file);
87 greg 2.1
88     /* Write average photon flux */
89     for (j = 0; j < 3; j++)
90     putflt(pmap -> photonFlux [j], file);
91    
92     /* Write max and min photon positions */
93     for (j = 0; j < 3; j++) {
94     putflt(pmap -> minPos [j], file);
95     putflt(pmap -> maxPos [j], file);
96     }
97    
98     /* Write centre of gravity */
99     for (j = 0; j < 3; j++)
100     putflt(pmap -> CoG [j], file);
101    
102     /* Write avg distance to centre of gravity */
103     putflt(pmap -> CoGdist, file);
104    
105     /* Write out primary photon rays (or just zero count if none) */
106 rschregle 2.9 if (pmap -> primaries) {
107     putint(pmap -> numPrimary, sizeof(pmap -> numPrimary), file);
108 greg 2.1
109 rschregle 2.9 for (i = 0; i < pmap -> numPrimary; i++) {
110     PhotonPrimary *prim = pmap -> primaries + i;
111    
112 greg 2.1 putint(prim -> srcIdx, sizeof(prim -> srcIdx), file);
113 rschregle 2.11 #ifdef PMAP_PRIMARYDIR
114 greg 2.4 putint(prim -> dir, sizeof(prim -> dir), file);
115 rschregle 2.11 #endif
116 rschregle 2.9 #ifdef PMAP_PRIMARYPOS
117 greg 2.1 for (j = 0; j < 3; j++)
118 greg 2.3 putflt(prim -> pos [j], file);
119 rschregle 2.9 #endif
120 greg 2.1 if (ferror(file))
121     error(SYSTEM, "error writing primary photon rays");
122     }
123     }
124 rschregle 2.9 else putint(0, sizeof(pmap -> numPrimary), file);
125    
126     /* Save photon storage */
127     #ifdef PMAP_OOC
128     if (OOC_SavePhotons(pmap, file)) {
129     #else
130     if (kdT_SavePhotons(pmap, file)) {
131     #endif
132     sprintf(errmsg, "error writing photon map file %s", fname);
133     error(SYSTEM, errmsg);
134     }
135 greg 2.1
136     fclose(file);
137     }
138    
139    
140    
141     PhotonMapType loadPhotonMap (PhotonMap *pmap, const char *fname)
142     {
143 rschregle 2.9 PhotonMapType ptype = PMAP_TYPE_NONE;
144 greg 2.12 char format [MAXFMTLEN];
145 rschregle 2.9 unsigned long i, j;
146     FILE *file;
147 greg 2.1
148     if (!pmap)
149     return PMAP_TYPE_NONE;
150    
151     if ((file = fopen(fname, "rb")) == NULL) {
152     sprintf(errmsg, "can't open photon map file %s", fname);
153     error(SYSTEM, errmsg);
154     }
155    
156     /* Get format string */
157     strcpy(format, PMAP_FORMAT_GLOB);
158     if (checkheader(file, format, NULL) != 1) {
159     sprintf(errmsg, "photon map file %s has unknown format %s",
160     fname, format);
161     error(USER, errmsg);
162     }
163    
164     /* Identify photon map type from format string */
165     for (ptype = 0;
166 rschregle 2.8 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
167 greg 2.1 ptype++);
168    
169     if (!validPmapType(ptype)) {
170     sprintf(errmsg, "file %s contains an unknown photon map type", fname);
171     error(USER, errmsg);
172     }
173    
174     initPhotonMap(pmap, ptype);
175    
176     /* Get file format version and check for compatibility */
177 rschregle 2.9 if (strcmp(getstr(format, file), PMAP_FILEVER))
178 greg 2.1 error(USER, "incompatible photon map file format");
179    
180     /* Get number of photons */
181 rschregle 2.9 pmap -> numPhotons = getint(sizeof(pmap -> numPhotons), file);
182 greg 2.1
183     /* Get average photon flux */
184     for (j = 0; j < 3; j++)
185     pmap -> photonFlux [j] = getflt(file);
186    
187     /* Get max and min photon positions */
188     for (j = 0; j < 3; j++) {
189     pmap -> minPos [j] = getflt(file);
190     pmap -> maxPos [j] = getflt(file);
191     }
192    
193     /* Get centre of gravity */
194     for (j = 0; j < 3; j++)
195     pmap -> CoG [j] = getflt(file);
196    
197     /* Get avg distance to centre of gravity */
198     pmap -> CoGdist = getflt(file);
199    
200     /* Get primary photon rays */
201 rschregle 2.9 pmap -> numPrimary = getint(sizeof(pmap -> numPrimary), file);
202 greg 2.1
203 rschregle 2.9 if (pmap -> numPrimary) {
204     pmap -> primaries = calloc(pmap -> numPrimary, sizeof(PhotonPrimary));
205     if (!pmap -> primaries)
206 greg 2.1 error(INTERNAL, "can't allocate primary photon rays");
207    
208 rschregle 2.9 for (i = 0; i < pmap -> numPrimary; i++) {
209     PhotonPrimary *prim = pmap -> primaries + i;
210 greg 2.1
211     prim -> srcIdx = getint(sizeof(prim -> srcIdx), file);
212 rschregle 2.11 #ifdef PMAP_PRIMARYDIR
213 greg 2.4 prim -> dir = getint(sizeof(prim -> dir), file);
214 rschregle 2.11 #endif
215 rschregle 2.9 #ifdef PMAP_PRIMARYPOS
216 greg 2.1 for (j = 0; j < 3; j++)
217 greg 2.3 prim -> pos [j] = getflt(file);
218 rschregle 2.9 #endif
219 greg 2.1 if (feof(file))
220     error(SYSTEM, "error reading primary photon rays");
221     }
222 rschregle 2.9 }
223    
224     /* Load photon storage */
225     #ifdef PMAP_OOC
226     if (OOC_LoadPhotons(pmap, file)) {
227     #else
228     if (kdT_LoadPhotons(pmap, file)) {
229     #endif
230     sprintf(errmsg, "error reading photon map file %s", fname);
231     error(SYSTEM, errmsg);
232 greg 2.1 }
233 rschregle 2.9
234 greg 2.1 fclose(file);
235     return ptype;
236     }