1 /****************************************************************************
2 * pov_util.cpp
3 *
4 * This module implements misc utility functions.
5 *
6 * from Persistence of Vision(tm) Ray Tracer version 3.6.
7 * Copyright 1991-2003 Persistence of Vision Team
8 * Copyright 2003-2004 Persistence of Vision Raytracer Pty. Ltd.
9 *---------------------------------------------------------------------------
10 * NOTICE: This source code file is provided so that users may experiment
11 * with enhancements to POV-Ray and to port the software to platforms other
12 * than those supported by the POV-Ray developers. There are strict rules
13 * regarding how you are permitted to use this file. These rules are contained
14 * in the distribution and derivative versions licenses which should have been
15 * provided with this file.
16 *
17 * These licences may be found online, linked from the end-user license
18 * agreement that is located at http://www.povray.org/povlegal.html
19 *---------------------------------------------------------------------------
20 * This program is based on the popular DKB raytracer version 2.12.
21 * DKBTrace was originally written by David K. Buck.
22 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
23 *---------------------------------------------------------------------------
24 *
25 *===========================================================================
26 * This file is part of MegaPOV, a modified and unofficial version of POV-Ray
27 * For more information on MegaPOV visit our website:
28 * http://megapov.inetart.net/
29 *===========================================================================
30 *
31 * $RCSfile: pov_util.cpp,v $
32 * $Revision: 1.13 $
33 * $Author: chris $
34 *
35 *****************************************************************************/
36
37 #include <ctype.h>
38 #include <stdarg.h>
39
40 #include "frame.h"
41 #include "pov_util.h"
42 #include "povray.h"
43
44 BEGIN_POV_NAMESPACE
45
46 /*
47 // not used right now
48 typedef struct
49 {
50 bool read_local;
51 bool read_global;
52 bool write_local;
53 bool write_global;
54 } POV_File_Restrictions;
55
56 POV_File_Restrictions gPOV_File_Restrictions[POV_File_Unknown_Count] =
57 {
58 { false, false, false, false }, // POV_File_Unknown
59 { true, true, false, false }, // POV_File_Image_Targa
60 { true, true, false, false }, // POV_File_Image_PNG
61 { true, true, false, false }, // POV_File_Image_PPM
62 { true, true, false, false }, // POV_File_Image_PGM
63 { true, true, false, false }, // POV_File_Image_GIF
64 { true, true, false, false }, // POV_File_Image_IFF
65 { true, true, false, false }, // POV_File_Image_JPEG
66 { true, true, false, false }, // POV_File_Image_TIFF
67 { true, true, false, false }, // POV_File_Image_System
68 { true, false, false, false }, // POV_File_Text_POV
69 { true, false, false, false }, // POV_File_Text_INC
70 { true, false, false, false }, // POV_File_Text_INI
71 { true, true, false, false }, // POV_File_Text_CSV
72 { true, false, false, false }, // POV_File_Text_Stream
73 { true, true, false, false }, // POV_File_Text_User
74 { true, true, true, false }, // POV_File_Data_DF3
75 { true, true, true, true }, // POV_File_Data_RCA
76 { true, true, true, true }, // POV_File_Data_LOG
77 { true, false, true, false } // POV_File_Font_TTF
78 };
79 */
80
81
82 /*****************************************************************************
83 *
84 * FUNCTION
85 *
86 * POV_Std_Split_Time
87 *
88 * INPUT
89 *
90 * OUTPUT
91 *
92 * RETURNS
93 *
94 * AUTHOR
95 *
96 * POV-Ray Team
97 *
98 * DESCRIPTION
99 *
100 * Split time into hours, minutes and seconds.
101 *
102 * CHANGES
103 *
104 * Changed to use plain integer math. Will no longer operate correctly for
105 * time differences longer than 6.8 years. [trf]
106 *
107 ******************************************************************************/
108
POV_Std_Split_Time(DBL time_dif,unsigned int * hrs,unsigned int * mins,DBL * secs)109 void POV_Std_Split_Time(DBL time_dif, unsigned int *hrs, unsigned int *mins, DBL *secs)
110 {
111 int t = (int)(time_dif * 10.0);
112
113 *hrs = t / 36000;
114
115 *mins = (t / 600) % 60;
116
117 *secs = ((DBL)(t % 600)) / 10.0;
118 }
119
120
121
122 /*****************************************************************************
123 *
124 * FUNCTION
125 *
126 * closest_power_of_2
127 *
128 * INPUT
129 *
130 * theNumber - the value to determine closest power of 2 for.
131 *
132 * OUTPUT
133 *
134 * RETURNS
135 *
136 * The closest power of two is returned, or zero if the
137 * argument is less than or equal to zero.
138 *
139 * AUTHOR
140 *
141 * Eduard Schwan
142 *
143 * DESCRIPTION
144 *
145 * Decription: Find the highest positive power of 2 that is
146 * less than or equal to the number passed.
147 *
148 * Input Output
149 * ----- ------
150 * 0 0
151 * 1 1
152 * 2 2
153 * 3 2
154 * 8 8
155 * 9 8
156 *
157 * CHANGES
158 *
159 * Aug 1994 : Created by Eduard.
160 *
161 ******************************************************************************/
162
closest_power_of_2(unsigned theNumber)163 unsigned closest_power_of_2(unsigned theNumber)
164 {
165 int PowerOf2Counter;
166
167 /* do not handle zero or negative numbers for now */
168
169 if (theNumber <= 0)
170 {
171 return(0);
172 }
173
174 /* count the number in question down as we count up a power of 2 */
175
176 PowerOf2Counter = 1;
177
178 while (theNumber > 1)
179 {
180 /* move our power of 2 counter bit up... */
181
182 PowerOf2Counter <<= 1;
183
184 /* and reduce our test number by a factor of 2 two */
185
186 theNumber >>= 1;
187 }
188
189 return(PowerOf2Counter);
190 }
191
192
193
194 /*****************************************************************************
195 *
196 * FUNCTION
197 * POVMSUtil_SetFormatString
198 *
199 * DESCRIPTION
200 * Stores a string with format information in the given attribute.
201 *
202 * CHANGES
203 * -
204 *
205 ******************************************************************************/
206
POVMSUtil_SetFormatString(POVMSObjectPtr object,POVMSType key,const char * format,...)207 int POVMSUtil_SetFormatString(POVMSObjectPtr object, POVMSType key, const char *format, ...) // Note: Strings may not contain \0 characters codes!
208 {
209 va_list marker;
210 char buffer[1024];
211
212 va_start(marker, format);
213 vsprintf(buffer, format, marker);
214 va_end(marker);
215
216 return POVMSUtil_SetString(object, key, buffer);
217 }
218
219
220 /*****************************************************************************
221 *
222 * FUNCTION
223 *
224 * New_Checked_IStream
225 *
226 * INPUT
227 *
228 * OUTPUT
229 *
230 * RETURNS
231 *
232 * AUTHOR
233 *
234 * POV-Ray Team
235 *
236 * DESCRIPTION
237 *
238 * CHANGES
239 *
240 ******************************************************************************/
241
New_Checked_IStream(char * filename,unsigned int stype)242 IStream *New_Checked_IStream(char *filename, unsigned int stype)
243 {
244 if(POV_ALLOW_FILE_READ(filename, stype) == true)
245 return New_IStream(filename, stype);
246 return NULL;
247 }
248
249
250 /*****************************************************************************
251 *
252 * FUNCTION
253 *
254 * New_Checked_OStream
255 *
256 * INPUT
257 *
258 * OUTPUT
259 *
260 * RETURNS
261 *
262 * AUTHOR
263 *
264 * POV-Ray Team
265 *
266 * DESCRIPTION
267 *
268 * CHANGES
269 *
270 ******************************************************************************/
271
New_Checked_OStream(char * filename,unsigned int stype,bool append)272 OStream *New_Checked_OStream(char *filename, unsigned int stype, bool append)
273 {
274 if(POV_ALLOW_FILE_WRITE(filename, stype) == true)
275 return New_OStream(filename, stype, append);
276 return NULL;
277 }
278
279
280 /*****************************************************************************
281 *
282 * FUNCTION
283 *
284 * Locate_File
285 *
286 * INPUT
287 *
288 * OUTPUT
289 *
290 * RETURNS
291 *
292 * AUTHOR
293 *
294 * POV-Ray Team
295 *
296 * DESCRIPTION
297 *
298 * Find a file in the search path.
299 *
300 * CHANGES
301 *
302 * Apr 1996: Don't add trailing FILENAME_SEPARATOR if we are immediately
303 * following DRIVE_SEPARATOR because of Amiga probs. [AED]
304 *
305 ******************************************************************************/
306
Locate_File(char * filename,unsigned int stype,char * buffer,bool err_flag)307 IStream *Locate_File(char *filename, unsigned int stype, char *buffer, bool err_flag)
308 {
309 IStream *result;
310 char *qualified_name = Locate_Filename(filename, stype, err_flag);
311
312 if (qualified_name != NULL)
313 {
314 POV_GET_FULL_PATH(qualified_name, buffer);
315 result = New_Checked_IStream(qualified_name, stype);
316 delete[] qualified_name;
317 }
318 else
319 {
320 /* Any error was already reported in Locate_Filename(...) */
321 result = NULL;
322 }
323
324 return result;
325 }
326
327 /*****************************************************************************
328 *
329 * FUNCTION
330 *
331 * Locate_Filename
332 *
333 * INPUT
334 *
335 * OUTPUT
336 *
337 * RETURNS
338 * Fully expanded filename, including drive, path, ...
339 *
340 * AUTHOR
341 *
342 * Alexander R. Enzmann
343 *
344 * DESCRIPTION
345 *
346 * Find a file in the search path.
347 *
348 * CHANGES
349 *
350 *
351 ******************************************************************************/
352
Locate_Filename(char * filename,unsigned int stype,bool err_flag)353 char *Locate_Filename(char *filename, unsigned int stype, bool err_flag)
354 {
355 int i,ii,l[4];
356 char pathname[FILE_NAME_LENGTH];
357 char file[FILE_NAME_LENGTH];
358 char file_x[4][FILE_NAME_LENGTH];
359 char *result = NULL;
360
361 if (Has_Extension(filename))
362 {
363 for(i = 0; i < 4; i++)
364 l[i]=0;
365 }
366 else
367 {
368 for(i = 0; i < 4; i++)
369 {
370 if ((l[i] = strlen(gPOV_File_Extensions[stype].ext[i])) > 0)
371 {
372 strcpy(file_x[i], filename);
373 strcat(file_x[i], gPOV_File_Extensions[stype].ext[i]);
374 }
375 }
376 }
377
378 /* Check the current directory first. */
379 for(i = 0; i < 4; i++)
380 {
381 /* Try appending the variations of the file extension */
382 if(l[i])
383 {
384 if (EXIST_FILE(file_x[i]) == true)
385 {
386 result = new char[strlen(file_x[i]) + 1];
387 POV_GET_FULL_PATH(file_x[i], result);
388 return result;
389 }
390 }
391 }
392 /* Try the filename without any modifications */
393 if (EXIST_FILE(filename) == true)
394 {
395 result = new char[strlen(filename) + 1];
396 POV_GET_FULL_PATH(filename, result);
397 return result;
398 }
399
400 /* Walk through the library paths, trying with and without file extensions */
401 for (i = 0; i < opts.Library_Path_Index; i++)
402 {
403 strcpy(file, opts.Library_Paths[i]);
404 file[strlen(file)+1] = '\0';
405 if (file[strlen(file) - 1] != DRIVE_SEPARATOR)
406 file[strlen(file)] = FILENAME_SEPARATOR;
407
408 for(ii = 0; ii < 4; ii++)
409 {
410 if(l[ii])
411 {
412 strcpy(pathname, file);
413 strcat(pathname, file_x[ii]);
414 if (EXIST_FILE(pathname) == true)
415 {
416 result = new char[strlen(pathname) + 1];
417 POV_GET_FULL_PATH(pathname, result);
418 return result;
419 }
420 }
421 }
422
423 strcpy(pathname, file);
424 strcat(pathname, filename);
425 if (EXIST_FILE(pathname) == true)
426 {
427 result = new char[strlen(pathname) + 1];
428 POV_GET_FULL_PATH(pathname, result);
429 return result;
430 }
431 }
432
433 // Allow system specific access of font files:
434 // Obviously this requires POV_NEW_ISTREAM
435 // to be platform specific as well! [trf]
436 if(stype == POV_File_Font_TTF)
437 {
438 if(EXIST_FONT_FILE(filename))
439 {
440 result = new char[strlen(filename) + 1];
441 strcpy(filename, result);
442 return result;
443 }
444 }
445
446 if (err_flag)
447 {
448 if (l[0])
449 PossibleError("Could not find file '%s%s'",filename,gPOV_File_Extensions[stype].ext[0]);
450 else
451 PossibleError("Could not find file '%s'",filename);
452 }
453
454 return NULL;
455 }
456
457 END_POV_NAMESPACE
458