98e75f2d |
1 | /* |
2 | * Texture Filtering |
3 | * Version: 1.0 |
4 | * |
5 | * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. |
6 | * Email koolsmoky(at)users.sourceforge.net |
7 | * Web http://www.3dfxzone.it/koolsmoky |
8 | * |
9 | * this is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2, or (at your option) |
12 | * any later version. |
13 | * |
14 | * this is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with GNU Make; see the file COPYING. If not, write to |
21 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ |
23 | |
24 | #ifdef __MSC__ |
25 | #pragma warning(disable: 4786) |
26 | #endif |
27 | |
28 | #include <functional> |
29 | #include <thread> |
30 | |
31 | /* NOTE: The codes are not optimized. They can be made faster. */ |
32 | |
33 | #include "TxQuantize.h" |
34 | |
35 | TxQuantize::TxQuantize() |
36 | { |
37 | _txUtil = new TxUtil(); |
38 | |
39 | /* get number of CPU cores. */ |
40 | _numcore = _txUtil->getNumberofProcessors(); |
41 | |
42 | /* get dxtn extensions */ |
43 | _tx_compress_fxt1 = TxLoadLib::getInstance()->getfxtCompressTexFuncExt(); |
44 | _tx_compress_dxtn = TxLoadLib::getInstance()->getdxtCompressTexFuncExt(); |
45 | } |
46 | |
47 | |
48 | TxQuantize::~TxQuantize() |
49 | { |
50 | delete _txUtil; |
51 | } |
52 | |
53 | void |
54 | TxQuantize::ARGB1555_ARGB8888(uint32* src, uint32* dest, int width, int height) |
55 | { |
56 | #if 1 |
57 | int siz = (width * height) >> 1; |
58 | int i; |
59 | for (i = 0; i < siz; i++) { |
60 | *dest = (((*src & 0x00008000) ? 0xff000000 : 0x00000000) | |
61 | ((*src & 0x00007c00) << 9) | ((*src & 0x00007000) << 4) | |
62 | ((*src & 0x000003e0) << 6) | ((*src & 0x00000380) << 1) | |
63 | ((*src & 0x0000001f) << 3) | ((*src & 0x0000001c) >> 2)); |
64 | dest++; |
65 | *dest = (((*src & 0x80000000) ? 0xff000000 : 0x00000000) | |
66 | ((*src & 0x7c000000) >> 7) | ((*src & 0x70000000) >> 12) | |
67 | ((*src & 0x03e00000) >> 10) | ((*src & 0x03800000) >> 15) | |
68 | ((*src & 0x001f0000) >> 13) | ((*src & 0x001c0000) >> 18)); |
69 | dest++; |
70 | src++; |
71 | } |
72 | #else |
73 | int siz = (width * height) >> 1; |
74 | |
75 | __asm { |
76 | push ebx; |
77 | push esi; |
78 | push edi; |
79 | |
80 | mov esi, dword ptr [src]; |
81 | mov edi, dword ptr [dest]; |
82 | mov ecx, dword ptr [siz]; |
83 | |
84 | tc1_loop: |
85 | mov eax, dword ptr [esi]; |
86 | add esi, 4; |
87 | |
88 | // arrr rrgg gggb bbbb |
89 | // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
90 | mov edx, eax; // edx = arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
91 | mov ebx, 0x00000000; |
92 | and eax, 0x00008000; // eax = 00000000 00000000 a0000000 00000000 |
93 | jz transparent1; |
94 | mov ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 00000000 |
95 | |
96 | transparent1: |
97 | mov eax, edx; // eax = arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
98 | and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 00000000 |
99 | shl edx, 4; // edx = 00000000 00000rrr rr000000 00000000 |
100 | or ebx, edx; // ebx = aaaaaaaa 00000rrr rr000000 00000000 |
101 | shl edx, 5; // edx = 00000000 rrrrr000 00000000 00000000 |
102 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr rr000000 00000000 |
103 | and ebx, 0xffff0000; // ebx = aaaaaaaa rrrrrrrr 00000000 00000000 |
104 | mov edx, eax; |
105 | and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg00000 |
106 | shl edx, 1; // edx = 00000000 00000000 00000ggg gg000000 |
107 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr 00000ggg gg000000 |
108 | shl edx, 5; // edx = 00000000 00000000 ggggg000 00000000 |
109 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg gg000000 |
110 | and ebx, 0xffffff00; // ebx = aaaaaaaa rrrrrrrr gggggggg 00000000 |
111 | mov edx, eax; |
112 | and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb |
113 | shl edx, 3; // edx = 00000000 00000000 00000000 bbbbb000 |
114 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbb000 |
115 | shr edx, 5; // edx = 00000000 00000000 00000000 00000bbb |
116 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
117 | |
118 | mov dword ptr [edi], ebx; |
119 | add edi, 4; |
120 | |
121 | shr eax, 16; // eax = 00000000 00000000 arrrrrgg gggbbbbb |
122 | mov edx, eax; // edx = 00000000 00000000 arrrrrgg gggbbbbb |
123 | mov ebx, 0x00000000; |
124 | and eax, 0x00008000; // eax = 00000000 00000000 a0000000 00000000 |
125 | jz transparent2; |
126 | mov ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 00000000 |
127 | |
128 | transparent2: |
129 | mov eax, edx; // eax = 00000000 00000000 arrrrrgg gggbbbbb |
130 | and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 00000000 |
131 | shl edx, 4; // edx = 00000000 00000rrr rr000000 00000000 |
132 | or ebx, edx; // ebx = aaaaaaaa 00000rrr rr000000 00000000 |
133 | shl edx, 5; // edx = 00000000 rrrrr000 00000000 00000000 |
134 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr rr000000 00000000 |
135 | and ebx, 0xffff0000; // ebx = aaaaaaaa rrrrrrrr 00000000 00000000 |
136 | mov edx, eax; |
137 | and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg00000 |
138 | shl edx, 1; // edx = 00000000 00000000 00000ggg gg000000 |
139 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr 00000ggg gg000000 |
140 | shl edx, 5; // edx = 00000000 00000000 ggggg000 00000000 |
141 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg gg000000 |
142 | and ebx, 0xffffff00; // ebx = aaaaaaaa rrrrrrrr gggggggg 00000000 |
143 | mov edx, eax; |
144 | and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb |
145 | shl edx, 3; // edx = 00000000 00000000 00000000 bbbbb000 |
146 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbb000 |
147 | shr edx, 5; // edx = 00000000 00000000 00000000 00000bbb |
148 | or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
149 | |
150 | mov dword ptr [edi], ebx; |
151 | add edi, 4; |
152 | |
153 | dec ecx; |
154 | jnz tc1_loop; |
155 | |
156 | pop edi; |
157 | pop esi; |
158 | pop ebx; |
159 | } |
160 | #endif |
161 | } |
162 | |
163 | void |
164 | TxQuantize::ARGB4444_ARGB8888(uint32* src, uint32* dest, int width, int height) |
165 | { |
166 | #if 1 |
167 | int siz = (width * height) >> 1; |
168 | int i; |
169 | for (i = 0; i < siz; i++) { |
170 | *dest = ((*src & 0x0000f000) << 12) | |
171 | ((*src & 0x00000f00) << 8) | |
172 | ((*src & 0x000000f0) << 4) | |
173 | (*src & 0x0000000f); |
174 | *dest |= (*dest << 4); |
175 | dest++; |
176 | *dest = ((*src & 0xf0000000) | |
177 | ((*src & 0x0f000000) >> 4) | |
178 | ((*src & 0x00f00000) >> 8) | |
179 | ((*src & 0x000f0000) >> 12)); |
180 | *dest |= (*dest >> 4); |
181 | dest++; |
182 | src++; |
183 | } |
184 | #else |
185 | int siz = (width * height) >> 1; |
186 | |
187 | __asm { |
188 | push ebx; |
189 | push esi; |
190 | push edi; |
191 | |
192 | mov esi, dword ptr [src]; |
193 | mov edi, dword ptr [dest]; |
194 | mov ecx, dword ptr [siz]; |
195 | |
196 | tc1_loop: |
197 | mov eax, dword ptr [esi]; |
198 | add esi, 4; |
199 | |
200 | // aaaa rrrr gggg bbbb |
201 | // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
202 | mov edx, eax; |
203 | and eax, 0x0000ffff; |
204 | mov ebx, eax; // 00000000 00000000 aaaarrrr ggggbbbb |
205 | and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 00000000 |
206 | shl ebx, 12; // 0000aaaa 00000000 00000000 00000000 |
207 | or eax, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb |
208 | mov ebx, eax; |
209 | and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 00000000 |
210 | shl ebx, 8; // 00000000 0000rrrr 00000000 00000000 |
211 | or eax, ebx; // 0000aaaa 0000rrrr aaaarrrr ggggbbbb |
212 | mov ebx, eax; |
213 | and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg0000 |
214 | shl ebx, 4; // 00000000 00000000 0000gggg 00000000 |
215 | and eax, 0x0f0f000f; // 0000aaaa 0000rrrr 00000000 0000bbbb |
216 | or eax, ebx; // 0000aaaa 0000rrrr 0000gggg 0000bbbb |
217 | mov ebx, eax; |
218 | shl ebx, 4; // aaaa0000 rrrr0000 gggg0000 bbbb0000 |
219 | or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
220 | |
221 | mov dword ptr [edi], eax; |
222 | add edi, 4; |
223 | |
224 | shr edx, 16; |
225 | mov ebx, edx; // 00000000 00000000 aaaarrrr ggggbbbb |
226 | and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 00000000 |
227 | shl ebx, 12; // 0000aaaa 00000000 00000000 00000000 |
228 | or edx, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb |
229 | mov ebx, edx; |
230 | and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 00000000 |
231 | shl ebx, 8; // 00000000 0000rrrr 00000000 00000000 |
232 | or edx, ebx; // 0000aaaa 0000rrrr aaaarrrr ggggbbbb |
233 | mov ebx, edx; |
234 | and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg0000 |
235 | shl ebx, 4; // 00000000 00000000 0000gggg 00000000 |
236 | and edx, 0x0f0f000f; // 0000aaaa 0000rrrr 00000000 0000bbbb |
237 | or edx, ebx; // 0000aaaa 0000rrrr 0000gggg 0000bbbb |
238 | mov ebx, edx; |
239 | shl ebx, 4; // aaaa0000 rrrr0000 gggg0000 bbbb0000 |
240 | or edx, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
241 | |
242 | mov dword ptr [edi], edx; |
243 | add edi, 4; |
244 | |
245 | dec ecx; |
246 | jnz tc1_loop; |
247 | |
248 | pop edi; |
249 | pop esi; |
250 | pop ebx; |
251 | } |
252 | #endif |
253 | } |
254 | |
255 | void |
256 | TxQuantize::RGB565_ARGB8888(uint32* src, uint32* dest, int width, int height) |
257 | { |
258 | #if 1 |
259 | int siz = (width * height) >> 1; |
260 | int i; |
261 | for (i = 0; i < siz; i++) { |
262 | *dest = (0xff000000 | |
263 | ((*src & 0x0000f800) << 8) | ((*src & 0x0000e000) << 3) | |
264 | ((*src & 0x000007e0) << 5) | ((*src & 0x00000600) >> 1) | |
265 | ((*src & 0x0000001f) << 3) | ((*src & 0x0000001c) >> 2)); |
266 | dest++; |
267 | *dest = (0xff000000 | |
268 | ((*src & 0xf8000000) >> 8) | ((*src & 0xe0000000) >> 13) | |
269 | ((*src & 0x07e00000) >> 11) | ((*src & 0x06000000) >> 17) | |
270 | ((*src & 0x001f0000) >> 13) | ((*src & 0x001c0000) >> 18)); |
271 | dest++; |
272 | src++; |
273 | } |
274 | #else |
275 | int siz = (width * height) >> 1; |
276 | |
277 | __asm { |
278 | push ebx; |
279 | push esi; |
280 | push edi; |
281 | |
282 | mov esi, dword ptr [src]; |
283 | mov edi, dword ptr [dest]; |
284 | mov ecx, dword ptr [siz]; |
285 | |
286 | tc1_loop: |
287 | mov eax, dword ptr [esi]; |
288 | add esi, 4; |
289 | |
290 | // rrrr rggg gggb bbbb |
291 | // 11111111 rrrrrrrr gggggggg bbbbbbbb |
292 | mov edx, eax; |
293 | and eax, 0x0000ffff; |
294 | mov ebx, eax; // 00000000 00000000 rrrrrggg gggbbbbb |
295 | and ebx, 0x0000f800; // 00000000 00000000 rrrrr000 00000000 |
296 | shl ebx, 5; // 00000000 000rrrrr 00000000 00000000 |
297 | or eax, ebx; // 00000000 000rrrrr rrrrrggg gggbbbbb |
298 | mov ebx, eax; |
299 | and ebx, 0x000007e0; // 00000000 00000000 00000ggg ggg00000 |
300 | shl ebx, 5; // 00000000 00000000 gggggg00 00000000 |
301 | and eax, 0x001F001F; // 00000000 000rrrrr 00000000 000bbbbb |
302 | shl eax, 3; // 00000000 rrrrr000 00000000 bbbbb000 |
303 | or eax, ebx; // 00000000 rrrrr000 gggggg00 bbbbb000 |
304 | mov ebx, eax; |
305 | shr ebx, 5; // 00000000 00000rrr rr000ggg ggg00bbb |
306 | and ebx, 0x00070007; // 00000000 00000rrr 00000000 00000bbb |
307 | or eax, ebx; // 00000000 rrrrrrrr gggggg00 bbbbbbbb |
308 | mov ebx, eax; |
309 | shr ebx, 6; |
310 | and ebx, 0x00000300; // 00000000 00000000 000000gg 00000000 |
311 | or eax, ebx // 00000000 rrrrrrrr gggggggg bbbbbbbb |
312 | or eax, 0xff000000; // 11111111 rrrrrrrr gggggggg bbbbbbbb |
313 | |
314 | mov dword ptr [edi], eax; |
315 | add edi, 4; |
316 | |
317 | shr edx, 16; |
318 | mov eax, edx; // 00000000 00000000 rrrrrggg gggbbbbb |
319 | and eax, 0x0000ffff; |
320 | mov ebx, eax; // 00000000 00000000 rrrrrggg gggbbbbb |
321 | and ebx, 0x0000f800; // 00000000 00000000 rrrrr000 00000000 |
322 | shl ebx, 5; // 00000000 000rrrrr 00000000 00000000 |
323 | or eax, ebx; // 00000000 000rrrrr rrrrrggg gggbbbbb |
324 | mov ebx, eax; |
325 | and ebx, 0x000007e0; // 00000000 00000000 00000ggg ggg00000 |
326 | shl ebx, 5; // 00000000 00000000 gggggg00 00000000 |
327 | and eax, 0x001F001F; // 00000000 000rrrrr 00000000 000bbbbb |
328 | shl eax, 3; // 00000000 rrrrr000 00000000 bbbbb000 |
329 | or eax, ebx; // 00000000 rrrrr000 gggggg00 bbbbb000 |
330 | mov ebx, eax; |
331 | shr ebx, 5; // 00000000 00000rrr rr000ggg ggg00bbb |
332 | and ebx, 0x00070007; // 00000000 00000rrr 00000000 00000bbb |
333 | or eax, ebx; // 00000000 rrrrrrrr gggggg00 bbbbbbbb |
334 | mov ebx, eax; |
335 | shr ebx, 6; |
336 | and ebx, 0x00000300; // 00000000 00000000 000000gg 00000000 |
337 | or eax, ebx // 00000000 rrrrrrrr gggggggg bbbbbbbb |
338 | or eax, 0xff000000; // 11111111 rrrrrrrr gggggggg bbbbbbbb |
339 | |
340 | mov dword ptr [edi], eax; |
341 | add edi, 4; |
342 | |
343 | dec ecx; |
344 | jnz tc1_loop; |
345 | |
346 | pop edi; |
347 | pop esi; |
348 | pop ebx; |
349 | } |
350 | #endif |
351 | } |
352 | |
353 | void |
354 | TxQuantize::A8_ARGB8888(uint32* src, uint32* dest, int width, int height) |
355 | { |
356 | #if 1 |
357 | int siz = (width * height) >> 2; |
358 | int i; |
359 | for (i = 0; i < siz; i++) { |
360 | *dest = (*src & 0x000000ff); |
361 | *dest |= (*dest << 8); |
362 | *dest |= (*dest << 16); |
363 | dest++; |
364 | *dest = (*src & 0x0000ff00); |
365 | *dest |= (*dest >> 8); |
366 | *dest |= (*dest << 16); |
367 | dest++; |
368 | *dest = (*src & 0x00ff0000); |
369 | *dest |= (*dest << 8); |
370 | *dest |= (*dest >> 16); |
371 | dest++; |
372 | *dest = (*src & 0xff000000); |
373 | *dest |= (*dest >> 8); |
374 | *dest |= (*dest >> 16); |
375 | dest++; |
376 | src++; |
377 | } |
378 | #else |
379 | int siz = (width * height) >> 2; |
380 | |
381 | __asm { |
382 | push ebx; |
383 | push esi; |
384 | push edi; |
385 | |
386 | mov esi, dword ptr [src]; |
387 | mov edi, dword ptr [dest]; |
388 | mov ecx, dword ptr [siz]; |
389 | |
390 | tc1_loop: |
391 | mov eax, dword ptr [esi]; |
392 | add esi, 4; |
393 | |
394 | // aaaaaaaa |
395 | // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
396 | mov edx, eax; |
397 | and eax, 0x000000ff; |
398 | mov ebx, eax; // 00000000 00000000 00000000 aaaaaaaa |
399 | shl ebx, 8; // 00000000 00000000 aaaaaaaa 00000000 |
400 | or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa |
401 | mov ebx, eax; |
402 | shl ebx, 16; // aaaaaaaa aaaaaaaa 00000000 00000000 |
403 | or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
404 | |
405 | mov dword ptr [edi], eax; |
406 | add edi, 4; |
407 | |
408 | mov eax, edx; |
409 | and eax, 0x0000ff00; |
410 | mov ebx, eax; // 00000000 00000000 aaaaaaaa 00000000 |
411 | shr ebx, 8; // 00000000 00000000 00000000 aaaaaaaa |
412 | or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa |
413 | mov ebx, eax; |
414 | shl ebx, 16; // aaaaaaaa aaaaaaaa 00000000 00000000 |
415 | or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
416 | |
417 | mov dword ptr [edi], eax; |
418 | add edi, 4; |
419 | |
420 | mov eax, edx; |
421 | and eax, 0x00ff0000; |
422 | mov ebx, eax; // 00000000 aaaaaaaa 00000000 00000000 |
423 | shl ebx, 8; // aaaaaaaa 00000000 00000000 00000000 |
424 | or eax, ebx; // aaaaaaaa aaaaaaaa 00000000 00000000 |
425 | mov ebx, eax; |
426 | shr ebx, 16; // 00000000 00000000 aaaaaaaa aaaaaaaa |
427 | or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
428 | |
429 | mov dword ptr [edi], eax; |
430 | add edi, 4; |
431 | |
432 | mov eax, edx; |
433 | and eax, 0xff000000; |
434 | mov ebx, eax; // aaaaaaaa 00000000 00000000 00000000 |
435 | shr ebx, 8; // 00000000 aaaaaaaa 00000000 00000000 |
436 | or eax, ebx; // aaaaaaaa aaaaaaaa 00000000 00000000 |
437 | mov ebx, eax; |
438 | shr ebx, 16; // 00000000 00000000 aaaaaaaa aaaaaaaa |
439 | or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb |
440 | |
441 | mov dword ptr [edi], eax; |
442 | add edi, 4; |
443 | |
444 | dec ecx; |
445 | jnz tc1_loop; |
446 | |
447 | pop edi; |
448 | pop esi; |
449 | pop ebx; |
450 | } |
451 | #endif |
452 | } |
453 | |
454 | void |
455 | TxQuantize::AI44_ARGB8888(uint32* src, uint32* dest, int width, int height) |
456 | { |
457 | #if 1 |
458 | int siz = (width * height) >> 2; |
459 | int i; |
460 | for (i = 0; i < siz; i++) { |
461 | *dest = (*src & 0x0000000f); |
462 | *dest |= ((*dest << 8) | (*dest << 16)); |
463 | *dest |= ((*src & 0x000000f0) << 20); |
464 | *dest |= (*dest << 4); |
465 | dest++; |
466 | *dest = (*src & 0x00000f00); |
467 | *dest |= ((*dest << 8) | (*dest >> 8)); |
468 | *dest |= ((*src & 0x0000f000) << 12); |
469 | *dest |= (*dest << 4); |
470 | dest++; |
471 | *dest = (*src & 0x000f0000); |
472 | *dest |= ((*dest >> 8) | (*dest >> 16)); |
473 | *dest |= ((*src & 0x00f00000) << 4); |
474 | *dest |= (*dest << 4); |
475 | dest++; |
476 | *dest = ((*src & 0x0f000000) >> 4); |
477 | *dest |= ((*dest >> 8) | (*dest >> 16)); |
478 | *dest |= (*src & 0xf0000000); |
479 | *dest |= (*dest >> 4); |
480 | dest++; |
481 | src++; |
482 | } |
483 | #else |
484 | int siz = (width * height) >> 2; |
485 | |
486 | __asm { |
487 | push ebx; |
488 | push esi; |
489 | push edi; |
490 | |
491 | mov esi, dword ptr [src]; |
492 | mov edi, dword ptr [dest]; |
493 | mov ecx, dword ptr [siz]; |
494 | |
495 | tc1_loop: |
496 | mov eax, dword ptr [esi]; |
497 | add esi, 4; |
498 | |
499 | // aaaaiiii |
500 | // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
501 | mov edx, eax; |
502 | and eax, 0x000000f0; // 00000000 00000000 00000000 aaaa0000 |
503 | mov ebx, edx; |
504 | shl eax, 20; // 0000aaaa 00000000 00000000 00000000 |
505 | and ebx, 0x0000000f; // 00000000 00000000 00000000 0000iiii |
506 | or eax, ebx; // 0000aaaa 00000000 00000000 0000iiii |
507 | shl ebx, 8; // 00000000 00000000 0000iiii 00000000 |
508 | or eax, ebx; // 0000aaaa 00000000 0000iiii 0000iiii |
509 | shl ebx, 8; // 00000000 0000iiii 00000000 00000000 |
510 | or eax, ebx; // 0000aaaa 0000iiii 0000iiii 0000iiii |
511 | mov ebx, eax; |
512 | shl ebx, 4; // aaaa0000 iiii0000 iiii0000 iiii0000 |
513 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
514 | |
515 | mov dword ptr [edi], eax; |
516 | add edi, 4; |
517 | |
518 | mov eax, edx; |
519 | and eax, 0x0000f000; // 00000000 00000000 aaaa0000 00000000 |
520 | mov ebx, edx; |
521 | shl eax, 12; // 0000aaaa 00000000 00000000 00000000 |
522 | and ebx, 0x00000f00; // 00000000 00000000 0000iiii 00000000 |
523 | or eax, ebx; // 0000aaaa 00000000 0000iiii 00000000 |
524 | shr ebx, 8; // 00000000 00000000 00000000 0000iiii |
525 | or eax, ebx; // 0000aaaa 00000000 0000iiii 0000iiii |
526 | shl ebx, 16; // 00000000 0000iiii 00000000 00000000 |
527 | or eax, ebx; // 0000aaaa 0000iiii 0000iiii 0000iiii |
528 | mov ebx, eax; |
529 | shl ebx, 4; // aaaa0000 iiii0000 iiii0000 iiii0000 |
530 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
531 | |
532 | mov dword ptr [edi], eax; |
533 | add edi, 4; |
534 | |
535 | mov eax, edx; |
536 | and eax, 0x00f00000; // 00000000 aaaa0000 00000000 00000000 |
537 | mov ebx, edx; |
538 | shl eax, 4; // 0000aaaa 00000000 00000000 00000000 |
539 | and ebx, 0x000f0000; // 00000000 0000iiii 00000000 00000000 |
540 | or eax, ebx; // 0000aaaa 0000iiii 00000000 00000000 |
541 | shr ebx, 8; // 00000000 00000000 0000iiii 00000000 |
542 | or eax, ebx; // 0000aaaa 0000iiii 0000iiii 00000000 |
543 | shr ebx, 8; // 00000000 00000000 00000000 0000iiii |
544 | or eax, ebx; // 0000aaaa 0000iiii 0000iiii 0000iiii |
545 | mov ebx, eax; |
546 | shl ebx, 4; // aaaa0000 iiii0000 iiii0000 iiii0000 |
547 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
548 | |
549 | mov dword ptr [edi], eax; |
550 | add edi, 4; |
551 | |
552 | mov eax, edx; |
553 | and eax, 0xf0000000; // aaaa0000 00000000 00000000 00000000 |
554 | mov ebx, edx; |
555 | and ebx, 0x0f000000; // 0000iiii 00000000 00000000 00000000 |
556 | shr ebx, 4; // 00000000 iiii0000 00000000 00000000 |
557 | or eax, ebx; // aaaa0000 iiii0000 00000000 00000000 |
558 | shr ebx, 8; // 00000000 00000000 iiii0000 00000000 |
559 | or eax, ebx; // aaaa0000 iiii0000 iiii0000 00000000 |
560 | shr ebx, 8; // 00000000 00000000 00000000 iiii0000 |
561 | or eax, ebx; // aaaa0000 iiii0000 iiii0000 iiii0000 |
562 | mov ebx, eax; |
563 | shr ebx, 4; // 0000aaaa 0000iiii 0000iiii 0000iiii |
564 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
565 | |
566 | mov dword ptr [edi], eax; |
567 | add edi, 4; |
568 | |
569 | dec ecx; |
570 | jnz tc1_loop; |
571 | |
572 | pop edi; |
573 | pop esi; |
574 | pop ebx; |
575 | } |
576 | #endif |
577 | } |
578 | |
579 | void |
580 | TxQuantize::AI88_ARGB8888(uint32* src, uint32* dest, int width, int height) |
581 | { |
582 | #if 1 |
583 | int siz = (width * height) >> 1; |
584 | int i; |
585 | for (i = 0; i < siz; i++) { |
586 | *dest = (*src & 0x000000ff); |
587 | *dest |= ((*dest << 8) | (*dest << 16)); |
588 | *dest |= ((*src & 0x0000ff00) << 16); |
589 | dest++; |
590 | *dest = (*src & 0x00ff0000); |
591 | *dest |= ((*dest >> 8) | (*dest >> 16)); |
592 | *dest |= (*src & 0xff000000); |
593 | dest++; |
594 | src++; |
595 | } |
596 | #else |
597 | int siz = (width * height) >> 1; |
598 | |
599 | __asm { |
600 | push ebx; |
601 | push esi; |
602 | push edi; |
603 | |
604 | mov esi, dword ptr [src]; |
605 | mov edi, dword ptr [dest]; |
606 | mov ecx, dword ptr [siz]; |
607 | |
608 | tc1_loop: |
609 | mov eax, dword ptr [esi]; |
610 | add esi, 4; |
611 | |
612 | // aaaaaaaa iiiiiiii |
613 | // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
614 | mov edx, eax; |
615 | and eax, 0x0000ffff; // 00000000 00000000 aaaaaaaa iiiiiiii |
616 | mov ebx, eax; // 00000000 00000000 aaaaaaaa iiiiiiii |
617 | shl eax, 16; // aaaaaaaa iiiiiiii 00000000 00000000 |
618 | and ebx, 0x000000ff; // 00000000 00000000 00000000 iiiiiiii |
619 | or eax, ebx; // aaaaaaaa iiiiiiii 00000000 iiiiiiii |
620 | shl ebx, 8; // 00000000 00000000 iiiiiiii 00000000 |
621 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
622 | |
623 | mov dword ptr [edi], eax; |
624 | add edi, 4; |
625 | |
626 | mov eax, edx; |
627 | and eax, 0xffff0000; // aaaaaaaa iiiiiiii 00000000 00000000 |
628 | mov ebx, eax; // aaaaaaaa iiiiiiii 00000000 00000000 |
629 | and ebx, 0x00ff0000; // 00000000 iiiiiiii 00000000 00000000 |
630 | shr ebx, 8; // 00000000 00000000 iiiiiiii 00000000 |
631 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii 00000000 |
632 | shr ebx, 8; // 00000000 00000000 00000000 iiiiiiii |
633 | or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii |
634 | |
635 | mov dword ptr [edi], eax; |
636 | add edi, 4; |
637 | |
638 | dec ecx; |
639 | jnz tc1_loop; |
640 | |
641 | pop edi; |
642 | pop esi; |
643 | pop ebx; |
644 | } |
645 | #endif |
646 | } |
647 | |
648 | void |
649 | TxQuantize::ARGB8888_ARGB1555(uint32* src, uint32* dest, int width, int height) |
650 | { |
651 | #if 1 |
652 | int siz = (width * height) >> 1; |
653 | int i; |
654 | for (i = 0; i < siz; i++) { |
655 | *dest = ((*src & 0xff000000) ? 0x00008000 : 0x00000000); |
656 | *dest |= (((*src & 0x00f80000) >> 9) | |
657 | ((*src & 0x0000f800) >> 6) | |
658 | ((*src & 0x000000f8) >> 3)); |
659 | src++; |
660 | *dest |= ((*src & 0xff000000) ? 0x80000000 : 0x00000000); |
661 | *dest |= (((*src & 0x00f80000) << 7) | |
662 | ((*src & 0x0000f800) << 10) | |
663 | ((*src & 0x000000f8) << 13)); |
664 | src++; |
665 | dest++; |
666 | } |
667 | #else |
668 | int siz = (width * height) >> 1; |
669 | |
670 | __asm { |
671 | push ebx; |
672 | push esi; |
673 | push edi; |
674 | |
675 | mov esi, dword ptr [src]; |
676 | mov edi, dword ptr [dest]; |
677 | mov ecx, dword ptr [siz]; |
678 | |
679 | tc1_loop: |
680 | mov eax, dword ptr [esi]; |
681 | add esi, 4; |
682 | |
683 | #if 1 |
684 | mov edx, eax; |
685 | and eax, 0xff000000; // aaaa0000 00000000 00000000 00000000 |
686 | jz transparent1; |
687 | mov eax, 0x00008000; // 00000000 00000000 a0000000 00000000 |
688 | |
689 | transparent1: |
690 | mov ebx, edx; |
691 | and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000 |
692 | shr ebx, 9; // 00000000 00000000 0rrrrr00 00000000 |
693 | or eax, ebx; // 00000000 00000000 arrrrr00 00000000 |
694 | mov ebx, edx; |
695 | and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000 |
696 | shr ebx, 6; // 00000000 00000000 000000gg ggg00000 |
697 | or eax, ebx; // 00000000 00000000 arrrrrgg ggg00000 |
698 | and edx, 0x000000f8; // 00000000 00000000 00000000 bbbbb000 |
699 | shr edx, 3; // 00000000 00000000 00000000 000bbbbb |
700 | or edx, eax; // 00000000 00000000 arrrrrgg gggbbbbb |
701 | |
702 | mov eax, dword ptr [esi]; |
703 | add esi, 4; |
704 | |
705 | mov ebx, eax; |
706 | and eax, 0xff000000; // aaaa0000 00000000 00000000 00000000 |
707 | jz transparent2; |
708 | or edx, 0x80000000; // a0000000 00000000 arrrrrgg gggbbbbb |
709 | |
710 | transparent2: |
711 | mov eax, ebx; |
712 | and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000 |
713 | shl ebx, 7; // 0rrrrr00 00000000 00000000 00000000 |
714 | or edx, ebx; // arrrrr00 00000000 arrrrrgg gggbbbbb |
715 | mov ebx, eax; |
716 | and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000 |
717 | shl ebx, 10; // 000000gg ggg00000 00000000 00000000 |
718 | or edx, ebx; // arrrrrgg ggg00000 arrrrrgg gggbbbbb |
719 | and eax, 0x000000f8; // 00000000 00000000 00000000 bbbbb000 |
720 | shl eax, 13; // 00000000 000bbbbb 00000000 00000000 |
721 | or edx, eax; // arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
722 | |
723 | mov dword ptr [edi], edx; |
724 | add edi, 4; |
725 | #else |
726 | mov edx, eax; |
727 | and edx, 0x01000000; // 0000000a 00000000 00000000 00000000 |
728 | shr edx, 9; // 00000000 00000000 a0000000 00000000 |
729 | mov ebx, eax; |
730 | and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000 |
731 | shr ebx, 9; // 00000000 00000000 0rrrrr00 00000000 |
732 | or edx, ebx; // 00000000 00000000 arrrrr00 00000000 |
733 | mov ebx, eax; |
734 | and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000 |
735 | shr ebx, 6; // 00000000 00000000 000000gg ggg00000 |
736 | or edx, ebx; // 00000000 00000000 arrrrrgg ggg00000 |
737 | and eax, 0x000000f8; // 00000000 00000000 00000000 bbbbb000 |
738 | shr eax, 3; // 00000000 00000000 00000000 000bbbbb |
739 | or edx, eax; // 00000000 00000000 arrrrrgg gggbbbbb |
740 | |
741 | mov eax, dword ptr [esi]; |
742 | add esi, 4; |
743 | |
744 | mov ebx, eax; |
745 | and ebx, 0x80000000; // a0000000 00000000 00000000 00000000 |
746 | or edx, ebx; // a0000000 00000000 arrrrrgg gggbbbbb |
747 | mov ebx, eax; |
748 | and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000 |
749 | shl ebx, 7; // 0rrrrr00 00000000 00000000 00000000 |
750 | or edx, ebx; // arrrrr00 00000000 arrrrrgg gggbbbbb |
751 | mov ebx, eax; |
752 | and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000 |
753 | shl ebx, 10; // 000000gg ggg00000 00000000 00000000 |
754 | or edx, ebx; // arrrrrgg ggg00000 arrrrrgg gggbbbbb |
755 | and eax, 0x000000f8; // 00000000 00000000 00000000 bbbbb000 |
756 | shl eax, 13; // 00000000 000bbbbb 00000000 00000000 |
757 | or edx, eax; // arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
758 | |
759 | mov dword ptr [edi], edx; |
760 | add edi, 4; |
761 | #endif |
762 | dec ecx; |
763 | jnz tc1_loop; |
764 | |
765 | pop edi; |
766 | pop esi; |
767 | pop ebx; |
768 | } |
769 | #endif |
770 | } |
771 | |
772 | void |
773 | TxQuantize::ARGB8888_ARGB4444(uint32* src, uint32* dest, int width, int height) |
774 | { |
775 | #if 1 |
776 | int siz = (width * height) >> 1; |
777 | int i; |
778 | for (i = 0; i < siz; i++) { |
779 | *dest = (((*src & 0xf0000000) >> 16) | |
780 | ((*src & 0x00f00000) >> 12) | |
781 | ((*src & 0x0000f000) >> 8) | |
782 | ((*src & 0x000000f0) >> 4)); |
783 | src++; |
784 | *dest |= ((*src & 0xf0000000) | |
785 | ((*src & 0x00f00000) << 4) | |
786 | ((*src & 0x0000f000) << 8) | |
787 | ((*src & 0x000000f0) << 12)); |
788 | src++; |
789 | dest++; |
790 | } |
791 | #else |
792 | int siz = (width * height) >> 1; |
793 | |
794 | __asm { |
795 | push ebx; |
796 | push esi; |
797 | push edi; |
798 | |
799 | mov esi, dword ptr [src]; |
800 | mov edi, dword ptr [dest]; |
801 | mov ecx, dword ptr [siz]; |
802 | |
803 | tc1_loop: |
804 | mov eax, dword ptr [esi]; |
805 | add esi, 4; |
806 | |
807 | mov edx, eax; |
808 | and edx, 0xf0000000; // aaaa0000 00000000 00000000 00000000 |
809 | shr edx, 16; // 00000000 00000000 aaaa0000 00000000 |
810 | mov ebx, eax; |
811 | and ebx, 0x00f00000; // 00000000 rrrr0000 00000000 00000000 |
812 | shr ebx, 12; // 00000000 00000000 0000rrrr 00000000 |
813 | or edx, ebx; // 00000000 00000000 aaaarrrr 00000000 |
814 | mov ebx, eax; |
815 | and ebx, 0x0000f000; // 00000000 00000000 gggg0000 00000000 |
816 | shr ebx, 8; // 00000000 00000000 00000000 gggg0000 |
817 | or edx, ebx; // 00000000 00000000 aaaarrrr gggg0000 |
818 | and eax, 0x000000f0; // 00000000 00000000 00000000 bbbb0000 |
819 | shr eax, 4; // 00000000 00000000 00000000 0000bbbb |
820 | or edx, eax; // 00000000 00000000 aaaarrrr ggggbbbb |
821 | |
822 | mov eax, dword ptr [esi]; |
823 | add esi, 4; |
824 | |
825 | mov ebx, eax; |
826 | and ebx, 0xf0000000; // aaaa0000 00000000 00000000 00000000 |
827 | or edx, ebx; // aaaa0000 00000000 aaaarrrr ggggbbbb |
828 | mov ebx, eax; |
829 | and ebx, 0x00f00000; // 00000000 rrrr0000 00000000 00000000 |
830 | shl ebx, 4; // 0000rrrr 00000000 00000000 00000000 |
831 | or edx, ebx; // aaaarrrr 00000000 aaaarrrr ggggbbbb |
832 | mov ebx, eax; |
833 | and ebx, 0x0000f000; // 00000000 00000000 gggg0000 00000000 |
834 | shl ebx, 8; // 00000000 gggg0000 00000000 00000000 |
835 | or edx, ebx; // aaaarrrr gggg0000 aaaarrrr ggggbbbb |
836 | and eax, 0x000000f0; // 00000000 00000000 00000000 bbbb0000 |
837 | shl eax, 12; // 00000000 0000bbbb 00000000 00000000 |
838 | or edx, eax; // arrrrrgg ggggbbbb aaaarrrr ggggbbbb |
839 | |
840 | mov dword ptr [edi], edx; |
841 | add edi, 4; |
842 | |
843 | dec ecx; |
844 | jnz tc1_loop; |
845 | |
846 | pop edi; |
847 | pop esi; |
848 | pop ebx; |
849 | } |
850 | #endif |
851 | } |
852 | |
853 | void |
854 | TxQuantize::ARGB8888_RGB565(uint32* src, uint32* dest, int width, int height) |
855 | { |
856 | #if 1 |
857 | int siz = (width * height) >> 1; |
858 | int i; |
859 | for (i = 0; i < siz; i++) { |
860 | *dest = (((*src & 0x000000f8) >> 3) | |
861 | ((*src & 0x0000fc00) >> 5) | |
862 | ((*src & 0x00f80000) >> 8)); |
863 | src++; |
864 | *dest |= (((*src & 0x000000f8) << 13) | |
865 | ((*src & 0x0000fc00) << 11) | |
866 | ((*src & 0x00f80000) << 8)); |
867 | src++; |
868 | dest++; |
869 | } |
870 | #else |
871 | int siz = (width * height) >> 1; |
872 | |
873 | __asm { |
874 | push ebx; |
875 | push esi; |
876 | push edi; |
877 | |
878 | mov esi, dword ptr [src]; |
879 | mov edi, dword ptr [dest]; |
880 | mov ecx, dword ptr [siz]; |
881 | |
882 | tc1_loop: |
883 | mov eax, dword ptr [esi]; |
884 | add esi, 4; |
885 | |
886 | mov edx, eax; |
887 | and edx, 0x000000F8; // 00000000 00000000 00000000 bbbbb000 |
888 | shr edx, 3; // 00000000 00000000 00000000 000bbbbb |
889 | mov ebx, eax; |
890 | and ebx, 0x0000FC00; // 00000000 00000000 gggggg00 00000000 |
891 | shr ebx, 5; // 00000000 00000000 00000ggg ggg00000 |
892 | or edx, ebx; // 00000000 00000000 00000ggg gggbbbbb |
893 | mov ebx, eax; |
894 | and ebx, 0x00F80000; // 00000000 rrrrr000 00000000 00000000 |
895 | shr ebx, 8; // 00000000 00000000 rrrrr000 00000000 |
896 | or edx, ebx; // 00000000 00000000 rrrrrggg gggbbbbb |
897 | |
898 | mov eax, dword ptr [esi]; |
899 | add esi, 4; |
900 | |
901 | mov ebx, eax; |
902 | and ebx, 0x000000F8; // 00000000 00000000 00000000 bbbbb000 |
903 | shl ebx, 13; // 00000000 000bbbbb 00000000 00000000 |
904 | or edx, ebx; // 00000000 000bbbbb rrrrrggg gggbbbbb |
905 | mov ebx, eax; |
906 | and ebx, 0x0000FC00; // 00000000 00000000 gggggg00 00000000 |
907 | shl ebx, 11; // 00000ggg ggg00000 00000000 00000000 |
908 | or edx, ebx; // 00000ggg gggbbbbb rrrrrggg gggbbbbb |
909 | mov ebx, eax; |
910 | and ebx, 0x00F80000; // 00000000 rrrrr000 00000000 00000000 |
911 | shl ebx, 8; // rrrrr000 00000000 00000000 00000000 |
912 | or edx, ebx; // rrrrrggg gggbbbbb rrrrrggg gggbbbbb |
913 | |
914 | mov dword ptr [edi], edx; |
915 | add edi, 4; |
916 | |
917 | dec ecx; |
918 | jnz tc1_loop; |
919 | |
920 | pop edi; |
921 | pop esi; |
922 | pop ebx; |
923 | } |
924 | #endif |
925 | } |
926 | |
927 | void |
928 | TxQuantize::ARGB8888_A8(uint32* src, uint32* dest, int width, int height) |
929 | { |
930 | #if 1 |
931 | int siz = (width * height) >> 2; |
932 | int i; |
933 | for (i = 0; i < siz; i++) { |
934 | *dest = (*src & 0x0000ff00) >> 8; |
935 | src++; |
936 | *dest |= (*src & 0x0000ff00); |
937 | src++; |
938 | *dest |= ((*src & 0x0000ff00) << 8); |
939 | src++; |
940 | *dest |= ((*src & 0x0000ff00) << 16); |
941 | src++; |
942 | dest++; |
943 | } |
944 | #else |
945 | int siz = (width * height) >> 2; |
946 | |
947 | __asm { |
948 | push ebx; |
949 | push esi; |
950 | push edi; |
951 | |
952 | mov esi, dword ptr [src]; |
953 | mov edi, dword ptr [dest]; |
954 | mov ecx, dword ptr [siz]; |
955 | |
956 | tc1_loop: |
957 | mov eax, dword ptr [esi]; |
958 | add esi, 4; |
959 | |
960 | #if 0 |
961 | mov edx, eax; // we'll use A comp for every pixel |
962 | and edx, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
963 | shr edx, 24; // 00000000 00000000 00000000 aaaaaaaa |
964 | |
965 | mov eax, dword ptr [esi]; |
966 | add esi, 4; |
967 | |
968 | and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
969 | shr eax, 16; // 00000000 00000000 aaaaaaaa 00000000 |
970 | or edx, eax; // 00000000 00000000 aaaaaaaa aaaaaaaa |
971 | |
972 | mov eax, dword ptr [esi]; |
973 | add esi, 4; |
974 | |
975 | and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
976 | shr eax, 8; // 00000000 aaaaaaaa 00000000 00000000 |
977 | or edx, eax; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
978 | |
979 | mov eax, dword ptr [esi]; |
980 | add esi, 4; |
981 | |
982 | and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
983 | or edx, eax; // aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa |
984 | #endif |
985 | |
986 | #if 1 |
987 | mov edx, eax; // we'll use G comp for every pixel |
988 | and edx, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000 |
989 | shr edx, 8; // 00000000 00000000 00000000 aaaaaaaa |
990 | |
991 | mov eax, dword ptr [esi]; |
992 | add esi, 4; |
993 | |
994 | and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000 |
995 | or edx, eax; // 00000000 00000000 aaaaaaaa aaaaaaaa |
996 | |
997 | mov eax, dword ptr [esi]; |
998 | add esi, 4; |
999 | |
1000 | and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000 |
1001 | shl eax, 8; // 00000000 aaaaaaaa 00000000 00000000 |
1002 | or edx, eax; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
1003 | |
1004 | mov eax, dword ptr [esi]; |
1005 | add esi, 4; |
1006 | |
1007 | and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000 |
1008 | shl eax, 16; // aaaaaaaa 00000000 00000000 00000000 |
1009 | or edx, eax; // aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa |
1010 | #endif |
1011 | |
1012 | #if 0 |
1013 | mov edx, eax; |
1014 | and edx, 0x000000FF; // 00000000 00000000 00000000 aaaaaaaa |
1015 | |
1016 | mov eax, dword ptr [esi]; |
1017 | add esi, 4; |
1018 | |
1019 | and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000 |
1020 | or edx, eax; // 00000000 00000000 aaaaaaaa aaaaaaaa |
1021 | |
1022 | mov eax, dword ptr [esi]; |
1023 | add esi, 4; |
1024 | |
1025 | and eax, 0x00FF0000; // 00000000 aaaaaaaa 00000000 00000000 |
1026 | or edx, eax; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
1027 | |
1028 | mov eax, dword ptr [esi]; |
1029 | add esi, 4; |
1030 | |
1031 | and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
1032 | or edx, eax; // aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa |
1033 | #endif |
1034 | mov dword ptr [edi], edx; |
1035 | add edi, 4; |
1036 | |
1037 | dec ecx; |
1038 | jnz tc1_loop; |
1039 | |
1040 | pop edi; |
1041 | pop esi; |
1042 | pop ebx; |
1043 | } |
1044 | #endif |
1045 | } |
1046 | |
1047 | void |
1048 | TxQuantize::ARGB8888_AI44(uint32* src, uint32* dest, int width, int height) |
1049 | { |
1050 | #if 1 |
1051 | int siz = (width * height) >> 2; |
1052 | int i; |
1053 | for (i = 0; i < siz; i++) { |
1054 | *dest = (((*src & 0xf0000000) >> 24) | ((*src & 0x0000f000) >> 12)); |
1055 | src++; |
1056 | *dest |= (((*src & 0xf0000000) >> 16) | ((*src & 0x0000f000) >> 4)); |
1057 | src++; |
1058 | *dest |= (((*src & 0xf0000000) >> 8) | ((*src & 0x0000f000) << 4)); |
1059 | src++; |
1060 | *dest |= ((*src & 0xf0000000) | ((*src & 0x0000f000) << 12)); |
1061 | src++; |
1062 | dest++; |
1063 | } |
1064 | #else |
1065 | int siz = (width * height) >> 2; |
1066 | |
1067 | __asm { |
1068 | push ebx; |
1069 | push esi; |
1070 | push edi; |
1071 | |
1072 | mov esi, dword ptr [src]; |
1073 | mov edi, dword ptr [dest]; |
1074 | mov ecx, dword ptr [siz]; |
1075 | |
1076 | tc1_loop: |
1077 | mov eax, dword ptr [esi]; |
1078 | add esi, 4; |
1079 | |
1080 | mov edx, eax; // use A and G comps MSB |
1081 | and edx, 0xF0000000; // aaaa0000 00000000 00000000 00000000 |
1082 | mov ebx, eax; |
1083 | shr edx, 24; // 00000000 00000000 00000000 aaaa0000 |
1084 | and ebx, 0x0000F000; // 00000000 00000000 iiii0000 00000000 |
1085 | shr ebx, 12; // 00000000 00000000 00000000 0000iiii |
1086 | or edx, ebx; // 00000000 00000000 00000000 aaaaiiii |
1087 | |
1088 | mov eax, dword ptr [esi]; |
1089 | add esi, 4; |
1090 | |
1091 | mov ebx, eax; |
1092 | and eax, 0xF0000000; // aaaa0000 00000000 00000000 00000000 |
1093 | shr eax, 16; // 00000000 00000000 aaaa0000 00000000 |
1094 | and ebx, 0x0000F000; // 00000000 00000000 iiii0000 00000000 |
1095 | shr ebx, 4; // 00000000 00000000 0000iiii 00000000 |
1096 | or eax, ebx; // 00000000 00000000 aaaaiiii 00000000 |
1097 | or edx, eax; // 00000000 00000000 aaaaiiii aaaaiiii |
1098 | |
1099 | mov eax, dword ptr [esi]; |
1100 | add esi, 4; |
1101 | |
1102 | mov ebx, eax; |
1103 | and eax, 0xF0000000; // aaaa0000 00000000 00000000 00000000 |
1104 | shr eax, 8; // 00000000 aaaa0000 00000000 00000000 |
1105 | and ebx, 0x0000F000; // 00000000 00000000 iiii0000 00000000 |
1106 | shl ebx, 4; // 00000000 0000iiii 00000000 00000000 |
1107 | or eax, ebx; // 00000000 aaaaiiii 00000000 00000000 |
1108 | or edx, eax; // 00000000 aaaaiiii aaaaiiii aaaaiiii |
1109 | |
1110 | mov eax, dword ptr [esi]; |
1111 | add esi, 4; |
1112 | |
1113 | mov ebx, eax; |
1114 | and eax, 0xF0000000; // aaaa0000 00000000 00000000 00000000 |
1115 | and ebx, 0x0000F000; // 00000000 00000000 iiii0000 00000000 |
1116 | shl ebx, 12; // 0000iiii 00000000 00000000 00000000 |
1117 | or eax, ebx; // aaaaiiii 00000000 00000000 00000000 |
1118 | or edx, eax; // aaaaiiii aaaaiiii aaaaiiii aaaaiiii |
1119 | |
1120 | mov dword ptr [edi], edx; |
1121 | add edi, 4; |
1122 | |
1123 | dec ecx; |
1124 | jnz tc1_loop; |
1125 | |
1126 | pop edi; |
1127 | pop esi; |
1128 | pop ebx; |
1129 | } |
1130 | #endif |
1131 | } |
1132 | |
1133 | void |
1134 | TxQuantize::ARGB8888_AI88(uint32* src, uint32* dest, int width, int height) |
1135 | { |
1136 | #if 1 |
1137 | int siz = (width * height) >> 1; |
1138 | int i; |
1139 | for (i = 0; i < siz; i++) { |
1140 | *dest = (((*src & 0xff000000) >> 16) | ((*src & 0x0000ff00) >> 8)); |
1141 | src++; |
1142 | *dest |= ((*src & 0xff000000) | ((*src & 0x0000ff00) << 8)); |
1143 | src++; |
1144 | dest++; |
1145 | } |
1146 | #else |
1147 | int siz = (width * height) >> 1; |
1148 | |
1149 | __asm { |
1150 | push ebx; |
1151 | push esi; |
1152 | push edi; |
1153 | |
1154 | mov esi, dword ptr [src]; |
1155 | mov edi, dword ptr [dest]; |
1156 | mov ecx, dword ptr [siz]; |
1157 | |
1158 | tc1_loop: |
1159 | mov eax, dword ptr [esi]; |
1160 | add esi, 4; |
1161 | |
1162 | mov edx, eax; |
1163 | and edx, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
1164 | mov ebx, eax; |
1165 | shr edx, 16; // 00000000 00000000 aaaaaaaa 00000000 |
1166 | and ebx, 0x0000FF00; // 00000000 00000000 iiiiiiii 00000000 |
1167 | shr ebx, 8; // 00000000 00000000 00000000 iiiiiiii |
1168 | or edx, ebx; // 00000000 00000000 aaaaaaaa iiiiiiii |
1169 | |
1170 | mov eax, dword ptr [esi]; |
1171 | add esi, 4; |
1172 | |
1173 | mov ebx, eax; |
1174 | and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000 |
1175 | and ebx, 0x0000FF00; // 00000000 00000000 iiiiiiii 00000000 |
1176 | shl ebx, 8; // 00000000 iiiiiiii 00000000 00000000 |
1177 | or eax, ebx; // aaaaaaaa iiiiiiii 00000000 00000000 |
1178 | or edx, eax; // aaaaaaaa iiiiiiii aaaaaaaa iiiiiiii |
1179 | |
1180 | mov dword ptr [edi], edx; |
1181 | add edi, 4; |
1182 | |
1183 | dec ecx; |
1184 | jnz tc1_loop; |
1185 | |
1186 | pop edi; |
1187 | pop esi; |
1188 | pop ebx; |
1189 | } |
1190 | #endif |
1191 | } |
1192 | |
1193 | /* R.W. Floyd and L. Steinberg, An adaptive algorithm |
1194 | * for spatial grey scale, Proceedings of the Society |
1195 | * of Information Display 17, pp75-77, 1976 |
1196 | */ |
1197 | void |
1198 | TxQuantize::ARGB8888_RGB565_ErrD(uint32* src, uint32* dst, int width, int height) |
1199 | { |
1200 | /* Floyd-Steinberg error-diffusion halftoning */ |
1201 | |
1202 | int i, x, y; |
1203 | int qr, qg, qb; /* quantized incoming values */ |
1204 | int ir, ig, ib; /* incoming values */ |
1205 | int t; |
1206 | int *errR = new int[width]; |
1207 | int *errG = new int[width]; |
1208 | int *errB = new int[width]; |
1209 | |
1210 | uint16 *dest = (uint16 *)dst; |
1211 | |
1212 | for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = 0; |
1213 | |
1214 | for (y = 0; y < height; y++) { |
1215 | qr = qg = qb = 0; |
1216 | for (x = 0; x < width; x++) { |
1217 | /* incoming pixel values */ |
1218 | ir = ((*src >> 16) & 0xFF) * 10000; |
1219 | ig = ((*src >> 8) & 0xFF) * 10000; |
1220 | ib = ((*src ) & 0xFF) * 10000; |
1221 | |
1222 | /* quantize pixel values. |
1223 | * qr * 0.4375 is the error from the pixel to the left, |
1224 | * errR is the error from the pixel to the top, top left, and top right */ |
1225 | /* qr * 0.4375 is the error distribution to the EAST in |
1226 | * the previous loop */ |
1227 | ir += errR[x] + qr * 4375 / 10000; |
1228 | ig += errG[x] + qg * 4375 / 10000; |
1229 | ib += errB[x] + qb * 4375 / 10000; |
1230 | |
1231 | /* error distribution to the SOUTH-EAST in the previous loop |
1232 | * can't calculate in the previous loop because it steps on |
1233 | * the above quantization */ |
1234 | errR[x] = qr * 625 / 10000; |
1235 | errG[x] = qg * 625 / 10000; |
1236 | errB[x] = qb * 625 / 10000; |
1237 | |
1238 | qr = ir; |
1239 | qg = ig; |
1240 | qb = ib; |
1241 | |
1242 | /* clamp */ |
1243 | if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000; |
1244 | if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000; |
1245 | if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000; |
1246 | |
1247 | /* convert to RGB565 */ |
1248 | qr = qr * 0x1F / 2550000; |
1249 | qg = qg * 0x3F / 2550000; |
1250 | qb = qb * 0x1F / 2550000; |
1251 | |
1252 | /* this is the dithered pixel */ |
1253 | t = (qr << 11) | (qg << 5) | qb; |
1254 | |
1255 | /* compute the errors */ |
1256 | qr = ((qr << 3) | (qr >> 2)) * 10000; |
1257 | qg = ((qg << 2) | (qg >> 4)) * 10000; |
1258 | qb = ((qb << 3) | (qb >> 2)) * 10000; |
1259 | qr = ir - qr; |
1260 | qg = ig - qg; |
1261 | qb = ib - qb; |
1262 | |
1263 | /* compute the error distributions */ |
1264 | /* Floyd-Steinberg filter |
1265 | * 7/16 (=0.4375) to the EAST |
1266 | * 5/16 (=0.3125) to the SOUTH |
1267 | * 1/16 (=0.0625) to the SOUTH-EAST |
1268 | * 3/16 (=0.1875) to the SOUTH-WEST |
1269 | * |
1270 | * x 7/16 |
1271 | * 3/16 5/16 1/16 |
1272 | */ |
1273 | /* SOUTH-WEST */ |
1274 | if (x > 1) { |
1275 | errR[x - 1] += qr * 1875 / 10000; |
1276 | errG[x - 1] += qg * 1875 / 10000; |
1277 | errB[x - 1] += qb * 1875 / 10000; |
1278 | } |
1279 | |
1280 | /* SOUTH */ |
1281 | errR[x] += qr * 3125 / 10000; |
1282 | errG[x] += qg * 3125 / 10000; |
1283 | errB[x] += qb * 3125 / 10000; |
1284 | |
1285 | *dest = (t & 0xFFFF); |
1286 | |
1287 | dest++; |
1288 | src++; |
1289 | } |
1290 | } |
1291 | |
1292 | delete [] errR; |
1293 | delete [] errG; |
1294 | delete [] errB; |
1295 | } |
1296 | |
1297 | |
1298 | void |
1299 | TxQuantize::ARGB8888_ARGB1555_ErrD(uint32* src, uint32* dst, int width, int height) |
1300 | { |
1301 | /* Floyd-Steinberg error-diffusion halftoning */ |
1302 | |
1303 | int i, x, y; |
1304 | int qr, qg, qb; /* quantized incoming values */ |
1305 | int ir, ig, ib; /* incoming values */ |
1306 | int t; |
1307 | int *errR = new int[width]; |
1308 | int *errG = new int[width]; |
1309 | int *errB = new int[width]; |
1310 | |
1311 | uint16 *dest = (uint16 *)dst; |
1312 | |
1313 | for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = 0; |
1314 | |
1315 | for (y = 0; y < height; y++) { |
1316 | qr = qg = qb = 0; |
1317 | for (x = 0; x < width; x++) { |
1318 | /* incoming pixel values */ |
1319 | ir = ((*src >> 16) & 0xFF) * 10000; |
1320 | ig = ((*src >> 8) & 0xFF) * 10000; |
1321 | ib = ((*src ) & 0xFF) * 10000; |
1322 | |
1323 | /* quantize pixel values. |
1324 | * qr * 0.4375 is the error from the pixel to the left, |
1325 | * errR is the error from the pixel to the top, top left, and top right */ |
1326 | /* qr * 0.4375 is the error distribution to the EAST in |
1327 | * the previous loop */ |
1328 | ir += errR[x] + qr * 4375 / 10000; |
1329 | ig += errG[x] + qg * 4375 / 10000; |
1330 | ib += errB[x] + qb * 4375 / 10000; |
1331 | |
1332 | /* error distribution to the SOUTH-EAST of the previous loop. |
1333 | * cannot calculate in the previous loop because it steps on |
1334 | * the above quantization */ |
1335 | errR[x] = qr * 625 / 10000; |
1336 | errG[x] = qg * 625 / 10000; |
1337 | errB[x] = qb * 625 / 10000; |
1338 | |
1339 | qr = ir; |
1340 | qg = ig; |
1341 | qb = ib; |
1342 | |
1343 | /* clamp */ |
1344 | if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000; |
1345 | if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000; |
1346 | if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000; |
1347 | |
1348 | /* convert to RGB555 */ |
1349 | qr = qr * 0x1F / 2550000; |
1350 | qg = qg * 0x1F / 2550000; |
1351 | qb = qb * 0x1F / 2550000; |
1352 | |
1353 | /* this is the dithered pixel */ |
1354 | t = (qr << 10) | (qg << 5) | qb; |
1355 | t |= ((*src >> 24) ? 0x8000 : 0); |
1356 | |
1357 | /* compute the errors */ |
1358 | qr = ((qr << 3) | (qr >> 2)) * 10000; |
1359 | qg = ((qg << 3) | (qg >> 2)) * 10000; |
1360 | qb = ((qb << 3) | (qb >> 2)) * 10000; |
1361 | qr = ir - qr; |
1362 | qg = ig - qg; |
1363 | qb = ib - qb; |
1364 | |
1365 | /* compute the error distributions */ |
1366 | /* Floyd-Steinberg filter |
1367 | * 7/16 (=0.4375) to the EAST |
1368 | * 5/16 (=0.3125) to the SOUTH |
1369 | * 1/16 (=0.0625) to the SOUTH-EAST |
1370 | * 3/16 (=0.1875) to the SOUTH-WEST |
1371 | * |
1372 | * x 7/16 |
1373 | * 3/16 5/16 1/16 |
1374 | */ |
1375 | /* SOUTH-WEST */ |
1376 | if (x > 1) { |
1377 | errR[x - 1] += qr * 1875 / 10000; |
1378 | errG[x - 1] += qg * 1875 / 10000; |
1379 | errB[x - 1] += qb * 1875 / 10000; |
1380 | } |
1381 | |
1382 | /* SOUTH */ |
1383 | errR[x] += qr * 3125 / 10000; |
1384 | errG[x] += qg * 3125 / 10000; |
1385 | errB[x] += qb * 3125 / 10000; |
1386 | |
1387 | *dest = (t & 0xFFFF); |
1388 | |
1389 | dest++; |
1390 | src++; |
1391 | } |
1392 | } |
1393 | |
1394 | delete [] errR; |
1395 | delete [] errG; |
1396 | delete [] errB; |
1397 | } |
1398 | |
1399 | void |
1400 | TxQuantize::ARGB8888_ARGB4444_ErrD(uint32* src, uint32* dst, int width, int height) |
1401 | { |
1402 | /* Floyd-Steinberg error-diffusion halftoning */ |
1403 | |
1404 | /* NOTE: alpha dithering looks better for alpha gradients, but are prone |
1405 | * to producing noisy speckles for constant or step level alpha. Output |
1406 | * results should always be checked. |
1407 | */ |
1408 | boolean ditherAlpha = 0; |
1409 | |
1410 | int i, x, y; |
1411 | int qr, qg, qb, qa; /* quantized incoming values */ |
1412 | int ir, ig, ib, ia; /* incoming values */ |
1413 | int t; |
1414 | int *errR = new int[width]; |
1415 | int *errG = new int[width]; |
1416 | int *errB = new int[width]; |
1417 | int *errA = new int[width]; |
1418 | |
1419 | uint16 *dest = (uint16 *)dst; |
1420 | |
1421 | for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = errA[i] = 0; |
1422 | |
1423 | for (y = 0; y < height; y++) { |
1424 | qr = qg = qb = qa = 0; |
1425 | for (x = 0; x < width; x++) { |
1426 | /* incoming pixel values */ |
1427 | ir = ((*src >> 16) & 0xFF) * 10000; |
1428 | ig = ((*src >> 8) & 0xFF) * 10000; |
1429 | ib = ((*src ) & 0xFF) * 10000; |
1430 | ia = ((*src >> 24) & 0xFF) * 10000; |
1431 | |
1432 | /* quantize pixel values. |
1433 | * qr * 0.4375 is the error from the pixel to the left, |
1434 | * errR is the error from the pixel to the top, top left, and top right */ |
1435 | /* qr * 0.4375 is the error distribution to the EAST in |
1436 | * the previous loop */ |
1437 | ir += errR[x] + qr * 4375 / 10000; |
1438 | ig += errG[x] + qg * 4375 / 10000; |
1439 | ib += errB[x] + qb * 4375 / 10000; |
1440 | ia += errA[x] + qa * 4375 / 10000; |
1441 | |
1442 | /* error distribution to the SOUTH-EAST of the previous loop. |
1443 | * cannot calculate in the previous loop because it steps on |
1444 | * the above quantization */ |
1445 | errR[x] = qr * 625 / 10000; |
1446 | errG[x] = qg * 625 / 10000; |
1447 | errB[x] = qb * 625 / 10000; |
1448 | errA[x] = qa * 625 / 10000; |
1449 | |
1450 | qr = ir; |
1451 | qg = ig; |
1452 | qb = ib; |
1453 | qa = ia; |
1454 | |
1455 | /* clamp */ |
1456 | if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000; |
1457 | if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000; |
1458 | if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000; |
1459 | if (qa < 0) qa = 0; else if (qa > 2550000) qa = 2550000; |
1460 | |
1461 | /* convert to RGB444 */ |
1462 | qr = qr * 0xF / 2550000; |
1463 | qg = qg * 0xF / 2550000; |
1464 | qb = qb * 0xF / 2550000; |
1465 | qa = qa * 0xF / 2550000; |
1466 | |
1467 | /* this is the value to be returned */ |
1468 | if (ditherAlpha) { |
1469 | t = (qa << 12) | (qr << 8) | (qg << 4) | qb; |
1470 | } else { |
1471 | t = (qr << 8) | (qg << 4) | qb; |
1472 | t |= (*src >> 16) & 0xF000; |
1473 | } |
1474 | |
1475 | /* compute the errors */ |
1476 | qr = ((qr << 4) | qr) * 10000; |
1477 | qg = ((qg << 4) | qg) * 10000; |
1478 | qb = ((qb << 4) | qb) * 10000; |
1479 | qa = ((qa << 4) | qa) * 10000; |
1480 | qr = ir - qr; |
1481 | qg = ig - qg; |
1482 | qb = ib - qb; |
1483 | qa = ia - qa; |
1484 | |
1485 | /* compute the error distributions */ |
1486 | /* Floyd-Steinberg filter |
1487 | * 7/16 (=0.4375) to the EAST |
1488 | * 5/16 (=0.3125) to the SOUTH |
1489 | * 1/16 (=0.0625) to the SOUTH-EAST |
1490 | * 3/16 (=0.1875) to the SOUTH-WEST |
1491 | * |
1492 | * x 7/16 |
1493 | * 3/16 5/16 1/16 |
1494 | */ |
1495 | /* SOUTH-WEST */ |
1496 | if (x > 1) { |
1497 | errR[x - 1] += qr * 1875 / 10000; |
1498 | errG[x - 1] += qg * 1875 / 10000; |
1499 | errB[x - 1] += qb * 1875 / 10000; |
1500 | errA[x - 1] += qa * 1875 / 10000; |
1501 | } |
1502 | |
1503 | /* SOUTH */ |
1504 | errR[x] += qr * 3125 / 10000; |
1505 | errG[x] += qg * 3125 / 10000; |
1506 | errB[x] += qb * 3125 / 10000; |
1507 | errA[x] += qa * 3125 / 10000; |
1508 | |
1509 | *dest = (t & 0xFFFF); |
1510 | |
1511 | dest++; |
1512 | src++; |
1513 | } |
1514 | } |
1515 | |
1516 | delete [] errR; |
1517 | delete [] errG; |
1518 | delete [] errB; |
1519 | delete [] errA; |
1520 | } |
1521 | |
1522 | void |
1523 | TxQuantize::ARGB8888_AI44_ErrD(uint32* src, uint32* dst, int width, int height) |
1524 | { |
1525 | /* Floyd-Steinberg error-diffusion halftoning */ |
1526 | |
1527 | /* NOTE: alpha dithering looks better for alpha gradients, but are prone |
1528 | * to producing noisy speckles for constant or step level alpha. Output |
1529 | * results should always be checked. |
1530 | */ |
1531 | boolean ditherAlpha = 0; |
1532 | |
1533 | int i, x, y; |
1534 | int qi, qa; /* quantized incoming values */ |
1535 | int ii, ia; /* incoming values */ |
1536 | int t; |
1537 | int *errI = new int[width]; |
1538 | int *errA = new int[width]; |
1539 | |
1540 | uint8 *dest = (uint8 *)dst; |
1541 | |
1542 | for (i = 0; i < width; i++) errI[i] = errA[i] = 0; |
1543 | |
1544 | for (y = 0; y < height; y++) { |
1545 | qi = qa = 0; |
1546 | for (x = 0; x < width; x++) { |
1547 | /* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 */ |
1548 | ii = ((*src >> 16) & 0xFF) * 2990 + |
1549 | ((*src >> 8) & 0xFF) * 5870 + |
1550 | ((*src ) & 0xFF) * 1140; |
1551 | ia = ((*src >> 24) & 0xFF) * 10000; |
1552 | |
1553 | /* quantize pixel values. |
1554 | * qi * 0.4375 is the error from the pixel to the left, |
1555 | * errI is the error from the pixel to the top, top left, and top right */ |
1556 | /* qi * 0.4375 is the error distrtibution to the EAST in |
1557 | * the previous loop */ |
1558 | ii += errI[x] + qi * 4375 / 10000; |
1559 | ia += errA[x] + qa * 4375 / 10000; |
1560 | |
1561 | /* error distribution to the SOUTH-EAST in the previous loop. |
1562 | * cannot calculate in the previous loop because it steps on |
1563 | * the above quantization */ |
1564 | errI[x] = qi * 625 / 10000; |
1565 | errA[x] = qa * 625 / 10000; |
1566 | |
1567 | qi = ii; |
1568 | qa = ia; |
1569 | |
1570 | /* clamp */ |
1571 | if (qi < 0) qi = 0; else if (qi > 2550000) qi = 2550000; |
1572 | if (qa < 0) qa = 0; else if (qa > 2550000) qa = 2550000; |
1573 | |
1574 | /* convert to I4 */ |
1575 | qi = qi * 0xF / 2550000; |
1576 | qa = qa * 0xF / 2550000; |
1577 | |
1578 | /* this is the value to be returned */ |
1579 | if (ditherAlpha) { |
1580 | t = (qa << 4) | qi; |
1581 | } else { |
1582 | t = qi; |
1583 | t |= ((*src >> 24) & 0xF0); |
1584 | } |
1585 | |
1586 | /* compute the errors */ |
1587 | qi = ((qi << 4) | qi) * 10000; |
1588 | qa = ((qa << 4) | qa) * 10000; |
1589 | qi = ii - qi; |
1590 | qa = ia - qa; |
1591 | |
1592 | /* compute the error distributions */ |
1593 | /* Floyd-Steinberg filter |
1594 | * 7/16 (=0.4375) to the EAST |
1595 | * 5/16 (=0.3125) to the SOUTH |
1596 | * 1/16 (=0.0625) to the SOUTH-EAST |
1597 | * 3/16 (=0.1875) to the SOUTH-WEST |
1598 | * |
1599 | * x 7/16 |
1600 | * 3/16 5/16 1/16 |
1601 | */ |
1602 | /* SOUTH-WEST */ |
1603 | if (x > 1) { |
1604 | errI[x - 1] += qi * 1875 / 10000; |
1605 | errA[x - 1] += qa * 1875 / 10000; |
1606 | } |
1607 | |
1608 | /* SOUTH */ |
1609 | errI[x] += qi * 3125 / 10000; |
1610 | errA[x] += qa * 3125 / 10000; |
1611 | |
1612 | *dest = t & 0xFF; |
1613 | |
1614 | dest++; |
1615 | src++; |
1616 | } |
1617 | } |
1618 | |
1619 | delete [] errI; |
1620 | delete [] errA; |
1621 | } |
1622 | |
1623 | void |
1624 | TxQuantize::ARGB8888_AI88_Slow(uint32* src, uint32* dst, int width, int height) |
1625 | { |
1626 | int x, y; |
1627 | uint16 *dest = (uint16 *)dst; |
1628 | for (y = 0; y < height; y++) { |
1629 | for (x = 0; x < width; x++) { |
1630 | #if 1 |
1631 | /* libpng style grayscale conversion. |
1632 | * Reduce RGB files to grayscale with or without alpha |
1633 | * using the equation given in Poynton's ColorFAQ at |
1634 | * <http://www.inforamp.net/~poynton/> |
1635 | * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net |
1636 | * |
1637 | * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B |
1638 | * |
1639 | * We approximate this with |
1640 | * |
1641 | * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B |
1642 | * |
1643 | * which can be expressed with integers as |
1644 | * |
1645 | * Y = (6969 * R + 23434 * G + 2365 * B)/32768 |
1646 | * |
1647 | * The calculation is to be done in a linear colorspace. |
1648 | */ |
1649 | *dest = (((int)((((*src >> 16) & 0xFF) * 6969 + |
1650 | ((*src >> 8) & 0xFF) * 23434 + |
1651 | ((*src ) & 0xFF) * 2365) / 32768) & 0xFF) | |
1652 | (uint16)((*src >> 16) & 0xFF00)); |
1653 | #else |
1654 | /* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 |
1655 | * this is same as the standard NTSC gray scale conversion. */ |
1656 | *dest = (((int)((((*src >> 16) & 0xFF) * 299 + |
1657 | ((*src >> 8) & 0xFF) * 587 + |
1658 | ((*src ) & 0xFF) * 114) / 1000) & 0xFF) | |
1659 | (uint16)((*src >> 16) & 0xFF00)); |
1660 | #endif |
1661 | dest++; |
1662 | src++; |
1663 | } |
1664 | } |
1665 | } |
1666 | |
1667 | void |
1668 | TxQuantize::ARGB8888_I8_Slow(uint32* src, uint32* dst, int width, int height) |
1669 | { |
1670 | int x, y; |
1671 | uint8 *dest = (uint8 *)dst; |
1672 | for (y = 0; y < height; y++) { |
1673 | for (x = 0; x < width; x++) { |
1674 | #if 1 |
1675 | /* libpng style Intensity = (6969 * R + 23434 * G + 2365 * B)/32768 */ |
1676 | *dest = (int)((((*src >> 16) & 0xFF) * 6969 + |
1677 | ((*src >> 8) & 0xFF) * 23434 + |
1678 | ((*src ) & 0xFF) * 2365) / 32768) & 0xFF; |
1679 | #else |
1680 | /* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 |
1681 | * this is same as the standard NTSC gray scale conversion. */ |
1682 | *dest = (int)((((*src >>16) & 0xFF) * 299 + |
1683 | ((*src >> 8) & 0xFF) * 587 + |
1684 | ((*src ) & 0xFF) * 114) / 1000) & 0xFF; |
1685 | #endif |
1686 | dest++; |
1687 | src++; |
1688 | } |
1689 | } |
1690 | } |
1691 | |
1692 | void |
1693 | TxQuantize::P8_16BPP(uint32* src, uint32* dest, int width, int height, uint32* palette) |
1694 | { |
1695 | /* passed in palette is RGBA5551 format */ |
1696 | #if 1 |
1697 | int i; |
1698 | int size = width * height; |
1699 | for (i = 0; i < size; i++) { |
1700 | ((uint16*)dest)[i] = ((uint16*)palette)[(int)(((uint8*)src)[i])]; |
1701 | ((uint16*)dest)[i] = ((((uint16*)dest)[i] << 15) | (((uint16*)dest)[i] >> 1)); |
1702 | } |
1703 | #else |
1704 | |
1705 | /* not finished yet... */ |
1706 | |
1707 | int siz = (width * height) >> 2; |
1708 | |
1709 | __asm { |
1710 | push ebx; |
1711 | push esi; |
1712 | push edi; |
1713 | |
1714 | mov esi, dword ptr [src]; |
1715 | mov edi, dword ptr [dest]; |
1716 | mov ecx, dword ptr [siz]; |
1717 | mov edx, dword ptr [palette]; |
1718 | |
1719 | tc1_loop: |
1720 | mov eax, dword ptr [esi]; |
1721 | add esi, 4; |
1722 | |
1723 | dec ecx; |
1724 | jnz tc1_loop; |
1725 | |
1726 | pop edi; |
1727 | pop esi; |
1728 | pop ebx; |
1729 | } |
1730 | #endif |
1731 | } |
1732 | |
1733 | boolean |
1734 | TxQuantize::quantize(uint8* src, uint8* dest, int width, int height, uint16 srcformat, uint16 destformat, boolean fastQuantizer) |
1735 | { |
1736 | typedef void (TxQuantize::*quantizerFunc)(uint32* src, uint32* dest, int width, int height); |
1737 | quantizerFunc quantizer; |
1738 | int bpp_shift = 0; |
1739 | |
1740 | if (destformat == GR_TEXFMT_ARGB_8888) { |
1741 | switch (srcformat) { |
1742 | case GR_TEXFMT_ARGB_1555: |
1743 | quantizer = &TxQuantize::ARGB1555_ARGB8888; |
1744 | bpp_shift = 1; |
1745 | break; |
1746 | case GR_TEXFMT_ARGB_4444: |
1747 | quantizer = &TxQuantize::ARGB4444_ARGB8888; |
1748 | bpp_shift = 1; |
1749 | break; |
1750 | case GR_TEXFMT_RGB_565: |
1751 | quantizer = &TxQuantize::RGB565_ARGB8888; |
1752 | bpp_shift = 1; |
1753 | break; |
1754 | case GR_TEXFMT_ALPHA_8: |
1755 | quantizer = &TxQuantize::A8_ARGB8888; |
1756 | bpp_shift = 2; |
1757 | break; |
1758 | case GR_TEXFMT_ALPHA_INTENSITY_44: |
1759 | quantizer = &TxQuantize::AI44_ARGB8888; |
1760 | bpp_shift = 2; |
1761 | break; |
1762 | case GR_TEXFMT_ALPHA_INTENSITY_88: |
1763 | quantizer = &TxQuantize::AI88_ARGB8888; |
1764 | bpp_shift = 1; |
1765 | break; |
1766 | default: |
1767 | return 0; |
1768 | } |
1769 | |
1770 | #if !defined(NO_FILTER_THREAD) |
1771 | unsigned int numcore = _numcore; |
1772 | unsigned int blkrow = 0; |
1773 | while (numcore > 1 && blkrow == 0) { |
1774 | blkrow = (height >> 2) / numcore; |
1775 | numcore--; |
1776 | } |
1777 | if (blkrow > 0 && numcore > 1) { |
1778 | std::thread *thrd[MAX_NUMCORE]; |
1779 | unsigned int i; |
1780 | int blkheight = blkrow << 2; |
1781 | unsigned int srcStride = (width * blkheight) << (2 - bpp_shift); |
1782 | unsigned int destStride = srcStride << bpp_shift; |
1783 | for (i = 0; i < numcore - 1; i++) { |
1784 | thrd[i] = new std::thread(std::bind(quantizer, |
1785 | this, |
1786 | (uint32*)src, |
1787 | (uint32*)dest, |
1788 | width, |
1789 | blkheight)); |
1790 | src += srcStride; |
1791 | dest += destStride; |
1792 | } |
1793 | thrd[i] = new std::thread(std::bind(quantizer, |
1794 | this, |
1795 | (uint32*)src, |
1796 | (uint32*)dest, |
1797 | width, |
1798 | height - blkheight * i)); |
1799 | for (i = 0; i < numcore; i++) { |
1800 | thrd[i]->join(); |
1801 | delete thrd[i]; |
1802 | } |
1803 | } else { |
1804 | (*this.*quantizer)((uint32*)src, (uint32*)dest, width, height); |
1805 | } |
1806 | #else |
1807 | (*this.*quantizer)((uint32*)src, (uint32*)dest, width, height); |
1808 | #endif |
1809 | |
1810 | } else if (srcformat == GR_TEXFMT_ARGB_8888) { |
1811 | switch (destformat) { |
1812 | case GR_TEXFMT_ARGB_1555: |
1813 | quantizer = fastQuantizer ? &TxQuantize::ARGB8888_ARGB1555 : &TxQuantize::ARGB8888_ARGB1555_ErrD; |
1814 | bpp_shift = 1; |
1815 | break; |
1816 | case GR_TEXFMT_ARGB_4444: |
1817 | quantizer = fastQuantizer ? &TxQuantize::ARGB8888_ARGB4444 : &TxQuantize::ARGB8888_ARGB4444_ErrD; |
1818 | bpp_shift = 1; |
1819 | break; |
1820 | case GR_TEXFMT_RGB_565: |
1821 | quantizer = fastQuantizer ? &TxQuantize::ARGB8888_RGB565 : &TxQuantize::ARGB8888_RGB565_ErrD; |
1822 | bpp_shift = 1; |
1823 | break; |
1824 | case GR_TEXFMT_ALPHA_8: |
1825 | case GR_TEXFMT_INTENSITY_8: |
1826 | quantizer = fastQuantizer ? &TxQuantize::ARGB8888_A8 : &TxQuantize::ARGB8888_I8_Slow; |
1827 | bpp_shift = 2; |
1828 | break; |
1829 | case GR_TEXFMT_ALPHA_INTENSITY_44: |
1830 | quantizer = fastQuantizer ? &TxQuantize::ARGB8888_AI44 : &TxQuantize::ARGB8888_AI44_ErrD; |
1831 | bpp_shift = 2; |
1832 | break; |
1833 | case GR_TEXFMT_ALPHA_INTENSITY_88: |
1834 | quantizer = fastQuantizer ? &TxQuantize::ARGB8888_AI88 : &TxQuantize::ARGB8888_AI88_Slow; |
1835 | bpp_shift = 1; |
1836 | break; |
1837 | default: |
1838 | return 0; |
1839 | } |
1840 | |
1841 | #if !defined(NO_FILTER_THREAD) |
1842 | unsigned int numcore = _numcore; |
1843 | unsigned int blkrow = 0; |
1844 | while (numcore > 1 && blkrow == 0) { |
1845 | blkrow = (height >> 2) / numcore; |
1846 | numcore--; |
1847 | } |
1848 | if (blkrow > 0 && numcore > 1) { |
1849 | std::thread *thrd[MAX_NUMCORE]; |
1850 | unsigned int i; |
1851 | int blkheight = blkrow << 2; |
1852 | unsigned int srcStride = (width * blkheight) << 2; |
1853 | unsigned int destStride = srcStride >> bpp_shift; |
1854 | for (i = 0; i < numcore - 1; i++) { |
1855 | thrd[i] = new std::thread(std::bind(quantizer, |
1856 | this, |
1857 | (uint32*)src, |
1858 | (uint32*)dest, |
1859 | width, |
1860 | blkheight)); |
1861 | src += srcStride; |
1862 | dest += destStride; |
1863 | } |
1864 | thrd[i] = new std::thread(std::bind(quantizer, |
1865 | this, |
1866 | (uint32*)src, |
1867 | (uint32*)dest, |
1868 | width, |
1869 | height - blkheight * i)); |
1870 | for (i = 0; i < numcore; i++) { |
1871 | thrd[i]->join(); |
1872 | delete thrd[i]; |
1873 | } |
1874 | } else { |
1875 | (*this.*quantizer)((uint32*)src, (uint32*)dest, width, height); |
1876 | } |
1877 | #else |
1878 | (*this.*quantizer)((uint32*)src, (uint32*)dest, width, height); |
1879 | #endif |
1880 | |
1881 | } else { |
1882 | return 0; |
1883 | } |
1884 | |
1885 | return 1; |
1886 | } |
1887 | |
1888 | boolean |
1889 | TxQuantize::FXT1(uint8 *src, uint8 *dest, |
1890 | int srcwidth, int srcheight, uint16 srcformat, |
1891 | int *destwidth, int *destheight, uint16 *destformat) |
1892 | { |
1893 | /* |
1894 | * NOTE: src must be in ARGB8888 format, srcformat describes |
1895 | * the closest 16bbp representation of src. |
1896 | * |
1897 | * NOTE: I have modified the dxtn library to use ARGB format |
1898 | * which originaly was ABGR format. |
1899 | */ |
1900 | |
1901 | boolean bRet = 0; |
1902 | |
1903 | if (_tx_compress_fxt1 && |
1904 | srcwidth >= 8 && srcheight >= 4) { |
1905 | /* compress to fxt1 |
1906 | * width and height must be larger than 8 and 4 respectively |
1907 | */ |
1908 | int dstRowStride = ((srcwidth + 7) & ~7) << 1; |
1909 | int srcRowStride = (srcwidth << 2); |
1910 | |
1911 | #if !defined(NO_FILTER_THREAD) |
1912 | unsigned int numcore = _numcore; |
1913 | unsigned int blkrow = 0; |
1914 | while (numcore > 1 && blkrow == 0) { |
1915 | blkrow = (srcheight >> 2) / numcore; |
1916 | numcore--; |
1917 | } |
1918 | if (blkrow > 0 && numcore > 1) { |
1919 | std::thread *thrd[MAX_NUMCORE]; |
1920 | unsigned int i; |
1921 | int blkheight = blkrow << 2; |
1922 | unsigned int srcStride = (srcwidth * blkheight) << 2; |
1923 | unsigned int destStride = dstRowStride * blkrow; |
1924 | for (i = 0; i < numcore - 1; i++) { |
1925 | thrd[i] = new std::thread(std::bind(_tx_compress_fxt1, |
1926 | srcwidth, |
1927 | blkheight, |
1928 | 4, |
1929 | src, |
1930 | srcRowStride, |
1931 | dest, |
1932 | dstRowStride)); |
1933 | src += srcStride; |
1934 | dest += destStride; |
1935 | } |
1936 | thrd[i] = new std::thread(std::bind(_tx_compress_fxt1, |
1937 | srcwidth, |
1938 | srcheight - blkheight * i, |
1939 | 4, |
1940 | src, |
1941 | srcRowStride, |
1942 | dest, |
1943 | dstRowStride)); |
1944 | for (i = 0; i < numcore; i++) { |
1945 | thrd[i]->join(); |
1946 | delete thrd[i]; |
1947 | } |
1948 | } else { |
1949 | (*_tx_compress_fxt1)(srcwidth, /* width */ |
1950 | srcheight, /* height */ |
1951 | 4, /* comps: ARGB8888=4, RGB888=3 */ |
1952 | src, /* source */ |
1953 | srcRowStride, /* width*comps */ |
1954 | dest, /* destination */ |
1955 | dstRowStride); /* 16 bytes per 8x4 texel */ |
1956 | } |
1957 | #else |
1958 | (*_tx_compress_fxt1)(srcwidth, /* width */ |
1959 | srcheight, /* height */ |
1960 | 4, /* comps: ARGB8888=4, RGB888=3 */ |
1961 | src, /* source */ |
1962 | srcRowStride, /* width*comps */ |
1963 | dest, /* destination */ |
1964 | dstRowStride); /* 16 bytes per 8x4 texel */ |
1965 | #endif |
1966 | |
1967 | /* dxtn adjusts width and height to M8 and M4 respectively by replication */ |
1968 | *destwidth = (srcwidth + 7) & ~7; |
1969 | *destheight = (srcheight + 3) & ~3; |
1970 | *destformat = GR_TEXFMT_ARGB_CMP_FXT1; |
1971 | |
1972 | bRet = 1; |
1973 | } |
1974 | |
1975 | return bRet; |
1976 | } |
1977 | |
1978 | boolean |
1979 | TxQuantize::DXTn(uint8 *src, uint8 *dest, |
1980 | int srcwidth, int srcheight, uint16 srcformat, |
1981 | int *destwidth, int *destheight, uint16 *destformat) |
1982 | { |
1983 | /* |
1984 | * NOTE: src must be in ARGB8888 format, srcformat describes |
1985 | * the closest 16bbp representation of src. |
1986 | * |
1987 | * NOTE: I have modified the dxtn library to use ARGB format |
1988 | * which originaly was ABGR format. |
1989 | */ |
1990 | |
1991 | boolean bRet = 0; |
1992 | |
1993 | if (_tx_compress_dxtn && |
1994 | srcwidth >= 4 && srcheight >= 4) { |
1995 | /* compress to dxtn |
1996 | * width and height must be larger than 4 |
1997 | */ |
1998 | |
1999 | /* skip formats that DXTn won't help in size. */ |
2000 | if (srcformat == GR_TEXFMT_ALPHA_8 || |
2001 | srcformat == GR_TEXFMT_ALPHA_INTENSITY_44) { |
2002 | ; /* shutup compiler */ |
2003 | } else { |
2004 | int dstRowStride = ((srcwidth + 3) & ~3) << 2; |
2005 | int compression = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; |
2006 | |
2007 | *destformat = GR_TEXFMT_ARGB_CMP_DXT5; |
2008 | |
2009 | #if !GLIDE64_DXTN |
2010 | /* okay... we are going to disable DXT1 with 1bit alpha |
2011 | * for Glide64. some textures have all 0 alpha values. |
2012 | * see "N64 Kobe Bryant in NBA Courtside" |
2013 | */ |
2014 | if (srcformat == GR_TEXFMT_ARGB_1555) { |
2015 | dstRowStride >>= 1; |
2016 | compression = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; |
2017 | *destformat = GR_TEXFMT_ARGB_CMP_DXT1; |
2018 | } else |
2019 | #endif |
2020 | if (srcformat == GR_TEXFMT_RGB_565 || |
2021 | srcformat == GR_TEXFMT_INTENSITY_8) { |
2022 | dstRowStride >>= 1; |
2023 | compression = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; |
2024 | *destformat = GR_TEXFMT_ARGB_CMP_DXT1; |
2025 | } |
2026 | |
2027 | #if !defined(NO_FILTER_THREAD) |
2028 | unsigned int numcore = _numcore; |
2029 | unsigned int blkrow = 0; |
2030 | while (numcore > 1 && blkrow == 0) { |
2031 | blkrow = (srcheight >> 2) / numcore; |
2032 | numcore--; |
2033 | } |
2034 | if (blkrow > 0 && numcore > 1) { |
2035 | std::thread *thrd[MAX_NUMCORE]; |
2036 | unsigned int i; |
2037 | int blkheight = blkrow << 2; |
2038 | unsigned int srcStride = (srcwidth * blkheight) << 2; |
2039 | unsigned int destStride = dstRowStride * blkrow; |
2040 | for (i = 0; i < numcore - 1; i++) { |
2041 | thrd[i] = new std::thread(std::bind(_tx_compress_dxtn, |
2042 | 4, |
2043 | srcwidth, |
2044 | blkheight, |
2045 | src, |
2046 | compression, |
2047 | dest, |
2048 | dstRowStride)); |
2049 | src += srcStride; |
2050 | dest += destStride; |
2051 | } |
2052 | thrd[i] = new std::thread(std::bind(_tx_compress_dxtn, |
2053 | 4, |
2054 | srcwidth, |
2055 | srcheight - blkheight * i, |
2056 | src, |
2057 | compression, |
2058 | dest, |
2059 | dstRowStride)); |
2060 | for (i = 0; i < numcore; i++) { |
2061 | thrd[i]->join(); |
2062 | delete thrd[i]; |
2063 | } |
2064 | } else { |
2065 | (*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */ |
2066 | srcwidth, /* width */ |
2067 | srcheight, /* height */ |
2068 | src, /* source */ |
2069 | compression, /* format */ |
2070 | dest, /* destination */ |
2071 | dstRowStride); /* DXT1 = 8 bytes per 4x4 texel |
2072 | * others = 16 bytes per 4x4 texel */ |
2073 | } |
2074 | #else |
2075 | (*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */ |
2076 | srcwidth, /* width */ |
2077 | srcheight, /* height */ |
2078 | src, /* source */ |
2079 | compression, /* format */ |
2080 | dest, /* destination */ |
2081 | dstRowStride); /* DXT1 = 8 bytes per 4x4 texel |
2082 | * others = 16 bytes per 4x4 texel */ |
2083 | #endif |
2084 | |
2085 | /* dxtn adjusts width and height to M4 by replication */ |
2086 | *destwidth = (srcwidth + 3) & ~3; |
2087 | *destheight = (srcheight + 3) & ~3; |
2088 | |
2089 | bRet = 1; |
2090 | } |
2091 | } |
2092 | |
2093 | return bRet; |
2094 | } |
2095 | |
2096 | boolean |
2097 | TxQuantize::compress(uint8 *src, uint8 *dest, |
2098 | int srcwidth, int srcheight, uint16 srcformat, |
2099 | int *destwidth, int *destheight, uint16 *destformat, |
2100 | int compressionType) |
2101 | { |
2102 | boolean bRet = 0; |
2103 | |
2104 | switch (compressionType) { |
2105 | case FXT1_COMPRESSION: |
2106 | bRet = FXT1(src, dest, |
2107 | srcwidth, srcheight, srcformat, |
2108 | destwidth, destheight, destformat); |
2109 | break; |
2110 | case S3TC_COMPRESSION: |
2111 | bRet = DXTn(src, dest, |
2112 | srcwidth, srcheight, srcformat, |
2113 | destwidth, destheight, destformat); |
2114 | break; |
2115 | case NCC_COMPRESSION: |
2116 | /* TODO: narrow channel compression */ |
2117 | ; |
2118 | } |
2119 | |
2120 | return bRet; |
2121 | } |
2122 | |
2123 | #if 0 /* unused */ |
2124 | void |
2125 | TxQuantize::I8_ARGB8888(uint32* src, uint32* dest, int width, int height) |
2126 | { |
2127 | int siz = (width * height) >> 2; |
2128 | |
2129 | __asm { |
2130 | push ebx; |
2131 | push esi; |
2132 | push edi; |
2133 | |
2134 | mov esi, dword ptr [src]; |
2135 | mov edi, dword ptr [dest]; |
2136 | mov ecx, dword ptr [siz]; |
2137 | |
2138 | tc1_loop: |
2139 | mov eax, dword ptr [esi]; |
2140 | add esi, 4; |
2141 | |
2142 | // aaaaaaaa |
2143 | // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa |
2144 | mov edx, eax; |
2145 | and eax, 0x000000ff; |
2146 | mov ebx, eax; // 00000000 00000000 00000000 aaaaaaaa |
2147 | shl ebx, 8; // 00000000 00000000 aaaaaaaa 00000000 |
2148 | or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa |
2149 | shl ebx, 8; // 00000000 aaaaaaaa 00000000 00000000 |
2150 | or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
2151 | or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa |
2152 | |
2153 | mov dword ptr [edi], eax; |
2154 | add edi, 4; |
2155 | |
2156 | mov eax, edx; |
2157 | and eax, 0x0000ff00; |
2158 | mov ebx, eax; // 00000000 00000000 aaaaaaaa 00000000 |
2159 | shr ebx, 8; // 00000000 00000000 00000000 aaaaaaaa |
2160 | or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa |
2161 | shl ebx, 16; // 00000000 aaaaaaaa 00000000 00000000 |
2162 | or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
2163 | or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa |
2164 | |
2165 | mov dword ptr [edi], eax; |
2166 | add edi, 4; |
2167 | |
2168 | mov eax, edx; |
2169 | and eax, 0x00ff0000; |
2170 | mov ebx, eax; // 00000000 aaaaaaaa 00000000 00000000 |
2171 | shr ebx, 8; // 00000000 00000000 aaaaaaaa 00000000 |
2172 | or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa 00000000 |
2173 | shr ebx, 8; // 00000000 00000000 00000000 aaaaaaaa |
2174 | or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
2175 | or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa |
2176 | |
2177 | mov dword ptr [edi], eax; |
2178 | add edi, 4; |
2179 | |
2180 | mov eax, edx; |
2181 | and eax, 0xff000000; |
2182 | mov ebx, eax; // aaaaaaaa 00000000 00000000 00000000 |
2183 | shr ebx, 8; // 00000000 aaaaaaaa 00000000 00000000 |
2184 | or eax, ebx; // aaaaaaaa aaaaaaaa 00000000 00000000 |
2185 | shr ebx, 8; // 00000000 00000000 aaaaaaaa 00000000 |
2186 | or eax, ebx; // aaaaaaaa aaaaaaaa aaaaaaaa 00000000 |
2187 | shr eax, 8; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa |
2188 | or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa |
2189 | |
2190 | mov dword ptr [edi], eax; |
2191 | add edi, 4; |
2192 | |
2193 | dec ecx; |
2194 | jnz tc1_loop; |
2195 | |
2196 | pop edi; |
2197 | pop esi; |
2198 | pop ebx; |
2199 | } |
2200 | } |
2201 | |
2202 | void |
2203 | TxQuantize::ARGB8888_I8(uint32* src, uint32* dest, int width, int height) |
2204 | { |
2205 | ARGB8888_A8(src, dest, width, height); |
2206 | } |
2207 | |
2208 | void |
2209 | TxQuantize::ARGB1555_ABGR8888(uint32* src, uint32* dest, int width, int height) |
2210 | { |
2211 | int siz = (width * height) >> 1; |
2212 | |
2213 | __asm { |
2214 | push ebx; |
2215 | push esi; |
2216 | push edi; |
2217 | |
2218 | mov esi, dword ptr [src]; |
2219 | mov edi, dword ptr [dest]; |
2220 | mov ecx, dword ptr [siz]; |
2221 | |
2222 | tc1_loop: |
2223 | mov eax, dword ptr [esi]; |
2224 | add esi, 4; |
2225 | |
2226 | // arrr rrgg gggb bbbb |
2227 | // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2228 | mov edx, eax; // edx = arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
2229 | and ebx, 0x00000000; |
2230 | and eax, 0x00008000; // eax = 00000000 00000000 a0000000 00000000 |
2231 | jz transparent1; |
2232 | or ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 00000000 |
2233 | |
2234 | transparent1: |
2235 | mov eax, edx; // eax = arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
2236 | and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb |
2237 | shl edx, 14; // edx = 00000000 00000bbb bb000000 00000000 |
2238 | or ebx, edx; // ebx = aaaaaaaa 00000bbb bb000000 00000000 |
2239 | shl edx, 5; // edx = 00000000 bbbbb000 00000000 00000000 |
2240 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb bb000000 00000000 |
2241 | and ebx, 0xffff0000; // ebx = aaaaaaaa bbbbbbbb 00000000 00000000 |
2242 | mov edx, eax; |
2243 | and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg00000 |
2244 | shl edx, 1; // edx = 00000000 00000000 00000ggg gg000000 |
2245 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb 00000ggg gg000000 |
2246 | shl edx, 5; // edx = 00000000 00000000 ggggg000 00000000 |
2247 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg gg000000 |
2248 | and ebx, 0xffffff00; // ebx = aaaaaaaa bbbbbbbb gggggggg 00000000 |
2249 | mov edx, eax; |
2250 | and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 00000000 |
2251 | shr edx, 7; // edx = 00000000 00000000 00000000 rrrrr000 |
2252 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrr000 |
2253 | shr edx, 5; // edx = 00000000 00000000 00000000 00000rrr |
2254 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2255 | |
2256 | mov dword ptr [edi], ebx; |
2257 | add edi, 4; |
2258 | |
2259 | shr eax, 16; // eax = 00000000 00000000 arrrrrgg gggbbbbb |
2260 | mov edx, eax; // edx = 00000000 00000000 arrrrrgg gggbbbbb |
2261 | and ebx, 0x00000000; |
2262 | and eax, 0x00008000; // eax = 00000000 00000000 a0000000 00000000 |
2263 | jz transparent2; |
2264 | or ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 00000000 |
2265 | |
2266 | transparent2: |
2267 | mov eax, edx; // eax = arrrrrgg gggbbbbb arrrrrgg gggbbbbb |
2268 | and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb |
2269 | shl edx, 14; // edx = 00000000 00000bbb bb000000 00000000 |
2270 | or ebx, edx; // ebx = aaaaaaaa 00000bbb bb000000 00000000 |
2271 | shl edx, 5; // edx = 00000000 bbbbb000 00000000 00000000 |
2272 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb bb000000 00000000 |
2273 | and ebx, 0xffff0000; // ebx = aaaaaaaa bbbbbbbb 00000000 00000000 |
2274 | mov edx, eax; |
2275 | and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg00000 |
2276 | shl edx, 1; // edx = 00000000 00000000 00000ggg gg000000 |
2277 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb 00000ggg gg000000 |
2278 | shl edx, 5; // edx = 00000000 00000000 ggggg000 00000000 |
2279 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg gg000000 |
2280 | and ebx, 0xffffff00; // ebx = aaaaaaaa bbbbbbbb gggggggg 00000000 |
2281 | mov edx, eax; |
2282 | and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 00000000 |
2283 | shr edx, 7; // edx = 00000000 00000000 00000000 rrrrr000 |
2284 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrr000 |
2285 | shr edx, 5; // edx = 00000000 00000000 00000000 00000rrr |
2286 | or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2287 | |
2288 | mov dword ptr [edi], ebx; |
2289 | add edi, 4; |
2290 | |
2291 | dec ecx; |
2292 | jnz tc1_loop; |
2293 | |
2294 | pop edi; |
2295 | pop esi; |
2296 | pop ebx; |
2297 | } |
2298 | } |
2299 | |
2300 | void |
2301 | TxQuantize::ARGB4444_ABGR8888(uint32* src, uint32* dest, int width, int height) |
2302 | { |
2303 | int siz = (width * height) >> 1; |
2304 | |
2305 | __asm { |
2306 | push ebx; |
2307 | push esi; |
2308 | push edi; |
2309 | |
2310 | mov esi, dword ptr [src]; |
2311 | mov edi, dword ptr [dest]; |
2312 | mov ecx, dword ptr [siz]; |
2313 | |
2314 | tc1_loop: |
2315 | mov eax, dword ptr [esi]; |
2316 | add esi, 4; |
2317 | |
2318 | // aaaa rrrr gggg bbbb |
2319 | // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2320 | mov edx, eax; |
2321 | and eax, 0x0000ffff; |
2322 | mov ebx, eax; // 00000000 00000000 aaaarrrr ggggbbbb |
2323 | and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 00000000 |
2324 | shl ebx, 12; // 0000aaaa 00000000 00000000 00000000 |
2325 | or eax, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb |
2326 | mov ebx, eax; |
2327 | and ebx, 0x0000000f; // 00000000 00000000 00000000 0000bbbb |
2328 | shl ebx, 16; // 00000000 0000bbbb 00000000 00000000 |
2329 | or eax, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggbbbb |
2330 | mov ebx, eax; |
2331 | and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 00000000 |
2332 | shr ebx, 8; // 00000000 00000000 00000000 0000rrrr |
2333 | and eax, 0xfffffff0; |
2334 | or eax, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggrrrr |
2335 | mov ebx, eax; |
2336 | and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg0000 |
2337 | shl ebx, 4; // 00000000 00000000 0000gggg 00000000 |
2338 | and eax, 0x0f0f000f; // 0000aaaa 0000bbbb 00000000 0000rrrr |
2339 | or eax, ebx; // 0000aaaa 0000bbbb 0000gggg 0000rrrr |
2340 | mov ebx, eax; |
2341 | shl ebx, 4; // aaaa0000 bbbb0000 gggg0000 rrrr0000 |
2342 | or eax, ebx; // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2343 | |
2344 | mov dword ptr [edi], eax; |
2345 | |
2346 | add edi, 4; |
2347 | |
2348 | shr edx, 16; |
2349 | mov ebx, edx; // 00000000 00000000 aaaarrrr ggggbbbb |
2350 | and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 00000000 |
2351 | shl ebx, 12; // 0000aaaa 00000000 00000000 00000000 |
2352 | or edx, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb |
2353 | mov ebx, edx; |
2354 | and ebx, 0x0000000f; // 00000000 00000000 00000000 0000bbbb |
2355 | shl ebx, 16; // 00000000 0000bbbb 00000000 00000000 |
2356 | or edx, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggbbbb |
2357 | mov ebx, edx; |
2358 | and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 00000000 |
2359 | shr ebx, 8; // 00000000 00000000 00000000 0000rrrr |
2360 | and edx, 0xfffffff0; |
2361 | or edx, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggrrrr |
2362 | mov ebx, edx; |
2363 | and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg0000 |
2364 | shl ebx, 4; // 00000000 00000000 0000gggg 00000000 |
2365 | and edx, 0x0f0f000f; // 0000aaaa 0000bbbb 00000000 0000rrrr |
2366 | or edx, ebx; // 0000aaaa 0000bbbb 0000gggg 0000rrrr |
2367 | mov ebx, edx; |
2368 | shl ebx, 4; // aaaa0000 bbbb0000 gggg0000 rrrr0000 |
2369 | or edx, ebx; // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2370 | |
2371 | mov dword ptr [edi], edx; |
2372 | add edi, 4; |
2373 | |
2374 | dec ecx; |
2375 | jnz tc1_loop; |
2376 | |
2377 | pop edi; |
2378 | pop esi; |
2379 | pop ebx; |
2380 | } |
2381 | } |
2382 | |
2383 | void |
2384 | TxQuantize::ARGB8888_ABGR8888(uint32* src, uint32* dest, int width, int height) |
2385 | { |
2386 | int siz = width * height; |
2387 | |
2388 | __asm { |
2389 | push ebx; |
2390 | push esi; |
2391 | push edi; |
2392 | |
2393 | mov esi, dword ptr [src]; |
2394 | mov edi, dword ptr [dest]; |
2395 | mov ecx, dword ptr [siz]; |
2396 | |
2397 | tc1_loop: |
2398 | mov eax, dword ptr [esi]; |
2399 | add esi, 4; |
2400 | |
2401 | // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr |
2402 | mov edx, eax; |
2403 | bswap edx; |
2404 | shr edx, 8; |
2405 | and eax, 0xff000000; |
2406 | |
2407 | or eax, edx; |
2408 | |
2409 | mov dword ptr [edi], eax; |
2410 | add edi, 4; |
2411 | |
2412 | dec ecx; |
2413 | jnz tc1_loop; |
2414 | |
2415 | pop edi; |
2416 | pop esi; |
2417 | pop ebx; |
2418 | } |
2419 | } |
2420 | #endif |