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