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