1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Sources
4 // Copyright (C) 2000-2008 by Denton Woods
5 // Last modified: 07/07/2006
6 //
7 // Filename: src-IL/src/il_fastconv.c
8 //
9 // Description: Converts between several image formats
10 //
11 //-----------------------------------------------------------------------------
12 
13 
14 #include "il_internal.h"
15 #ifdef ALTIVEC_GCC
16 #include "altivec_typeconversion.h"
17 #endif
18 
iFastConvert(ILenum DestFormat)19 ILboolean iFastConvert(ILenum DestFormat)
20 {
21 	ILubyte		*BytePtr = iCurImage->Data;
22 	ILushort	*ShortPtr = (ILushort*)iCurImage->Data;
23 	ILuint		*IntPtr = (ILuint*)iCurImage->Data;
24 	ILfloat		*FloatPtr = (ILfloat*)iCurImage->Data;
25 	ILdouble	*DblPtr = (ILdouble*)iCurImage->Data;
26 
27 #ifndef ALTIVEC_GCC
28 	ILuint		SizeOfData, i=0;
29 	ILubyte TempByte = 0;
30 	ILushort TempShort = 0;
31 	ILuint TempInt = 0;
32 	ILfloat TempFloat = 0;
33 	ILdouble TempDbl = 0;
34 #endif
35 
36 	switch (DestFormat)
37 	{
38 		case IL_RGB:
39 		case IL_BGR:
40 			if (iCurImage->Format != IL_RGB && iCurImage->Format != IL_BGR)
41 				return IL_FALSE;
42 
43 			switch (iCurImage->Type)
44 			{
45 				case IL_BYTE:
46 				case IL_UNSIGNED_BYTE:
47 				#ifdef ALTIVEC_GCC
48 					abc2cba_byte(BytePtr,iCurImage->SizeOfData,BytePtr);
49 				#else
50 					SizeOfData = iCurImage->SizeOfData / 3;
51 					#ifdef USE_WIN32_ASM
52 						__asm
53 						{
54 							mov ebx, BytePtr
55 							mov ecx, SizeOfData
56 							L1:
57 								mov al,[ebx+0]
58 								xchg al,[ebx+2]
59 								mov [ebx+0],al
60 								add ebx,3
61 								loop L1
62 						}
63 					#else
64 						for (i = 0; i < SizeOfData; i++) {
65 							TempByte = BytePtr[0];
66 							BytePtr[0] = BytePtr[2];
67 							BytePtr[2] = TempByte;
68 							BytePtr += 3;
69 						}
70 					#endif//USE_WIN32_ASM
71 				#endif
72 					return IL_TRUE;
73 
74 				case IL_SHORT:
75 				case IL_UNSIGNED_SHORT:
76 				#ifdef ALTIVEC_GCC
77 					abc2cba_short(ShortPtr,iCurImage->SizeOfData,ShortPtr);
78 				#else
79 					SizeOfData = iCurImage->SizeOfData / 6;  // 3*2
80 					#ifdef USE_WIN32_ASM
81 						__asm
82 						{
83 							mov ebx, ShortPtr
84 							mov ecx, SizeOfData
85 							L2:
86 								mov ax,[ebx+0]
87 								xchg ax,[ebx+4]
88 								mov [ebx+0],ax
89 								add ebx,6
90 								loop L2
91 						}
92 					#else
93 						for (i = 0; i < SizeOfData; i++) {
94 							TempShort = ShortPtr[0];
95 							ShortPtr[0] = ShortPtr[2];
96 							ShortPtr[2] = TempShort;
97 							ShortPtr += 3;
98 						}
99 					#endif//USE_WIN32_ASM
100 				#endif
101 					return IL_TRUE;
102 
103 				case IL_INT:
104 				case IL_UNSIGNED_INT:
105 				#ifdef ALTIVEC_GCC
106 					abc2cba_int(IntPtr,iCurImage->SizeOfData,IntPtr);
107 				#else
108 					SizeOfData = iCurImage->SizeOfData / 12;  // 3*4
109 					#ifdef USE_WIN32_ASM
110 						__asm
111 						{
112 							mov ebx, IntPtr
113 							mov ecx, SizeOfData
114 							L3:
115 								mov eax,[ebx+0]
116 								xchg eax,[ebx+8]
117 								mov [ebx+0],ax
118 								add ebx,12
119 								loop L3
120 						}
121 					#else
122 						for (i = 0; i < SizeOfData; i++) {
123 							TempInt = IntPtr[0];
124 							IntPtr[0] = IntPtr[2];
125 							IntPtr[2] = TempInt;
126 							IntPtr += 3;
127 						}
128 					#endif//USE_WIN32_ASM
129 				#endif
130 					return IL_TRUE;
131 
132 				case IL_FLOAT:
133 				#ifdef ALTIVEC_GCC
134 					abc2cba_float(FloatPtr,iCurImage->SizeOfData,FloatPtr);
135 				#else
136 					SizeOfData = iCurImage->SizeOfData / 12;  // 3*4
137 					for (i = 0; i < SizeOfData; i++) {
138 						TempFloat = FloatPtr[0];
139 						FloatPtr[0] = FloatPtr[2];
140 						FloatPtr[2] = TempFloat;
141 						FloatPtr += 3;
142 					}
143 				#endif
144 					return IL_TRUE;
145 
146 				case IL_DOUBLE:
147 				#ifdef ALTIVEC_GCC
148 					abc2cba_double(DblPtr,iCurImage->SizeOfData,DblPtr);
149 				#else
150 					SizeOfData = iCurImage->SizeOfData / 24;  // 3*8
151 					for (i = 0; i < SizeOfData; i++) {
152 						TempDbl = DblPtr[0];
153 						DblPtr[0] = DblPtr[2];
154 						DblPtr[2] = TempDbl;
155 						DblPtr += 3;
156 					}
157 				#endif
158 					return IL_TRUE;
159 			}
160 			break;
161 
162 		case IL_RGBA:
163 		case IL_BGRA:
164 			if (iCurImage->Format != IL_RGBA && iCurImage->Format != IL_BGRA)
165 				return IL_FALSE;
166 
167 			switch (iCurImage->Type)
168 			{
169 				case IL_BYTE:
170 				case IL_UNSIGNED_BYTE:
171 				#ifdef ALTIVEC_GCC
172 					abcd2cbad_byte(BytePtr,iCurImage->SizeOfData,BytePtr);
173 				#else
174 					SizeOfData = iCurImage->SizeOfData / 4;
175 					#ifdef USE_WIN32_ASM
176 						__asm
177 						{
178 							mov ebx, BytePtr
179 							mov ecx, SizeOfData
180 							L4:
181 								mov eax,[ebx]
182 								bswap eax
183 								ror eax,8
184 								mov [ebx], eax
185 								add ebx,4
186 								loop L4
187 						}
188 					#else
189 						for (i = 0; i < SizeOfData; i++) {
190 							TempByte = BytePtr[0];
191 							BytePtr[0] = BytePtr[2];
192 							BytePtr[2] = TempByte;
193 							BytePtr += 4;
194 						}
195 					#endif//USE_WIN32_ASM
196 				#endif
197 					return IL_TRUE;
198 
199 				case IL_SHORT:
200 				case IL_UNSIGNED_SHORT:
201 				#ifdef ALTIVEC_GCC
202 					abcd2cbad_short(ShortPtr,iCurImage->SizeOfData,ShortPtr);
203 				#else
204 					SizeOfData = iCurImage->SizeOfData / 8;  // 4*2
205 					#ifdef USE_WIN32_ASM
206 						__asm
207 						{
208 							mov ebx, ShortPtr
209 							mov ecx, SizeOfData
210 							L5:
211 								mov ax,[ebx+0]
212 								xchg ax,[ebx+4]
213 								mov [ebx+0],ax
214 								add ebx,8
215 								loop L5
216 						}
217 					#else
218 						for (i = 0; i < SizeOfData; i++) {
219 							TempShort = ShortPtr[0];
220 							ShortPtr[0] = ShortPtr[2];
221 							ShortPtr[2] = TempShort;
222 							ShortPtr += 4;
223 						}
224 					#endif//USE_WIN32_ASM
225 				#endif
226 					return IL_TRUE;
227 
228 				case IL_INT:
229 				case IL_UNSIGNED_INT:
230 				#ifdef ALTIVEC_GCC
231 					abcd2cbad_int(IntPtr,iCurImage->SizeOfData,IntPtr);
232 				#else
233 					SizeOfData = iCurImage->SizeOfData / 16;  // 4*4
234 					#ifdef USE_WIN32_ASM
235 						__asm
236 						{
237 							mov ebx, IntPtr
238 							mov ecx, SizeOfData
239 							L6:
240 								mov eax,[ebx+0]
241 								xchg eax,[ebx+8]
242 								mov [ebx+0],ax
243 								add ebx,16
244 								loop L6
245 						}
246 					#else
247 						for (i = 0; i < SizeOfData; i++) {
248 							TempInt = IntPtr[0];
249 							IntPtr[0] = IntPtr[2];
250 							IntPtr[2] = TempInt;
251 							IntPtr += 4;
252 						}
253 					#endif//USE_WIN32_ASM
254 				#endif
255 					return IL_TRUE;
256 
257 				case IL_FLOAT:
258 				#ifdef ALTIVEC_GCC
259 					abcd2cbad_float(FloatPtr,iCurImage->SizeOfData,FloatPtr);
260 				#else
261 					SizeOfData = iCurImage->SizeOfData / 16;  // 4*4
262 					for (i = 0; i < SizeOfData; i++) {
263 						TempFloat = FloatPtr[0];
264 						FloatPtr[0] = FloatPtr[2];
265 						FloatPtr[2] = TempFloat;
266 						FloatPtr += 4;
267 					}
268 				#endif
269 					return IL_TRUE;
270 
271 				case IL_DOUBLE:
272 				#ifdef ALTIVEC_GCC
273 					abcd2cbad_double(DblPtr,iCurImage->SizeOfData,DblPtr);
274 				#else
275 					SizeOfData = iCurImage->SizeOfData / 32;  // 4*8
276 					for (i = 0; i < SizeOfData; i++) {
277 						TempDbl = DblPtr[0];
278 						DblPtr[0] = DblPtr[2];
279 						DblPtr[2] = TempDbl;
280 						DblPtr += 4;
281 					}
282 				#endif
283 					return IL_TRUE;
284 			}
285 	}
286 
287 
288 	return IL_FALSE;
289 }
290 
291