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, 8 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pmapio.c,v 2.11 2018/02/08 19:55:02 rschregle Exp $";
3 #endif
4
5 /*
6 ======================================================================
7 Photon map file I/O
8
9 Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10 (c) Fraunhofer Institute for Solar Energy Systems,
11 (c) Lucerne University of Applied Sciences and Arts,
12 supported by the Swiss National Science Foundation (SNSF, #147053)
13 ======================================================================
14
15 $Id: pmapio.c,v 2.11 2018/02/08 19:55:02 rschregle Exp $
16 */
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 int argc, char **argv)
28 {
29 unsigned long i, j;
30 FILE *file;
31
32 if (!pmap || !pmap -> numPhotons || !validPmapType(pmap -> type)) {
33 error(INTERNAL, "attempt to save empty or invalid photon map");
34 return;
35 }
36
37 if (verbose) {
38 if (pmap -> numPrimary)
39 sprintf(errmsg, "Saving %s (%ld photons, %d primaries)\n",
40 fname, pmap -> numPhotons, pmap -> numPrimary);
41 else sprintf(errmsg, "Saving %s (%ld photons)\n", fname,
42 pmap -> numPhotons);
43
44 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 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 pmap -> photonFlux [1], pmap -> photonFlux [2],
67 pmap -> minPos [0], pmap -> minPos [1], pmap -> minPos [2],
68 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
75 /* Write format */
76 fputformat((char*)pmapFormat [pmap -> type], file);
77 fprintf(file, "VERSION=%s\n", PMAP_FILEVER);
78
79 /* Empty line = end of header */
80 putc('\n', file);
81
82 /* Write file format version */
83 putstr(PMAP_FILEVER, file);
84
85 /* Write number of photons */
86 putint(pmap -> numPhotons, sizeof(pmap -> numPhotons), file);
87
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 if (pmap -> primaries) {
107 putint(pmap -> numPrimary, sizeof(pmap -> numPrimary), file);
108
109 for (i = 0; i < pmap -> numPrimary; i++) {
110 PhotonPrimary *prim = pmap -> primaries + i;
111
112 putint(prim -> srcIdx, sizeof(prim -> srcIdx), file);
113 #ifdef PMAP_PRIMARYDIR
114 putint(prim -> dir, sizeof(prim -> dir), file);
115 #endif
116 #ifdef PMAP_PRIMARYPOS
117 for (j = 0; j < 3; j++)
118 putflt(prim -> pos [j], file);
119 #endif
120 if (ferror(file))
121 error(SYSTEM, "error writing primary photon rays");
122 }
123 }
124 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
136 fclose(file);
137 }
138
139
140
141 PhotonMapType loadPhotonMap (PhotonMap *pmap, const char *fname)
142 {
143 PhotonMapType ptype = PMAP_TYPE_NONE;
144 char format [MAXFMTLEN];
145 unsigned long i, j;
146 FILE *file;
147
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 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
167 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 if (strcmp(getstr(format, file), PMAP_FILEVER))
178 error(USER, "incompatible photon map file format");
179
180 /* Get number of photons */
181 pmap -> numPhotons = getint(sizeof(pmap -> numPhotons), file);
182
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 pmap -> numPrimary = getint(sizeof(pmap -> numPrimary), file);
202
203 if (pmap -> numPrimary) {
204 pmap -> primaries = calloc(pmap -> numPrimary, sizeof(PhotonPrimary));
205 if (!pmap -> primaries)
206 error(INTERNAL, "can't allocate primary photon rays");
207
208 for (i = 0; i < pmap -> numPrimary; i++) {
209 PhotonPrimary *prim = pmap -> primaries + i;
210
211 prim -> srcIdx = getint(sizeof(prim -> srcIdx), file);
212 #ifdef PMAP_PRIMARYDIR
213 prim -> dir = getint(sizeof(prim -> dir), file);
214 #endif
215 #ifdef PMAP_PRIMARYPOS
216 for (j = 0; j < 3; j++)
217 prim -> pos [j] = getflt(file);
218 #endif
219 if (feof(file))
220 error(SYSTEM, "error reading primary photon rays");
221 }
222 }
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 }
233
234 fclose(file);
235 return ptype;
236 }