0023843: scanf without field width limits can crash with huge input data.
[occt.git] / src / Voxel / Voxel_Reader.cxx
CommitLineData
b311480e 1// Created on: 2008-08-28
2// Created by: Vladislav ROMASHKO
3// Copyright (c) 2008-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21#include <Voxel_Reader.ixx>
22#include <Voxel_BoolDS.hxx>
23#include <Voxel_ColorDS.hxx>
24#include <Voxel_FloatDS.hxx>
25#include <Voxel_VoxelFileFormat.hxx>
26#include <Voxel_TypeDef.hxx>
27
28#include <TCollection_AsciiString.hxx>
29
30Voxel_Reader::Voxel_Reader():myBoolVoxels(0),myColorVoxels(0),myFloatVoxels(0)
31{
32
33}
34
35Standard_Boolean Voxel_Reader::Read(const TCollection_ExtendedString& file)
36{
37 // Open file in ASCII mode to read header
38 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
39 if (!f)
40 return Standard_False;
41
42 // Read the header
43 Standard_Byte type; // 0 - bool, 1 - color, 2 - float
44 Voxel_VoxelFileFormat format;
d0e4e578 45 Standard_Character svoxels[9], sformat[9], stype[9];
46 fscanf(f, "%8s %8s %8s\n", svoxels, sformat, stype);
7fd59977 47 fclose(f);
48
49 // Take format, type of voxels.
50 // Voxels
51 if (strcmp(svoxels, VOXELS))
52 return Standard_False;
53 // Format
54 if (strcmp(sformat, ASCII) == 0)
55 format = Voxel_VFF_ASCII;
56 else if (strcmp(sformat, BINARY) == 0)
57 format = Voxel_VFF_BINARY;
58 else
59 return Standard_False;
60 // Type of voxels
61 if (strcmp(stype, BOOL) == 0)
62 type = 0;
63 else if (strcmp(stype, COLOR) == 0)
64 type = 1;
65 else if (strcmp(stype, FLOAT) == 0)
66 type = 2;
67 else
68 return Standard_False;
69
70 // Read the rest
71 switch (format)
72 {
73 case Voxel_VFF_ASCII:
74 {
75 switch (type)
76 {
77 case 0:
78 return ReadBoolAsciiVoxels(file);
79 case 1:
80 return ReadColorAsciiVoxels(file);
81 case 2:
82 return ReadFloatAsciiVoxels(file);
83 }
84 }
85 case Voxel_VFF_BINARY:
86 {
87 switch (type)
88 {
89 case 0:
90 return ReadBoolBinaryVoxels(file);
91 case 1:
92 return ReadColorBinaryVoxels(file);
93 case 2:
94 return ReadFloatBinaryVoxels(file);
95 }
96 }
97 }
98
99 // No voxels or no format description is found:
100 return Standard_False;
101}
102
103Standard_Boolean Voxel_Reader::IsBoolVoxels() const
104{
105 return (myBoolVoxels != 0);
106}
107
108Standard_Boolean Voxel_Reader::IsColorVoxels() const
109{
110 return (myColorVoxels != 0);
111}
112
113Standard_Boolean Voxel_Reader::IsFloatVoxels() const
114{
115 return (myFloatVoxels != 0);
116}
117
118Standard_Address Voxel_Reader::GetBoolVoxels() const
119{
120 return myBoolVoxels;
121}
122
123Standard_Address Voxel_Reader::GetColorVoxels() const
124{
125 return myColorVoxels;
126}
127
128Standard_Address Voxel_Reader::GetFloatVoxels() const
129{
130 return myFloatVoxels;
131}
132
133static Standard_Boolean has_slice(const Standard_CString line)
134{
135 Standard_Integer i = 0, nb_spaces = 0;
136 while (line[i] != '\0')
137 {
138 if (line[i] == ' ')
139 nb_spaces++;
140 i++;
141 }
142 return (nb_spaces == 2);
143}
144
145Standard_Boolean Voxel_Reader::ReadBoolAsciiVoxels(const TCollection_ExtendedString& file)
146{
147 // Open file for reading
148 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
149 if (!f)
150 return Standard_False;
d0e4e578 151 Standard_Character line[65], sx[33], sy[33], sz[33];
7fd59977 152
153 // Header: skip it
154 fgets(line, 64, f);
155
156 // Location, size, number of splits
157 Standard_Integer nbx = 0, nby = 0, nbz = 0;
158 Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
d0e4e578 159 if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
7fd59977 160 {
161 fclose(f);
162 return Standard_False;
163 }
91322f44 164 x = Atof(sx); y = Atof(sy); z = Atof(sz);
d0e4e578 165 if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
7fd59977 166 {
167 fclose(f);
168 return Standard_False;
169 }
91322f44 170 xlen = Atof(sx); ylen = Atof(sy); zlen = Atof(sz);
7fd59977 171 if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
172 {
173 fclose(f);
174 return Standard_False;
175 }
176
177 // Allocate the voxels
178 myBoolVoxels = (Standard_Address) new Voxel_BoolDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
179
180 // Data
181 // Copied from Voxel_BoolDS.cxx:
182 Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 8.0));
183 Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
184 // myData[0 .. nb_slices - 1][0 .. 7]
185 if (nb_slices)
186 {
187 Standard_Integer i1 = 0, i2 = 0, value = 0;
188 while (!feof(f))
189 {
190 fgets(line, 64, f);
191 if (has_slice(line))
192 {
193 if (sscanf(line, "%d %d %d\n", &i1, &i2, &value) != 3)
194 {
195 fclose(f);
196 return Standard_False;
197 }
198 }
199 else
200 {
201 if (sscanf(line, "%d %d\n", &i2, &value) != 2)
202 {
203 fclose(f);
204 return Standard_False;
205 }
206 }
207
208 // Set value
209 if (!((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])
210 {
211 ((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1] =
212 (Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
213 }
214 (((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])[i2] = value;
215 }
216 }
217
218 fclose(f);
219 return Standard_True;
220}
221
222Standard_Boolean Voxel_Reader::ReadColorAsciiVoxels(const TCollection_ExtendedString& file)
223{
224 // Open file for reading
225 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
226 if (!f)
227 return Standard_False;
d0e4e578 228 Standard_Character line[65], sx[33], sy[33], sz[33];
7fd59977 229
230 // Header: skip it
231 fgets(line, 64, f);
232
233 // Location, size, number of splits
234 Standard_Integer nbx = 0, nby = 0, nbz = 0;
235 Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
d0e4e578 236 if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
7fd59977 237 {
238 fclose(f);
239 return Standard_False;
240 }
91322f44 241 x = Atof(sx); y = Atof(sy); z = Atof(sz);
d0e4e578 242 if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
7fd59977 243 {
244 fclose(f);
245 return Standard_False;
246 }
91322f44 247 xlen = Atof(sx); ylen = Atof(sy); zlen = Atof(sz);
7fd59977 248 if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
249 {
250 fclose(f);
251 return Standard_False;
252 }
253
254 // Allocate the voxels
255 myColorVoxels = (Standard_Address) new Voxel_ColorDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
256
257 // Data
258 // Copied from Voxel_ColorDS.cxx:
259 Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 2.0));
260 Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
261 // myData[0 .. nb_slices - 1][0 .. 31]
262 if (nb_slices)
263 {
264 Standard_Integer i1 = 0, i2 = 0, value = 0;
265 while (!feof(f))
266 {
267 fgets(line, 64, f);
268 if (has_slice(line))
269 {
270 if (sscanf(line, "%d %d %d\n", &i1, &i2, &value) != 3)
271 {
272 fclose(f);
273 return Standard_False;
274 }
275 }
276 else
277 {
278 if (sscanf(line, "%d %d\n", &i2, &value) != 2)
279 {
280 fclose(f);
281 return Standard_False;
282 }
283 }
284
285 // Set value
286 if (!((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])
287 {
288 ((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1] =
289 (Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
290 }
291 (((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])[i2] = value;
292 }
293 }
294
295 fclose(f);
296 return Standard_True;
297}
298
299Standard_Boolean Voxel_Reader::ReadFloatAsciiVoxels(const TCollection_ExtendedString& file)
300{
301 // Open file for reading
302 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
303 if (!f)
304 return Standard_False;
d0e4e578 305 Standard_Character line[65], sx[33], sy[33], sz[33];
7fd59977 306
307 // Header: skip it
308 fgets(line, 64, f);
309
310 // Location, size, number of splits
311 Standard_Integer nbx = 0, nby = 0, nbz = 0;
312 Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
d0e4e578 313 if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
7fd59977 314 {
315 fclose(f);
316 return Standard_False;
317 }
91322f44 318 x = Atof(sx); y = Atof(sy); z = Atof(sz);
d0e4e578 319 if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
7fd59977 320 {
321 fclose(f);
322 return Standard_False;
323 }
91322f44 324 xlen = Atof(sx); ylen = Atof(sy); zlen = Atof(sz);
7fd59977 325 if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
326 {
327 fclose(f);
328 return Standard_False;
329 }
330
331 // Allocate the voxels
332 myFloatVoxels = (Standard_Address) new Voxel_FloatDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
333
334 // Data
335 // Copied from Voxel_FloatDS.cxx:
336 Standard_Integer nb_floats = nbx * nby * nbz;
337 Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
338 // myData[0 .. nb_slices - 1][0 .. 31]
339 if (nb_slices)
340 {
341 Standard_Integer i1 = 0, i2 = 0;
342 Standard_ShortReal value = 0.0;
343 while (!feof(f))
344 {
345 fgets(line, 64, f);
346 if (has_slice(line))
347 {
d0e4e578 348 if (sscanf(line, "%d %d %64s\n", &i1, &i2, line) != 3)
7fd59977 349 {
350 fclose(f);
351 return Standard_False;
352 }
353 }
354 else
355 {
d0e4e578 356 if (sscanf(line, "%d %64s\n", &i2, line) != 2)
7fd59977 357 {
358 fclose(f);
359 return Standard_False;
360 }
361 }
7f4c4756 362 value = (Standard_ShortReal)Atof(line);
7fd59977 363
364 // Set value
365 if (!((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])
366 {
367 ((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1] =
368 (Standard_ShortReal*) calloc(32/*number of floats in slice*/, sizeof(Standard_ShortReal));
369 }
370 (((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])[i2] = value;
371 }
372 }
373
374 fclose(f);
375 return Standard_True;
376}
377
378Standard_Boolean Voxel_Reader::ReadBoolBinaryVoxels(const TCollection_ExtendedString& file)
379{
380 // Open file for reading
381 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "rb");
382 if (!f)
383 return Standard_False;
384
385 // Header: skip it
d0e4e578 386 Standard_Character line[65];
7fd59977 387 fgets(line, 64, f);
388
389 // Location, size, number of splits
390 Standard_Integer nbx = 0, nby = 0, nbz = 0;
391 Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
392 fread(&x, sizeof(Standard_Real), 1, f);
393 fread(&y, sizeof(Standard_Real), 1, f);
394 fread(&z, sizeof(Standard_Real), 1, f);
395 fread(&xlen, sizeof(Standard_Real), 1, f);
396 fread(&ylen, sizeof(Standard_Real), 1, f);
397 fread(&zlen, sizeof(Standard_Real), 1, f);
398 fread(&nbx, sizeof(Standard_Integer), 1, f);
399 fread(&nby, sizeof(Standard_Integer), 1, f);
400 fread(&nbz, sizeof(Standard_Integer), 1, f);
401
402 // Allocate the voxels
403 myBoolVoxels = (Standard_Address) new Voxel_BoolDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
404
405 // Data
406 // Copied from Voxel_BoolDS.cxx:
407 Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 8.0));
408 Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
409 // myData[0 .. nb_slices - 1][0 .. 7]
410 if (nb_slices)
411 {
412 Standard_Integer i1 = 0, i2 = 0, value = 0;
413 while (!feof(f))
414 {
415 fread(&i1, sizeof(Standard_Integer), 1, f);
416 fread(&i2, sizeof(Standard_Integer), 1, f);
417 fread(&value, sizeof(Standard_Byte), 1, f);
418
419 // Set value
420 if (!((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])
421 {
422 ((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1] =
423 (Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
424 }
425 (((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])[i2] = value;
426 }
427 }
428
429 fclose(f);
430 return Standard_True;
431}
432
433Standard_Boolean Voxel_Reader::ReadColorBinaryVoxels(const TCollection_ExtendedString& file)
434{
435 // Open file for reading
436 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "rb");
437 if (!f)
438 return Standard_False;
439
440 // Header: skip it
d0e4e578 441 Standard_Character line[65];
7fd59977 442 fgets(line, 64, f);
443
444 // Location, size, number of splits
445 Standard_Integer nbx = 0, nby = 0, nbz = 0;
446 Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
447 fread(&x, sizeof(Standard_Real), 1, f);
448 fread(&y, sizeof(Standard_Real), 1, f);
449 fread(&z, sizeof(Standard_Real), 1, f);
450 fread(&xlen, sizeof(Standard_Real), 1, f);
451 fread(&ylen, sizeof(Standard_Real), 1, f);
452 fread(&zlen, sizeof(Standard_Real), 1, f);
453 fread(&nbx, sizeof(Standard_Integer), 1, f);
454 fread(&nby, sizeof(Standard_Integer), 1, f);
455 fread(&nbz, sizeof(Standard_Integer), 1, f);
456
457 // Allocate the voxels
458 myColorVoxels = (Standard_Address) new Voxel_ColorDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
459
460 // Data
461 // Copied from Voxel_ColorDS.cxx:
462 Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 2.0));
463 Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
464 // myData[0 .. nb_slices - 1][0 .. 31]
465 if (nb_slices)
466 {
467 Standard_Integer i1 = 0, i2 = 0, value = 0;
468 while (!feof(f))
469 {
470 fread(&i1, sizeof(Standard_Integer), 1, f);
471 fread(&i2, sizeof(Standard_Integer), 1, f);
472 fread(&value, sizeof(Standard_Byte), 1, f);
473
474 // Set value
475 if (!((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])
476 {
477 ((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1] =
478 (Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
479 }
480 (((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])[i2] = value;
481 }
482 }
483
484 fclose(f);
485 return Standard_True;
486}
487
488Standard_Boolean Voxel_Reader::ReadFloatBinaryVoxels(const TCollection_ExtendedString& file)
489{
490 // Open file for reading
491 FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "rb");
492 if (!f)
493 return Standard_False;
494
495 // Header: skip it
d0e4e578 496 Standard_Character line[65];
7fd59977 497 fgets(line, 64, f);
498
499 // Location, size, number of splits
500 Standard_Integer nbx = 0, nby = 0, nbz = 0;
501 Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
502 fread(&x, sizeof(Standard_Real), 1, f);
503 fread(&y, sizeof(Standard_Real), 1, f);
504 fread(&z, sizeof(Standard_Real), 1, f);
505 fread(&xlen, sizeof(Standard_Real), 1, f);
506 fread(&ylen, sizeof(Standard_Real), 1, f);
507 fread(&zlen, sizeof(Standard_Real), 1, f);
508 fread(&nbx, sizeof(Standard_Integer), 1, f);
509 fread(&nby, sizeof(Standard_Integer), 1, f);
510 fread(&nbz, sizeof(Standard_Integer), 1, f);
511
512 // Allocate the voxels
513 myFloatVoxels = (Standard_Address) new Voxel_FloatDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
514
515 // Data
516 // Copied from Voxel_FloatDS.cxx:
517 Standard_Integer nb_floats = nbx * nby * nbz;
518 Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
519 // myData[0 .. nb_slices - 1][0 .. 31]
520 if (nb_slices)
521 {
522 Standard_Integer i1 = 0, i2 = 0;
523 Standard_ShortReal value = 0.0;
524 while (!feof(f))
525 {
526 fread(&i1, sizeof(Standard_Integer), 1, f);
527 fread(&i2, sizeof(Standard_Integer), 1, f);
528 fread(&value, sizeof(Standard_ShortReal), 1, f);
529
530 // Set value
531 if (!((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])
532 {
533 ((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1] =
534 (Standard_ShortReal*) calloc(32/*number of floats in slice*/, sizeof(Standard_ShortReal));
535 }
536 (((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])[i2] = value;
537 }
538 }
539
540 fclose(f);
541 return Standard_True;
542}