1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Sources
4 // Copyright (C) 2000-2008 by Denton Woods
5 // Last modified: 11/08/2008
6 //
7 // Filename: src-IL/src/il_internal.c
8 //
9 // Description: Internal stuff for DevIL
10 //
11 //-----------------------------------------------------------------------------
12 
13 
14 #include "il_internal.h"
15 #include <string.h>
16 #include <stdlib.h>
17 
18 
19 ILimage *iCurImage = NULL;
20 
21 
22 /* Siigron: added this for Linux... a #define should work, but for some reason
23 	it doesn't (anyone who knows why?) */
24 #if !_WIN32 || (_WIN32 && __GNUC__) // Cygwin
stricmp(const char * src1,const char * src2)25 	int stricmp(const char *src1, const char *src2)
26 	{
27 		return strcasecmp(src1, src2);
28 	}
strnicmp(const char * src1,const char * src2,size_t max)29 	int strnicmp(const char *src1, const char *src2, size_t max)
30 	{
31 		return strncasecmp(src1, src2, max);
32 	}
33 #elif _WIN32_WCE
stricmp(const char * src1,const char * src2)34 	int stricmp(const char *src1, const char *src2)
35 	{
36 		return _stricmp(src1, src2);
37 	}
strnicmp(const char * src1,const char * src2,size_t max)38 	int strnicmp(const char *src1, const char *src2, size_t max)
39 	{
40 		return _strnicmp(src1, src2, max);
41 	}
42 #endif /* _WIN32 */
43 
44 #ifdef _WIN32_WCE
strdup(const char * src)45 	char *strdup(const char *src)
46 	{
47 		return _strdup(src);
48 	}
49 #endif//_WIN32_WCE
50 
51 
52 #ifdef _UNICODE
iStrCmp(ILconst_string src1,ILconst_string src2)53 	int iStrCmp(ILconst_string src1, ILconst_string src2)
54 	{
55 		return wcsicmp(src1, src2);
56 	}
57 #else
iStrCmp(ILconst_string src1,ILconst_string src2)58 	int iStrCmp(ILconst_string src1, ILconst_string src2)
59 	{
60 		return stricmp(src1, src2);
61 	}
62 #endif
63 
64 
65 //! Glut's portability.txt says to use this...
ilStrDup(ILconst_string Str)66 ILstring ilStrDup(ILconst_string Str)
67 {
68 	ILstring copy;
69 
70 	copy = (ILstring)ialloc((ilStrLen(Str) + 1) * sizeof(ILchar));
71 	if (copy == NULL)
72 		return NULL;
73 	iStrCpy(copy, Str);
74 	return copy;
75 }
76 
77 
78 // Because MSVC++'s version is too stupid to check for NULL...
ilStrLen(ILconst_string Str)79 ILuint ilStrLen(ILconst_string Str)
80 {
81 	ILconst_string eos = Str;
82 
83 	if (Str == NULL)
84 		return 0;
85 
86 	while (*eos++);
87 
88 	return((int)(eos - Str - 1));
89 }
90 
91 
92 // Because MSVC++'s version is too stupid to check for NULL...
93 //  Passing NULL to strlen will definitely cause a crash.
ilCharStrLen(const char * Str)94 ILuint ilCharStrLen(const char *Str)
95 {
96 	const char *eos = Str;
97 
98 	if (Str == NULL)
99 		return 0;
100 
101 	while (*eos++);
102 
103 	return((int)(eos - Str - 1));
104 }
105 
106 
107 // Simple function to test if a filename has a given extension, disregarding case
iCheckExtension(ILconst_string Arg,ILconst_string Ext)108 ILboolean iCheckExtension(ILconst_string Arg, ILconst_string Ext)
109 {
110 	ILboolean PeriodFound = IL_FALSE;
111 	ILint i, Len;
112 	ILstring Argu = (ILstring)Arg;
113 
114 	if (Arg == NULL || Ext == NULL || !ilStrLen(Arg) || !ilStrLen(Ext))  // if not a good filename/extension, exit early
115 		return IL_FALSE;
116 
117 	Len = ilStrLen(Arg);
118 	Argu += Len;  // start at the end
119 
120 	for (i = Len; i >= 0; i--) {
121 		if (*Argu == '.') {  // try to find a period
122 			PeriodFound = IL_TRUE;
123 			break;
124 		}
125 		Argu--;
126 	}
127 
128 	if (!PeriodFound)  // if no period, no extension
129 		return IL_FALSE;
130 
131 	if (!iStrCmp(Argu+1, Ext))  // extension and ext match?
132 		return IL_TRUE;
133 
134 	return IL_FALSE;  // if all else fails, return IL_FALSE
135 }
136 
137 
iGetExtension(ILconst_string FileName)138 ILstring iGetExtension(ILconst_string FileName)
139 {
140 	ILboolean PeriodFound = IL_FALSE;
141 	ILstring Ext = (ILstring)FileName;
142 	ILint i, Len = ilStrLen(FileName);
143 
144 	if (FileName == NULL || !Len)  // if not a good filename/extension, exit early
145 		return NULL;
146 
147 	Ext += Len;  // start at the end
148 
149 	for (i = Len; i >= 0; i--) {
150 		if (*Ext == '.') {  // try to find a period
151 			PeriodFound = IL_TRUE;
152 			break;
153 		}
154 		Ext--;
155 	}
156 
157 	if (!PeriodFound)  // if no period, no extension
158 		return NULL;
159 
160 	return Ext+1;
161 }
162 
163 
164 // Checks if the file exists
iFileExists(ILconst_string FileName)165 ILboolean iFileExists(ILconst_string FileName)
166 {
167 #if (!defined(_UNICODE) || !defined(_WIN32))
168 	FILE *CheckFile = fopen(FileName, "rb");
169 #else // Windows uses _wfopen instead.
170 	FILE *CheckFile = _wfopen(FileName, L"rb");
171 #endif//_UNICODE
172 
173 	if (CheckFile) {
174 		fclose(CheckFile);
175 		return IL_TRUE;
176 	}
177 	return IL_FALSE;
178 }
179 
180 
181 // Last time I tried, MSVC++'s fgets() was really really screwy
iFgets(char * buffer,ILuint maxlen)182 ILbyte *iFgets(char *buffer, ILuint maxlen)
183 {
184 	ILuint	counter = 0;
185 	ILint	temp = '\0';
186 
187 	while ((temp = igetc()) && temp != '\n' && temp != IL_EOF && counter < maxlen) {
188 		buffer[counter] = temp;
189 		counter++;
190 	}
191 	buffer[counter] = '\0';
192 
193 	if (temp == IL_EOF && counter == 0)  // Only return NULL if no data was "got".
194 		return NULL;
195 
196 	return (ILbyte*)buffer;
197 }
198 
199 
200 // A fast integer squareroot, completely accurate for x < 289.
201 // Taken from http://atoms.org.uk/sqrt/
202 // There is also a version that is accurate for all integers
203 // < 2^31, if we should need it
204 
205 static int table[] = {
206 	0,    16,  22,  27,  32,  35,  39,  42,  45,  48,  50,  53,  55,  57,
207 	59,   61,  64,  65,  67,  69,  71,  73,  75,  76,  78,  80,  81,  83,
208 	84,   86,  87,  89,  90,  91,  93,  94,  96,  97,  98,  99, 101, 102,
209 	103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
210 	119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
211 	133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145,
212 	146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157,
213 	158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
214 	169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178,
215 	179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188,
216 	189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197,
217 	198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206,
218 	207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215,
219 	215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223,
220 	224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231,
221 	231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
222 	239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246,
223 	246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
224 	253, 254, 254, 255
225 };
226 
iSqrt(int x)227 int iSqrt(int x) {
228 	if (x >= 0x10000) {
229 		if (x >= 0x1000000) {
230 			if (x >= 0x10000000) {
231 				if (x >= 0x40000000) {
232 					return (table[x >> 24] << 8);
233 				} else {
234 					return (table[x >> 22] << 7);
235 				}
236 			} else if (x >= 0x4000000) {
237 				return (table[x >> 20] << 6);
238 			} else {
239 				return (table[x >> 18] << 5);
240 			}
241 		} else if (x >= 0x100000) {
242 			if (x >= 0x400000) {
243 				return (table[x >> 16] << 4);
244 			} else {
245 				return (table[x >> 14] << 3);
246 			}
247 		} else if (x >= 0x40000) {
248 			return (table[x >> 12] << 2);
249 		} else {
250 			return (table[x >> 10] << 1);
251 		}
252 	} else if (x >= 0x100) {
253 		if (x >= 0x1000) {
254 			if (x >= 0x4000) {
255 				return (table[x >> 8]);
256 			} else {
257 				return (table[x >> 6] >> 1);
258 			}
259 		} else if (x >= 0x400) {
260 			return (table[x >> 4] >> 2);
261 		} else {
262 			return (table[x >> 2] >> 3);
263 		}
264 	} else if (x >= 0) {
265 		return table[x] >> 4;
266 	}
267 
268 	//hm, x was negative....
269 	return -1;
270 }
271 
272