Path: blob/master/libmupen64plus/mupen64plus-video-glide64mk2/src/GlideHQ/TxQuantize.cpp
2 views
/*1* Texture Filtering2* Version: 1.03*4* Copyright (C) 2007 Hiroshi Morii All Rights Reserved.5* Email koolsmoky(at)users.sourceforge.net6* Web http://www.3dfxzone.it/koolsmoky7*8* this is free software; you can redistribute it and/or modify9* it under the terms of the GNU General Public License as published by10* the Free Software Foundation; either version 2, or (at your option)11* any later version.12*13* this is distributed in the hope that it will be useful,14* but WITHOUT ANY WARRANTY; without even the implied warranty of15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16* GNU General Public License for more details.17*18* You should have received a copy of the GNU General Public License19* along with GNU Make; see the file COPYING. If not, write to20* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.21*/2223#ifdef __MSC__24#pragma warning(disable: 4786)25#endif2627#include <functional>2829//zero 01-aug-2013 - no need to include <thread> if option isnt selected30#if !defined(NO_FILTER_THREAD)31#include <thread>32#endif3334/* NOTE: The codes are not optimized. They can be made faster. */3536#include "TxQuantize.h"3738TxQuantize::TxQuantize()39{40_txUtil = new TxUtil();4142/* get number of CPU cores. */43_numcore = _txUtil->getNumberofProcessors();4445/* get dxtn extensions */46_tx_compress_fxt1 = TxLoadLib::getInstance()->getfxtCompressTexFuncExt();47_tx_compress_dxtn = TxLoadLib::getInstance()->getdxtCompressTexFuncExt();48}495051TxQuantize::~TxQuantize()52{53delete _txUtil;54}5556void57TxQuantize::ARGB1555_ARGB8888(uint32* src, uint32* dest, int width, int height)58{59#if 160int siz = (width * height) >> 1;61int i;62for (i = 0; i < siz; i++) {63*dest = (((*src & 0x00008000) ? 0xff000000 : 0x00000000) |64((*src & 0x00007c00) << 9) | ((*src & 0x00007000) << 4) |65((*src & 0x000003e0) << 6) | ((*src & 0x00000380) << 1) |66((*src & 0x0000001f) << 3) | ((*src & 0x0000001c) >> 2));67dest++;68*dest = (((*src & 0x80000000) ? 0xff000000 : 0x00000000) |69((*src & 0x7c000000) >> 7) | ((*src & 0x70000000) >> 12) |70((*src & 0x03e00000) >> 10) | ((*src & 0x03800000) >> 15) |71((*src & 0x001f0000) >> 13) | ((*src & 0x001c0000) >> 18));72dest++;73src++;74}75#else76int siz = (width * height) >> 1;7778__asm {79push ebx;80push esi;81push edi;8283mov esi, dword ptr [src];84mov edi, dword ptr [dest];85mov ecx, dword ptr [siz];8687tc1_loop:88mov eax, dword ptr [esi];89add esi, 4;9091// arrr rrgg gggb bbbb92// aaaaaaaa rrrrrrrr gggggggg bbbbbbbb93mov edx, eax; // edx = arrrrrgg gggbbbbb arrrrrgg gggbbbbb94mov ebx, 0x00000000;95and eax, 0x00008000; // eax = 00000000 00000000 a0000000 0000000096jz transparent1;97mov ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 000000009899transparent1:100mov eax, edx; // eax = arrrrrgg gggbbbbb arrrrrgg gggbbbbb101and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 00000000102shl edx, 4; // edx = 00000000 00000rrr rr000000 00000000103or ebx, edx; // ebx = aaaaaaaa 00000rrr rr000000 00000000104shl edx, 5; // edx = 00000000 rrrrr000 00000000 00000000105or ebx, edx; // ebx = aaaaaaaa rrrrrrrr rr000000 00000000106and ebx, 0xffff0000; // ebx = aaaaaaaa rrrrrrrr 00000000 00000000107mov edx, eax;108and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg00000109shl edx, 1; // edx = 00000000 00000000 00000ggg gg000000110or ebx, edx; // ebx = aaaaaaaa rrrrrrrr 00000ggg gg000000111shl edx, 5; // edx = 00000000 00000000 ggggg000 00000000112or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg gg000000113and ebx, 0xffffff00; // ebx = aaaaaaaa rrrrrrrr gggggggg 00000000114mov edx, eax;115and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb116shl edx, 3; // edx = 00000000 00000000 00000000 bbbbb000117or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbb000118shr edx, 5; // edx = 00000000 00000000 00000000 00000bbb119or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbbbbb120121mov dword ptr [edi], ebx;122add edi, 4;123124shr eax, 16; // eax = 00000000 00000000 arrrrrgg gggbbbbb125mov edx, eax; // edx = 00000000 00000000 arrrrrgg gggbbbbb126mov ebx, 0x00000000;127and eax, 0x00008000; // eax = 00000000 00000000 a0000000 00000000128jz transparent2;129mov ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 00000000130131transparent2:132mov eax, edx; // eax = 00000000 00000000 arrrrrgg gggbbbbb133and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 00000000134shl edx, 4; // edx = 00000000 00000rrr rr000000 00000000135or ebx, edx; // ebx = aaaaaaaa 00000rrr rr000000 00000000136shl edx, 5; // edx = 00000000 rrrrr000 00000000 00000000137or ebx, edx; // ebx = aaaaaaaa rrrrrrrr rr000000 00000000138and ebx, 0xffff0000; // ebx = aaaaaaaa rrrrrrrr 00000000 00000000139mov edx, eax;140and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg00000141shl edx, 1; // edx = 00000000 00000000 00000ggg gg000000142or ebx, edx; // ebx = aaaaaaaa rrrrrrrr 00000ggg gg000000143shl edx, 5; // edx = 00000000 00000000 ggggg000 00000000144or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg gg000000145and ebx, 0xffffff00; // ebx = aaaaaaaa rrrrrrrr gggggggg 00000000146mov edx, eax;147and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb148shl edx, 3; // edx = 00000000 00000000 00000000 bbbbb000149or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbb000150shr edx, 5; // edx = 00000000 00000000 00000000 00000bbb151or ebx, edx; // ebx = aaaaaaaa rrrrrrrr gggggggg bbbbbbbb152153mov dword ptr [edi], ebx;154add edi, 4;155156dec ecx;157jnz tc1_loop;158159pop edi;160pop esi;161pop ebx;162}163#endif164}165166void167TxQuantize::ARGB4444_ARGB8888(uint32* src, uint32* dest, int width, int height)168{169#if 1170int siz = (width * height) >> 1;171int i;172for (i = 0; i < siz; i++) {173*dest = ((*src & 0x0000f000) << 12) |174((*src & 0x00000f00) << 8) |175((*src & 0x000000f0) << 4) |176(*src & 0x0000000f);177*dest |= (*dest << 4);178dest++;179*dest = ((*src & 0xf0000000) |180((*src & 0x0f000000) >> 4) |181((*src & 0x00f00000) >> 8) |182((*src & 0x000f0000) >> 12));183*dest |= (*dest >> 4);184dest++;185src++;186}187#else188int siz = (width * height) >> 1;189190__asm {191push ebx;192push esi;193push edi;194195mov esi, dword ptr [src];196mov edi, dword ptr [dest];197mov ecx, dword ptr [siz];198199tc1_loop:200mov eax, dword ptr [esi];201add esi, 4;202203// aaaa rrrr gggg bbbb204// aaaaaaaa rrrrrrrr gggggggg bbbbbbbb205mov edx, eax;206and eax, 0x0000ffff;207mov ebx, eax; // 00000000 00000000 aaaarrrr ggggbbbb208and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 00000000209shl ebx, 12; // 0000aaaa 00000000 00000000 00000000210or eax, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb211mov ebx, eax;212and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 00000000213shl ebx, 8; // 00000000 0000rrrr 00000000 00000000214or eax, ebx; // 0000aaaa 0000rrrr aaaarrrr ggggbbbb215mov ebx, eax;216and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg0000217shl ebx, 4; // 00000000 00000000 0000gggg 00000000218and eax, 0x0f0f000f; // 0000aaaa 0000rrrr 00000000 0000bbbb219or eax, ebx; // 0000aaaa 0000rrrr 0000gggg 0000bbbb220mov ebx, eax;221shl ebx, 4; // aaaa0000 rrrr0000 gggg0000 bbbb0000222or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb223224mov dword ptr [edi], eax;225add edi, 4;226227shr edx, 16;228mov ebx, edx; // 00000000 00000000 aaaarrrr ggggbbbb229and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 00000000230shl ebx, 12; // 0000aaaa 00000000 00000000 00000000231or edx, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb232mov ebx, edx;233and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 00000000234shl ebx, 8; // 00000000 0000rrrr 00000000 00000000235or edx, ebx; // 0000aaaa 0000rrrr aaaarrrr ggggbbbb236mov ebx, edx;237and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg0000238shl ebx, 4; // 00000000 00000000 0000gggg 00000000239and edx, 0x0f0f000f; // 0000aaaa 0000rrrr 00000000 0000bbbb240or edx, ebx; // 0000aaaa 0000rrrr 0000gggg 0000bbbb241mov ebx, edx;242shl ebx, 4; // aaaa0000 rrrr0000 gggg0000 bbbb0000243or edx, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb244245mov dword ptr [edi], edx;246add edi, 4;247248dec ecx;249jnz tc1_loop;250251pop edi;252pop esi;253pop ebx;254}255#endif256}257258void259TxQuantize::RGB565_ARGB8888(uint32* src, uint32* dest, int width, int height)260{261#if 1262int siz = (width * height) >> 1;263int i;264for (i = 0; i < siz; i++) {265*dest = (0xff000000 |266((*src & 0x0000f800) << 8) | ((*src & 0x0000e000) << 3) |267((*src & 0x000007e0) << 5) | ((*src & 0x00000600) >> 1) |268((*src & 0x0000001f) << 3) | ((*src & 0x0000001c) >> 2));269dest++;270*dest = (0xff000000 |271((*src & 0xf8000000) >> 8) | ((*src & 0xe0000000) >> 13) |272((*src & 0x07e00000) >> 11) | ((*src & 0x06000000) >> 17) |273((*src & 0x001f0000) >> 13) | ((*src & 0x001c0000) >> 18));274dest++;275src++;276}277#else278int siz = (width * height) >> 1;279280__asm {281push ebx;282push esi;283push edi;284285mov esi, dword ptr [src];286mov edi, dword ptr [dest];287mov ecx, dword ptr [siz];288289tc1_loop:290mov eax, dword ptr [esi];291add esi, 4;292293// rrrr rggg gggb bbbb294// 11111111 rrrrrrrr gggggggg bbbbbbbb295mov edx, eax;296and eax, 0x0000ffff;297mov ebx, eax; // 00000000 00000000 rrrrrggg gggbbbbb298and ebx, 0x0000f800; // 00000000 00000000 rrrrr000 00000000299shl ebx, 5; // 00000000 000rrrrr 00000000 00000000300or eax, ebx; // 00000000 000rrrrr rrrrrggg gggbbbbb301mov ebx, eax;302and ebx, 0x000007e0; // 00000000 00000000 00000ggg ggg00000303shl ebx, 5; // 00000000 00000000 gggggg00 00000000304and eax, 0x001F001F; // 00000000 000rrrrr 00000000 000bbbbb305shl eax, 3; // 00000000 rrrrr000 00000000 bbbbb000306or eax, ebx; // 00000000 rrrrr000 gggggg00 bbbbb000307mov ebx, eax;308shr ebx, 5; // 00000000 00000rrr rr000ggg ggg00bbb309and ebx, 0x00070007; // 00000000 00000rrr 00000000 00000bbb310or eax, ebx; // 00000000 rrrrrrrr gggggg00 bbbbbbbb311mov ebx, eax;312shr ebx, 6;313and ebx, 0x00000300; // 00000000 00000000 000000gg 00000000314or eax, ebx // 00000000 rrrrrrrr gggggggg bbbbbbbb315or eax, 0xff000000; // 11111111 rrrrrrrr gggggggg bbbbbbbb316317mov dword ptr [edi], eax;318add edi, 4;319320shr edx, 16;321mov eax, edx; // 00000000 00000000 rrrrrggg gggbbbbb322and eax, 0x0000ffff;323mov ebx, eax; // 00000000 00000000 rrrrrggg gggbbbbb324and ebx, 0x0000f800; // 00000000 00000000 rrrrr000 00000000325shl ebx, 5; // 00000000 000rrrrr 00000000 00000000326or eax, ebx; // 00000000 000rrrrr rrrrrggg gggbbbbb327mov ebx, eax;328and ebx, 0x000007e0; // 00000000 00000000 00000ggg ggg00000329shl ebx, 5; // 00000000 00000000 gggggg00 00000000330and eax, 0x001F001F; // 00000000 000rrrrr 00000000 000bbbbb331shl eax, 3; // 00000000 rrrrr000 00000000 bbbbb000332or eax, ebx; // 00000000 rrrrr000 gggggg00 bbbbb000333mov ebx, eax;334shr ebx, 5; // 00000000 00000rrr rr000ggg ggg00bbb335and ebx, 0x00070007; // 00000000 00000rrr 00000000 00000bbb336or eax, ebx; // 00000000 rrrrrrrr gggggg00 bbbbbbbb337mov ebx, eax;338shr ebx, 6;339and ebx, 0x00000300; // 00000000 00000000 000000gg 00000000340or eax, ebx // 00000000 rrrrrrrr gggggggg bbbbbbbb341or eax, 0xff000000; // 11111111 rrrrrrrr gggggggg bbbbbbbb342343mov dword ptr [edi], eax;344add edi, 4;345346dec ecx;347jnz tc1_loop;348349pop edi;350pop esi;351pop ebx;352}353#endif354}355356void357TxQuantize::A8_ARGB8888(uint32* src, uint32* dest, int width, int height)358{359#if 1360int siz = (width * height) >> 2;361int i;362for (i = 0; i < siz; i++) {363*dest = (*src & 0x000000ff);364*dest |= (*dest << 8);365*dest |= (*dest << 16);366dest++;367*dest = (*src & 0x0000ff00);368*dest |= (*dest >> 8);369*dest |= (*dest << 16);370dest++;371*dest = (*src & 0x00ff0000);372*dest |= (*dest << 8);373*dest |= (*dest >> 16);374dest++;375*dest = (*src & 0xff000000);376*dest |= (*dest >> 8);377*dest |= (*dest >> 16);378dest++;379src++;380}381#else382int siz = (width * height) >> 2;383384__asm {385push ebx;386push esi;387push edi;388389mov esi, dword ptr [src];390mov edi, dword ptr [dest];391mov ecx, dword ptr [siz];392393tc1_loop:394mov eax, dword ptr [esi];395add esi, 4;396397// aaaaaaaa398// aaaaaaaa rrrrrrrr gggggggg bbbbbbbb399mov edx, eax;400and eax, 0x000000ff;401mov ebx, eax; // 00000000 00000000 00000000 aaaaaaaa402shl ebx, 8; // 00000000 00000000 aaaaaaaa 00000000403or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa404mov ebx, eax;405shl ebx, 16; // aaaaaaaa aaaaaaaa 00000000 00000000406or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb407408mov dword ptr [edi], eax;409add edi, 4;410411mov eax, edx;412and eax, 0x0000ff00;413mov ebx, eax; // 00000000 00000000 aaaaaaaa 00000000414shr ebx, 8; // 00000000 00000000 00000000 aaaaaaaa415or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa416mov ebx, eax;417shl ebx, 16; // aaaaaaaa aaaaaaaa 00000000 00000000418or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb419420mov dword ptr [edi], eax;421add edi, 4;422423mov eax, edx;424and eax, 0x00ff0000;425mov ebx, eax; // 00000000 aaaaaaaa 00000000 00000000426shl ebx, 8; // aaaaaaaa 00000000 00000000 00000000427or eax, ebx; // aaaaaaaa aaaaaaaa 00000000 00000000428mov ebx, eax;429shr ebx, 16; // 00000000 00000000 aaaaaaaa aaaaaaaa430or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb431432mov dword ptr [edi], eax;433add edi, 4;434435mov eax, edx;436and eax, 0xff000000;437mov ebx, eax; // aaaaaaaa 00000000 00000000 00000000438shr ebx, 8; // 00000000 aaaaaaaa 00000000 00000000439or eax, ebx; // aaaaaaaa aaaaaaaa 00000000 00000000440mov ebx, eax;441shr ebx, 16; // 00000000 00000000 aaaaaaaa aaaaaaaa442or eax, ebx; // aaaaaaaa rrrrrrrr gggggggg bbbbbbbb443444mov dword ptr [edi], eax;445add edi, 4;446447dec ecx;448jnz tc1_loop;449450pop edi;451pop esi;452pop ebx;453}454#endif455}456457void458TxQuantize::AI44_ARGB8888(uint32* src, uint32* dest, int width, int height)459{460#if 1461int siz = (width * height) >> 2;462int i;463for (i = 0; i < siz; i++) {464*dest = (*src & 0x0000000f);465*dest |= ((*dest << 8) | (*dest << 16));466*dest |= ((*src & 0x000000f0) << 20);467*dest |= (*dest << 4);468dest++;469*dest = (*src & 0x00000f00);470*dest |= ((*dest << 8) | (*dest >> 8));471*dest |= ((*src & 0x0000f000) << 12);472*dest |= (*dest << 4);473dest++;474*dest = (*src & 0x000f0000);475*dest |= ((*dest >> 8) | (*dest >> 16));476*dest |= ((*src & 0x00f00000) << 4);477*dest |= (*dest << 4);478dest++;479*dest = ((*src & 0x0f000000) >> 4);480*dest |= ((*dest >> 8) | (*dest >> 16));481*dest |= (*src & 0xf0000000);482*dest |= (*dest >> 4);483dest++;484src++;485}486#else487int siz = (width * height) >> 2;488489__asm {490push ebx;491push esi;492push edi;493494mov esi, dword ptr [src];495mov edi, dword ptr [dest];496mov ecx, dword ptr [siz];497498tc1_loop:499mov eax, dword ptr [esi];500add esi, 4;501502// aaaaiiii503// aaaaaaaa iiiiiiii iiiiiiii iiiiiiii504mov edx, eax;505and eax, 0x000000f0; // 00000000 00000000 00000000 aaaa0000506mov ebx, edx;507shl eax, 20; // 0000aaaa 00000000 00000000 00000000508and ebx, 0x0000000f; // 00000000 00000000 00000000 0000iiii509or eax, ebx; // 0000aaaa 00000000 00000000 0000iiii510shl ebx, 8; // 00000000 00000000 0000iiii 00000000511or eax, ebx; // 0000aaaa 00000000 0000iiii 0000iiii512shl ebx, 8; // 00000000 0000iiii 00000000 00000000513or eax, ebx; // 0000aaaa 0000iiii 0000iiii 0000iiii514mov ebx, eax;515shl ebx, 4; // aaaa0000 iiii0000 iiii0000 iiii0000516or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii517518mov dword ptr [edi], eax;519add edi, 4;520521mov eax, edx;522and eax, 0x0000f000; // 00000000 00000000 aaaa0000 00000000523mov ebx, edx;524shl eax, 12; // 0000aaaa 00000000 00000000 00000000525and ebx, 0x00000f00; // 00000000 00000000 0000iiii 00000000526or eax, ebx; // 0000aaaa 00000000 0000iiii 00000000527shr ebx, 8; // 00000000 00000000 00000000 0000iiii528or eax, ebx; // 0000aaaa 00000000 0000iiii 0000iiii529shl ebx, 16; // 00000000 0000iiii 00000000 00000000530or eax, ebx; // 0000aaaa 0000iiii 0000iiii 0000iiii531mov ebx, eax;532shl ebx, 4; // aaaa0000 iiii0000 iiii0000 iiii0000533or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii534535mov dword ptr [edi], eax;536add edi, 4;537538mov eax, edx;539and eax, 0x00f00000; // 00000000 aaaa0000 00000000 00000000540mov ebx, edx;541shl eax, 4; // 0000aaaa 00000000 00000000 00000000542and ebx, 0x000f0000; // 00000000 0000iiii 00000000 00000000543or eax, ebx; // 0000aaaa 0000iiii 00000000 00000000544shr ebx, 8; // 00000000 00000000 0000iiii 00000000545or eax, ebx; // 0000aaaa 0000iiii 0000iiii 00000000546shr ebx, 8; // 00000000 00000000 00000000 0000iiii547or eax, ebx; // 0000aaaa 0000iiii 0000iiii 0000iiii548mov ebx, eax;549shl ebx, 4; // aaaa0000 iiii0000 iiii0000 iiii0000550or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii551552mov dword ptr [edi], eax;553add edi, 4;554555mov eax, edx;556and eax, 0xf0000000; // aaaa0000 00000000 00000000 00000000557mov ebx, edx;558and ebx, 0x0f000000; // 0000iiii 00000000 00000000 00000000559shr ebx, 4; // 00000000 iiii0000 00000000 00000000560or eax, ebx; // aaaa0000 iiii0000 00000000 00000000561shr ebx, 8; // 00000000 00000000 iiii0000 00000000562or eax, ebx; // aaaa0000 iiii0000 iiii0000 00000000563shr ebx, 8; // 00000000 00000000 00000000 iiii0000564or eax, ebx; // aaaa0000 iiii0000 iiii0000 iiii0000565mov ebx, eax;566shr ebx, 4; // 0000aaaa 0000iiii 0000iiii 0000iiii567or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii568569mov dword ptr [edi], eax;570add edi, 4;571572dec ecx;573jnz tc1_loop;574575pop edi;576pop esi;577pop ebx;578}579#endif580}581582void583TxQuantize::AI88_ARGB8888(uint32* src, uint32* dest, int width, int height)584{585#if 1586int siz = (width * height) >> 1;587int i;588for (i = 0; i < siz; i++) {589*dest = (*src & 0x000000ff);590*dest |= ((*dest << 8) | (*dest << 16));591*dest |= ((*src & 0x0000ff00) << 16);592dest++;593*dest = (*src & 0x00ff0000);594*dest |= ((*dest >> 8) | (*dest >> 16));595*dest |= (*src & 0xff000000);596dest++;597src++;598}599#else600int siz = (width * height) >> 1;601602__asm {603push ebx;604push esi;605push edi;606607mov esi, dword ptr [src];608mov edi, dword ptr [dest];609mov ecx, dword ptr [siz];610611tc1_loop:612mov eax, dword ptr [esi];613add esi, 4;614615// aaaaaaaa iiiiiiii616// aaaaaaaa iiiiiiii iiiiiiii iiiiiiii617mov edx, eax;618and eax, 0x0000ffff; // 00000000 00000000 aaaaaaaa iiiiiiii619mov ebx, eax; // 00000000 00000000 aaaaaaaa iiiiiiii620shl eax, 16; // aaaaaaaa iiiiiiii 00000000 00000000621and ebx, 0x000000ff; // 00000000 00000000 00000000 iiiiiiii622or eax, ebx; // aaaaaaaa iiiiiiii 00000000 iiiiiiii623shl ebx, 8; // 00000000 00000000 iiiiiiii 00000000624or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii625626mov dword ptr [edi], eax;627add edi, 4;628629mov eax, edx;630and eax, 0xffff0000; // aaaaaaaa iiiiiiii 00000000 00000000631mov ebx, eax; // aaaaaaaa iiiiiiii 00000000 00000000632and ebx, 0x00ff0000; // 00000000 iiiiiiii 00000000 00000000633shr ebx, 8; // 00000000 00000000 iiiiiiii 00000000634or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii 00000000635shr ebx, 8; // 00000000 00000000 00000000 iiiiiiii636or eax, ebx; // aaaaaaaa iiiiiiii iiiiiiii iiiiiiii637638mov dword ptr [edi], eax;639add edi, 4;640641dec ecx;642jnz tc1_loop;643644pop edi;645pop esi;646pop ebx;647}648#endif649}650651void652TxQuantize::ARGB8888_ARGB1555(uint32* src, uint32* dest, int width, int height)653{654#if 1655int siz = (width * height) >> 1;656int i;657for (i = 0; i < siz; i++) {658*dest = ((*src & 0xff000000) ? 0x00008000 : 0x00000000);659*dest |= (((*src & 0x00f80000) >> 9) |660((*src & 0x0000f800) >> 6) |661((*src & 0x000000f8) >> 3));662src++;663*dest |= ((*src & 0xff000000) ? 0x80000000 : 0x00000000);664*dest |= (((*src & 0x00f80000) << 7) |665((*src & 0x0000f800) << 10) |666((*src & 0x000000f8) << 13));667src++;668dest++;669}670#else671int siz = (width * height) >> 1;672673__asm {674push ebx;675push esi;676push edi;677678mov esi, dword ptr [src];679mov edi, dword ptr [dest];680mov ecx, dword ptr [siz];681682tc1_loop:683mov eax, dword ptr [esi];684add esi, 4;685686#if 1687mov edx, eax;688and eax, 0xff000000; // aaaa0000 00000000 00000000 00000000689jz transparent1;690mov eax, 0x00008000; // 00000000 00000000 a0000000 00000000691692transparent1:693mov ebx, edx;694and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000695shr ebx, 9; // 00000000 00000000 0rrrrr00 00000000696or eax, ebx; // 00000000 00000000 arrrrr00 00000000697mov ebx, edx;698and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000699shr ebx, 6; // 00000000 00000000 000000gg ggg00000700or eax, ebx; // 00000000 00000000 arrrrrgg ggg00000701and edx, 0x000000f8; // 00000000 00000000 00000000 bbbbb000702shr edx, 3; // 00000000 00000000 00000000 000bbbbb703or edx, eax; // 00000000 00000000 arrrrrgg gggbbbbb704705mov eax, dword ptr [esi];706add esi, 4;707708mov ebx, eax;709and eax, 0xff000000; // aaaa0000 00000000 00000000 00000000710jz transparent2;711or edx, 0x80000000; // a0000000 00000000 arrrrrgg gggbbbbb712713transparent2:714mov eax, ebx;715and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000716shl ebx, 7; // 0rrrrr00 00000000 00000000 00000000717or edx, ebx; // arrrrr00 00000000 arrrrrgg gggbbbbb718mov ebx, eax;719and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000720shl ebx, 10; // 000000gg ggg00000 00000000 00000000721or edx, ebx; // arrrrrgg ggg00000 arrrrrgg gggbbbbb722and eax, 0x000000f8; // 00000000 00000000 00000000 bbbbb000723shl eax, 13; // 00000000 000bbbbb 00000000 00000000724or edx, eax; // arrrrrgg gggbbbbb arrrrrgg gggbbbbb725726mov dword ptr [edi], edx;727add edi, 4;728#else729mov edx, eax;730and edx, 0x01000000; // 0000000a 00000000 00000000 00000000731shr edx, 9; // 00000000 00000000 a0000000 00000000732mov ebx, eax;733and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000734shr ebx, 9; // 00000000 00000000 0rrrrr00 00000000735or edx, ebx; // 00000000 00000000 arrrrr00 00000000736mov ebx, eax;737and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000738shr ebx, 6; // 00000000 00000000 000000gg ggg00000739or edx, ebx; // 00000000 00000000 arrrrrgg ggg00000740and eax, 0x000000f8; // 00000000 00000000 00000000 bbbbb000741shr eax, 3; // 00000000 00000000 00000000 000bbbbb742or edx, eax; // 00000000 00000000 arrrrrgg gggbbbbb743744mov eax, dword ptr [esi];745add esi, 4;746747mov ebx, eax;748and ebx, 0x80000000; // a0000000 00000000 00000000 00000000749or edx, ebx; // a0000000 00000000 arrrrrgg gggbbbbb750mov ebx, eax;751and ebx, 0x00f80000; // 00000000 rrrrr000 00000000 00000000752shl ebx, 7; // 0rrrrr00 00000000 00000000 00000000753or edx, ebx; // arrrrr00 00000000 arrrrrgg gggbbbbb754mov ebx, eax;755and ebx, 0x0000f800; // 00000000 00000000 ggggg000 00000000756shl ebx, 10; // 000000gg ggg00000 00000000 00000000757or edx, ebx; // arrrrrgg ggg00000 arrrrrgg gggbbbbb758and eax, 0x000000f8; // 00000000 00000000 00000000 bbbbb000759shl eax, 13; // 00000000 000bbbbb 00000000 00000000760or edx, eax; // arrrrrgg gggbbbbb arrrrrgg gggbbbbb761762mov dword ptr [edi], edx;763add edi, 4;764#endif765dec ecx;766jnz tc1_loop;767768pop edi;769pop esi;770pop ebx;771}772#endif773}774775void776TxQuantize::ARGB8888_ARGB4444(uint32* src, uint32* dest, int width, int height)777{778#if 1779int siz = (width * height) >> 1;780int i;781for (i = 0; i < siz; i++) {782*dest = (((*src & 0xf0000000) >> 16) |783((*src & 0x00f00000) >> 12) |784((*src & 0x0000f000) >> 8) |785((*src & 0x000000f0) >> 4));786src++;787*dest |= ((*src & 0xf0000000) |788((*src & 0x00f00000) << 4) |789((*src & 0x0000f000) << 8) |790((*src & 0x000000f0) << 12));791src++;792dest++;793}794#else795int siz = (width * height) >> 1;796797__asm {798push ebx;799push esi;800push edi;801802mov esi, dword ptr [src];803mov edi, dword ptr [dest];804mov ecx, dword ptr [siz];805806tc1_loop:807mov eax, dword ptr [esi];808add esi, 4;809810mov edx, eax;811and edx, 0xf0000000; // aaaa0000 00000000 00000000 00000000812shr edx, 16; // 00000000 00000000 aaaa0000 00000000813mov ebx, eax;814and ebx, 0x00f00000; // 00000000 rrrr0000 00000000 00000000815shr ebx, 12; // 00000000 00000000 0000rrrr 00000000816or edx, ebx; // 00000000 00000000 aaaarrrr 00000000817mov ebx, eax;818and ebx, 0x0000f000; // 00000000 00000000 gggg0000 00000000819shr ebx, 8; // 00000000 00000000 00000000 gggg0000820or edx, ebx; // 00000000 00000000 aaaarrrr gggg0000821and eax, 0x000000f0; // 00000000 00000000 00000000 bbbb0000822shr eax, 4; // 00000000 00000000 00000000 0000bbbb823or edx, eax; // 00000000 00000000 aaaarrrr ggggbbbb824825mov eax, dword ptr [esi];826add esi, 4;827828mov ebx, eax;829and ebx, 0xf0000000; // aaaa0000 00000000 00000000 00000000830or edx, ebx; // aaaa0000 00000000 aaaarrrr ggggbbbb831mov ebx, eax;832and ebx, 0x00f00000; // 00000000 rrrr0000 00000000 00000000833shl ebx, 4; // 0000rrrr 00000000 00000000 00000000834or edx, ebx; // aaaarrrr 00000000 aaaarrrr ggggbbbb835mov ebx, eax;836and ebx, 0x0000f000; // 00000000 00000000 gggg0000 00000000837shl ebx, 8; // 00000000 gggg0000 00000000 00000000838or edx, ebx; // aaaarrrr gggg0000 aaaarrrr ggggbbbb839and eax, 0x000000f0; // 00000000 00000000 00000000 bbbb0000840shl eax, 12; // 00000000 0000bbbb 00000000 00000000841or edx, eax; // arrrrrgg ggggbbbb aaaarrrr ggggbbbb842843mov dword ptr [edi], edx;844add edi, 4;845846dec ecx;847jnz tc1_loop;848849pop edi;850pop esi;851pop ebx;852}853#endif854}855856void857TxQuantize::ARGB8888_RGB565(uint32* src, uint32* dest, int width, int height)858{859#if 1860int siz = (width * height) >> 1;861int i;862for (i = 0; i < siz; i++) {863*dest = (((*src & 0x000000f8) >> 3) |864((*src & 0x0000fc00) >> 5) |865((*src & 0x00f80000) >> 8));866src++;867*dest |= (((*src & 0x000000f8) << 13) |868((*src & 0x0000fc00) << 11) |869((*src & 0x00f80000) << 8));870src++;871dest++;872}873#else874int siz = (width * height) >> 1;875876__asm {877push ebx;878push esi;879push edi;880881mov esi, dword ptr [src];882mov edi, dword ptr [dest];883mov ecx, dword ptr [siz];884885tc1_loop:886mov eax, dword ptr [esi];887add esi, 4;888889mov edx, eax;890and edx, 0x000000F8; // 00000000 00000000 00000000 bbbbb000891shr edx, 3; // 00000000 00000000 00000000 000bbbbb892mov ebx, eax;893and ebx, 0x0000FC00; // 00000000 00000000 gggggg00 00000000894shr ebx, 5; // 00000000 00000000 00000ggg ggg00000895or edx, ebx; // 00000000 00000000 00000ggg gggbbbbb896mov ebx, eax;897and ebx, 0x00F80000; // 00000000 rrrrr000 00000000 00000000898shr ebx, 8; // 00000000 00000000 rrrrr000 00000000899or edx, ebx; // 00000000 00000000 rrrrrggg gggbbbbb900901mov eax, dword ptr [esi];902add esi, 4;903904mov ebx, eax;905and ebx, 0x000000F8; // 00000000 00000000 00000000 bbbbb000906shl ebx, 13; // 00000000 000bbbbb 00000000 00000000907or edx, ebx; // 00000000 000bbbbb rrrrrggg gggbbbbb908mov ebx, eax;909and ebx, 0x0000FC00; // 00000000 00000000 gggggg00 00000000910shl ebx, 11; // 00000ggg ggg00000 00000000 00000000911or edx, ebx; // 00000ggg gggbbbbb rrrrrggg gggbbbbb912mov ebx, eax;913and ebx, 0x00F80000; // 00000000 rrrrr000 00000000 00000000914shl ebx, 8; // rrrrr000 00000000 00000000 00000000915or edx, ebx; // rrrrrggg gggbbbbb rrrrrggg gggbbbbb916917mov dword ptr [edi], edx;918add edi, 4;919920dec ecx;921jnz tc1_loop;922923pop edi;924pop esi;925pop ebx;926}927#endif928}929930void931TxQuantize::ARGB8888_A8(uint32* src, uint32* dest, int width, int height)932{933#if 1934int siz = (width * height) >> 2;935int i;936for (i = 0; i < siz; i++) {937*dest = (*src & 0x0000ff00) >> 8;938src++;939*dest |= (*src & 0x0000ff00);940src++;941*dest |= ((*src & 0x0000ff00) << 8);942src++;943*dest |= ((*src & 0x0000ff00) << 16);944src++;945dest++;946}947#else948int siz = (width * height) >> 2;949950__asm {951push ebx;952push esi;953push edi;954955mov esi, dword ptr [src];956mov edi, dword ptr [dest];957mov ecx, dword ptr [siz];958959tc1_loop:960mov eax, dword ptr [esi];961add esi, 4;962963#if 0964mov edx, eax; // we'll use A comp for every pixel965and edx, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000966shr edx, 24; // 00000000 00000000 00000000 aaaaaaaa967968mov eax, dword ptr [esi];969add esi, 4;970971and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000972shr eax, 16; // 00000000 00000000 aaaaaaaa 00000000973or edx, eax; // 00000000 00000000 aaaaaaaa aaaaaaaa974975mov eax, dword ptr [esi];976add esi, 4;977978and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000979shr eax, 8; // 00000000 aaaaaaaa 00000000 00000000980or edx, eax; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa981982mov eax, dword ptr [esi];983add esi, 4;984985and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 00000000986or edx, eax; // aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa987#endif988989#if 1990mov edx, eax; // we'll use G comp for every pixel991and edx, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000992shr edx, 8; // 00000000 00000000 00000000 aaaaaaaa993994mov eax, dword ptr [esi];995add esi, 4;996997and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 00000000998or edx, eax; // 00000000 00000000 aaaaaaaa aaaaaaaa9991000mov eax, dword ptr [esi];1001add esi, 4;10021003and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 000000001004shl eax, 8; // 00000000 aaaaaaaa 00000000 000000001005or edx, eax; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa10061007mov eax, dword ptr [esi];1008add esi, 4;10091010and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 000000001011shl eax, 16; // aaaaaaaa 00000000 00000000 000000001012or edx, eax; // aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa1013#endif10141015#if 01016mov edx, eax;1017and edx, 0x000000FF; // 00000000 00000000 00000000 aaaaaaaa10181019mov eax, dword ptr [esi];1020add esi, 4;10211022and eax, 0x0000FF00; // 00000000 00000000 aaaaaaaa 000000001023or edx, eax; // 00000000 00000000 aaaaaaaa aaaaaaaa10241025mov eax, dword ptr [esi];1026add esi, 4;10271028and eax, 0x00FF0000; // 00000000 aaaaaaaa 00000000 000000001029or edx, eax; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa10301031mov eax, dword ptr [esi];1032add esi, 4;10331034and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 000000001035or edx, eax; // aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa1036#endif1037mov dword ptr [edi], edx;1038add edi, 4;10391040dec ecx;1041jnz tc1_loop;10421043pop edi;1044pop esi;1045pop ebx;1046}1047#endif1048}10491050void1051TxQuantize::ARGB8888_AI44(uint32* src, uint32* dest, int width, int height)1052{1053#if 11054int siz = (width * height) >> 2;1055int i;1056for (i = 0; i < siz; i++) {1057*dest = (((*src & 0xf0000000) >> 24) | ((*src & 0x0000f000) >> 12));1058src++;1059*dest |= (((*src & 0xf0000000) >> 16) | ((*src & 0x0000f000) >> 4));1060src++;1061*dest |= (((*src & 0xf0000000) >> 8) | ((*src & 0x0000f000) << 4));1062src++;1063*dest |= ((*src & 0xf0000000) | ((*src & 0x0000f000) << 12));1064src++;1065dest++;1066}1067#else1068int siz = (width * height) >> 2;10691070__asm {1071push ebx;1072push esi;1073push edi;10741075mov esi, dword ptr [src];1076mov edi, dword ptr [dest];1077mov ecx, dword ptr [siz];10781079tc1_loop:1080mov eax, dword ptr [esi];1081add esi, 4;10821083mov edx, eax; // use A and G comps MSB1084and edx, 0xF0000000; // aaaa0000 00000000 00000000 000000001085mov ebx, eax;1086shr edx, 24; // 00000000 00000000 00000000 aaaa00001087and ebx, 0x0000F000; // 00000000 00000000 iiii0000 000000001088shr ebx, 12; // 00000000 00000000 00000000 0000iiii1089or edx, ebx; // 00000000 00000000 00000000 aaaaiiii10901091mov eax, dword ptr [esi];1092add esi, 4;10931094mov ebx, eax;1095and eax, 0xF0000000; // aaaa0000 00000000 00000000 000000001096shr eax, 16; // 00000000 00000000 aaaa0000 000000001097and ebx, 0x0000F000; // 00000000 00000000 iiii0000 000000001098shr ebx, 4; // 00000000 00000000 0000iiii 000000001099or eax, ebx; // 00000000 00000000 aaaaiiii 000000001100or edx, eax; // 00000000 00000000 aaaaiiii aaaaiiii11011102mov eax, dword ptr [esi];1103add esi, 4;11041105mov ebx, eax;1106and eax, 0xF0000000; // aaaa0000 00000000 00000000 000000001107shr eax, 8; // 00000000 aaaa0000 00000000 000000001108and ebx, 0x0000F000; // 00000000 00000000 iiii0000 000000001109shl ebx, 4; // 00000000 0000iiii 00000000 000000001110or eax, ebx; // 00000000 aaaaiiii 00000000 000000001111or edx, eax; // 00000000 aaaaiiii aaaaiiii aaaaiiii11121113mov eax, dword ptr [esi];1114add esi, 4;11151116mov ebx, eax;1117and eax, 0xF0000000; // aaaa0000 00000000 00000000 000000001118and ebx, 0x0000F000; // 00000000 00000000 iiii0000 000000001119shl ebx, 12; // 0000iiii 00000000 00000000 000000001120or eax, ebx; // aaaaiiii 00000000 00000000 000000001121or edx, eax; // aaaaiiii aaaaiiii aaaaiiii aaaaiiii11221123mov dword ptr [edi], edx;1124add edi, 4;11251126dec ecx;1127jnz tc1_loop;11281129pop edi;1130pop esi;1131pop ebx;1132}1133#endif1134}11351136void1137TxQuantize::ARGB8888_AI88(uint32* src, uint32* dest, int width, int height)1138{1139#if 11140int siz = (width * height) >> 1;1141int i;1142for (i = 0; i < siz; i++) {1143*dest = (((*src & 0xff000000) >> 16) | ((*src & 0x0000ff00) >> 8));1144src++;1145*dest |= ((*src & 0xff000000) | ((*src & 0x0000ff00) << 8));1146src++;1147dest++;1148}1149#else1150int siz = (width * height) >> 1;11511152__asm {1153push ebx;1154push esi;1155push edi;11561157mov esi, dword ptr [src];1158mov edi, dword ptr [dest];1159mov ecx, dword ptr [siz];11601161tc1_loop:1162mov eax, dword ptr [esi];1163add esi, 4;11641165mov edx, eax;1166and edx, 0xFF000000; // aaaaaaaa 00000000 00000000 000000001167mov ebx, eax;1168shr edx, 16; // 00000000 00000000 aaaaaaaa 000000001169and ebx, 0x0000FF00; // 00000000 00000000 iiiiiiii 000000001170shr ebx, 8; // 00000000 00000000 00000000 iiiiiiii1171or edx, ebx; // 00000000 00000000 aaaaaaaa iiiiiiii11721173mov eax, dword ptr [esi];1174add esi, 4;11751176mov ebx, eax;1177and eax, 0xFF000000; // aaaaaaaa 00000000 00000000 000000001178and ebx, 0x0000FF00; // 00000000 00000000 iiiiiiii 000000001179shl ebx, 8; // 00000000 iiiiiiii 00000000 000000001180or eax, ebx; // aaaaaaaa iiiiiiii 00000000 000000001181or edx, eax; // aaaaaaaa iiiiiiii aaaaaaaa iiiiiiii11821183mov dword ptr [edi], edx;1184add edi, 4;11851186dec ecx;1187jnz tc1_loop;11881189pop edi;1190pop esi;1191pop ebx;1192}1193#endif1194}11951196/* R.W. Floyd and L. Steinberg, An adaptive algorithm1197* for spatial grey scale, Proceedings of the Society1198* of Information Display 17, pp75-77, 19761199*/1200void1201TxQuantize::ARGB8888_RGB565_ErrD(uint32* src, uint32* dst, int width, int height)1202{1203/* Floyd-Steinberg error-diffusion halftoning */12041205int i, x, y;1206int qr, qg, qb; /* quantized incoming values */1207int ir, ig, ib; /* incoming values */1208int t;1209int *errR = new int[width];1210int *errG = new int[width];1211int *errB = new int[width];12121213uint16 *dest = (uint16 *)dst;12141215for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = 0;12161217for (y = 0; y < height; y++) {1218qr = qg = qb = 0;1219for (x = 0; x < width; x++) {1220/* incoming pixel values */1221ir = ((*src >> 16) & 0xFF) * 10000;1222ig = ((*src >> 8) & 0xFF) * 10000;1223ib = ((*src ) & 0xFF) * 10000;12241225/* quantize pixel values.1226* qr * 0.4375 is the error from the pixel to the left,1227* errR is the error from the pixel to the top, top left, and top right */1228/* qr * 0.4375 is the error distribution to the EAST in1229* the previous loop */1230ir += errR[x] + qr * 4375 / 10000;1231ig += errG[x] + qg * 4375 / 10000;1232ib += errB[x] + qb * 4375 / 10000;12331234/* error distribution to the SOUTH-EAST in the previous loop1235* can't calculate in the previous loop because it steps on1236* the above quantization */1237errR[x] = qr * 625 / 10000;1238errG[x] = qg * 625 / 10000;1239errB[x] = qb * 625 / 10000;12401241qr = ir;1242qg = ig;1243qb = ib;12441245/* clamp */1246if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000;1247if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000;1248if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000;12491250/* convert to RGB565 */1251qr = qr * 0x1F / 2550000;1252qg = qg * 0x3F / 2550000;1253qb = qb * 0x1F / 2550000;12541255/* this is the dithered pixel */1256t = (qr << 11) | (qg << 5) | qb;12571258/* compute the errors */1259qr = ((qr << 3) | (qr >> 2)) * 10000;1260qg = ((qg << 2) | (qg >> 4)) * 10000;1261qb = ((qb << 3) | (qb >> 2)) * 10000;1262qr = ir - qr;1263qg = ig - qg;1264qb = ib - qb;12651266/* compute the error distributions */1267/* Floyd-Steinberg filter1268* 7/16 (=0.4375) to the EAST1269* 5/16 (=0.3125) to the SOUTH1270* 1/16 (=0.0625) to the SOUTH-EAST1271* 3/16 (=0.1875) to the SOUTH-WEST1272*1273* x 7/161274* 3/16 5/16 1/161275*/1276/* SOUTH-WEST */1277if (x > 1) {1278errR[x - 1] += qr * 1875 / 10000;1279errG[x - 1] += qg * 1875 / 10000;1280errB[x - 1] += qb * 1875 / 10000;1281}12821283/* SOUTH */1284errR[x] += qr * 3125 / 10000;1285errG[x] += qg * 3125 / 10000;1286errB[x] += qb * 3125 / 10000;12871288*dest = (t & 0xFFFF);12891290dest++;1291src++;1292}1293}12941295delete [] errR;1296delete [] errG;1297delete [] errB;1298}129913001301void1302TxQuantize::ARGB8888_ARGB1555_ErrD(uint32* src, uint32* dst, int width, int height)1303{1304/* Floyd-Steinberg error-diffusion halftoning */13051306int i, x, y;1307int qr, qg, qb; /* quantized incoming values */1308int ir, ig, ib; /* incoming values */1309int t;1310int *errR = new int[width];1311int *errG = new int[width];1312int *errB = new int[width];13131314uint16 *dest = (uint16 *)dst;13151316for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = 0;13171318for (y = 0; y < height; y++) {1319qr = qg = qb = 0;1320for (x = 0; x < width; x++) {1321/* incoming pixel values */1322ir = ((*src >> 16) & 0xFF) * 10000;1323ig = ((*src >> 8) & 0xFF) * 10000;1324ib = ((*src ) & 0xFF) * 10000;13251326/* quantize pixel values.1327* qr * 0.4375 is the error from the pixel to the left,1328* errR is the error from the pixel to the top, top left, and top right */1329/* qr * 0.4375 is the error distribution to the EAST in1330* the previous loop */1331ir += errR[x] + qr * 4375 / 10000;1332ig += errG[x] + qg * 4375 / 10000;1333ib += errB[x] + qb * 4375 / 10000;13341335/* error distribution to the SOUTH-EAST of the previous loop.1336* cannot calculate in the previous loop because it steps on1337* the above quantization */1338errR[x] = qr * 625 / 10000;1339errG[x] = qg * 625 / 10000;1340errB[x] = qb * 625 / 10000;13411342qr = ir;1343qg = ig;1344qb = ib;13451346/* clamp */1347if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000;1348if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000;1349if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000;13501351/* convert to RGB555 */1352qr = qr * 0x1F / 2550000;1353qg = qg * 0x1F / 2550000;1354qb = qb * 0x1F / 2550000;13551356/* this is the dithered pixel */1357t = (qr << 10) | (qg << 5) | qb;1358t |= ((*src >> 24) ? 0x8000 : 0);13591360/* compute the errors */1361qr = ((qr << 3) | (qr >> 2)) * 10000;1362qg = ((qg << 3) | (qg >> 2)) * 10000;1363qb = ((qb << 3) | (qb >> 2)) * 10000;1364qr = ir - qr;1365qg = ig - qg;1366qb = ib - qb;13671368/* compute the error distributions */1369/* Floyd-Steinberg filter1370* 7/16 (=0.4375) to the EAST1371* 5/16 (=0.3125) to the SOUTH1372* 1/16 (=0.0625) to the SOUTH-EAST1373* 3/16 (=0.1875) to the SOUTH-WEST1374*1375* x 7/161376* 3/16 5/16 1/161377*/1378/* SOUTH-WEST */1379if (x > 1) {1380errR[x - 1] += qr * 1875 / 10000;1381errG[x - 1] += qg * 1875 / 10000;1382errB[x - 1] += qb * 1875 / 10000;1383}13841385/* SOUTH */1386errR[x] += qr * 3125 / 10000;1387errG[x] += qg * 3125 / 10000;1388errB[x] += qb * 3125 / 10000;13891390*dest = (t & 0xFFFF);13911392dest++;1393src++;1394}1395}13961397delete [] errR;1398delete [] errG;1399delete [] errB;1400}14011402void1403TxQuantize::ARGB8888_ARGB4444_ErrD(uint32* src, uint32* dst, int width, int height)1404{1405/* Floyd-Steinberg error-diffusion halftoning */14061407/* NOTE: alpha dithering looks better for alpha gradients, but are prone1408* to producing noisy speckles for constant or step level alpha. Output1409* results should always be checked.1410*/1411boolean ditherAlpha = 0;14121413int i, x, y;1414int qr, qg, qb, qa; /* quantized incoming values */1415int ir, ig, ib, ia; /* incoming values */1416int t;1417int *errR = new int[width];1418int *errG = new int[width];1419int *errB = new int[width];1420int *errA = new int[width];14211422uint16 *dest = (uint16 *)dst;14231424for (i = 0; i < width; i++) errR[i] = errG[i] = errB[i] = errA[i] = 0;14251426for (y = 0; y < height; y++) {1427qr = qg = qb = qa = 0;1428for (x = 0; x < width; x++) {1429/* incoming pixel values */1430ir = ((*src >> 16) & 0xFF) * 10000;1431ig = ((*src >> 8) & 0xFF) * 10000;1432ib = ((*src ) & 0xFF) * 10000;1433ia = ((*src >> 24) & 0xFF) * 10000;14341435/* quantize pixel values.1436* qr * 0.4375 is the error from the pixel to the left,1437* errR is the error from the pixel to the top, top left, and top right */1438/* qr * 0.4375 is the error distribution to the EAST in1439* the previous loop */1440ir += errR[x] + qr * 4375 / 10000;1441ig += errG[x] + qg * 4375 / 10000;1442ib += errB[x] + qb * 4375 / 10000;1443ia += errA[x] + qa * 4375 / 10000;14441445/* error distribution to the SOUTH-EAST of the previous loop.1446* cannot calculate in the previous loop because it steps on1447* the above quantization */1448errR[x] = qr * 625 / 10000;1449errG[x] = qg * 625 / 10000;1450errB[x] = qb * 625 / 10000;1451errA[x] = qa * 625 / 10000;14521453qr = ir;1454qg = ig;1455qb = ib;1456qa = ia;14571458/* clamp */1459if (qr < 0) qr = 0; else if (qr > 2550000) qr = 2550000;1460if (qg < 0) qg = 0; else if (qg > 2550000) qg = 2550000;1461if (qb < 0) qb = 0; else if (qb > 2550000) qb = 2550000;1462if (qa < 0) qa = 0; else if (qa > 2550000) qa = 2550000;14631464/* convert to RGB444 */1465qr = qr * 0xF / 2550000;1466qg = qg * 0xF / 2550000;1467qb = qb * 0xF / 2550000;1468qa = qa * 0xF / 2550000;14691470/* this is the value to be returned */1471if (ditherAlpha) {1472t = (qa << 12) | (qr << 8) | (qg << 4) | qb;1473} else {1474t = (qr << 8) | (qg << 4) | qb;1475t |= (*src >> 16) & 0xF000;1476}14771478/* compute the errors */1479qr = ((qr << 4) | qr) * 10000;1480qg = ((qg << 4) | qg) * 10000;1481qb = ((qb << 4) | qb) * 10000;1482qa = ((qa << 4) | qa) * 10000;1483qr = ir - qr;1484qg = ig - qg;1485qb = ib - qb;1486qa = ia - qa;14871488/* compute the error distributions */1489/* Floyd-Steinberg filter1490* 7/16 (=0.4375) to the EAST1491* 5/16 (=0.3125) to the SOUTH1492* 1/16 (=0.0625) to the SOUTH-EAST1493* 3/16 (=0.1875) to the SOUTH-WEST1494*1495* x 7/161496* 3/16 5/16 1/161497*/1498/* SOUTH-WEST */1499if (x > 1) {1500errR[x - 1] += qr * 1875 / 10000;1501errG[x - 1] += qg * 1875 / 10000;1502errB[x - 1] += qb * 1875 / 10000;1503errA[x - 1] += qa * 1875 / 10000;1504}15051506/* SOUTH */1507errR[x] += qr * 3125 / 10000;1508errG[x] += qg * 3125 / 10000;1509errB[x] += qb * 3125 / 10000;1510errA[x] += qa * 3125 / 10000;15111512*dest = (t & 0xFFFF);15131514dest++;1515src++;1516}1517}15181519delete [] errR;1520delete [] errG;1521delete [] errB;1522delete [] errA;1523}15241525void1526TxQuantize::ARGB8888_AI44_ErrD(uint32* src, uint32* dst, int width, int height)1527{1528/* Floyd-Steinberg error-diffusion halftoning */15291530/* NOTE: alpha dithering looks better for alpha gradients, but are prone1531* to producing noisy speckles for constant or step level alpha. Output1532* results should always be checked.1533*/1534boolean ditherAlpha = 0;15351536int i, x, y;1537int qi, qa; /* quantized incoming values */1538int ii, ia; /* incoming values */1539int t;1540int *errI = new int[width];1541int *errA = new int[width];15421543uint8 *dest = (uint8 *)dst;15441545for (i = 0; i < width; i++) errI[i] = errA[i] = 0;15461547for (y = 0; y < height; y++) {1548qi = qa = 0;1549for (x = 0; x < width; x++) {1550/* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.114 */1551ii = ((*src >> 16) & 0xFF) * 2990 +1552((*src >> 8) & 0xFF) * 5870 +1553((*src ) & 0xFF) * 1140;1554ia = ((*src >> 24) & 0xFF) * 10000;15551556/* quantize pixel values.1557* qi * 0.4375 is the error from the pixel to the left,1558* errI is the error from the pixel to the top, top left, and top right */1559/* qi * 0.4375 is the error distrtibution to the EAST in1560* the previous loop */1561ii += errI[x] + qi * 4375 / 10000;1562ia += errA[x] + qa * 4375 / 10000;15631564/* error distribution to the SOUTH-EAST in the previous loop.1565* cannot calculate in the previous loop because it steps on1566* the above quantization */1567errI[x] = qi * 625 / 10000;1568errA[x] = qa * 625 / 10000;15691570qi = ii;1571qa = ia;15721573/* clamp */1574if (qi < 0) qi = 0; else if (qi > 2550000) qi = 2550000;1575if (qa < 0) qa = 0; else if (qa > 2550000) qa = 2550000;15761577/* convert to I4 */1578qi = qi * 0xF / 2550000;1579qa = qa * 0xF / 2550000;15801581/* this is the value to be returned */1582if (ditherAlpha) {1583t = (qa << 4) | qi;1584} else {1585t = qi;1586t |= ((*src >> 24) & 0xF0);1587}15881589/* compute the errors */1590qi = ((qi << 4) | qi) * 10000;1591qa = ((qa << 4) | qa) * 10000;1592qi = ii - qi;1593qa = ia - qa;15941595/* compute the error distributions */1596/* Floyd-Steinberg filter1597* 7/16 (=0.4375) to the EAST1598* 5/16 (=0.3125) to the SOUTH1599* 1/16 (=0.0625) to the SOUTH-EAST1600* 3/16 (=0.1875) to the SOUTH-WEST1601*1602* x 7/161603* 3/16 5/16 1/161604*/1605/* SOUTH-WEST */1606if (x > 1) {1607errI[x - 1] += qi * 1875 / 10000;1608errA[x - 1] += qa * 1875 / 10000;1609}16101611/* SOUTH */1612errI[x] += qi * 3125 / 10000;1613errA[x] += qa * 3125 / 10000;16141615*dest = t & 0xFF;16161617dest++;1618src++;1619}1620}16211622delete [] errI;1623delete [] errA;1624}16251626void1627TxQuantize::ARGB8888_AI88_Slow(uint32* src, uint32* dst, int width, int height)1628{1629int x, y;1630uint16 *dest = (uint16 *)dst;1631for (y = 0; y < height; y++) {1632for (x = 0; x < width; x++) {1633#if 11634/* libpng style grayscale conversion.1635* Reduce RGB files to grayscale with or without alpha1636* using the equation given in Poynton's ColorFAQ at1637* <http://www.inforamp.net/~poynton/>1638* Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net1639*1640* Y = 0.212671 * R + 0.715160 * G + 0.072169 * B1641*1642* We approximate this with1643*1644* Y = 0.21268 * R + 0.7151 * G + 0.07217 * B1645*1646* which can be expressed with integers as1647*1648* Y = (6969 * R + 23434 * G + 2365 * B)/327681649*1650* The calculation is to be done in a linear colorspace.1651*/1652*dest = (((int)((((*src >> 16) & 0xFF) * 6969 +1653((*src >> 8) & 0xFF) * 23434 +1654((*src ) & 0xFF) * 2365) / 32768) & 0xFF) |1655(uint16)((*src >> 16) & 0xFF00));1656#else1657/* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.1141658* this is same as the standard NTSC gray scale conversion. */1659*dest = (((int)((((*src >> 16) & 0xFF) * 299 +1660((*src >> 8) & 0xFF) * 587 +1661((*src ) & 0xFF) * 114) / 1000) & 0xFF) |1662(uint16)((*src >> 16) & 0xFF00));1663#endif1664dest++;1665src++;1666}1667}1668}16691670void1671TxQuantize::ARGB8888_I8_Slow(uint32* src, uint32* dst, int width, int height)1672{1673int x, y;1674uint8 *dest = (uint8 *)dst;1675for (y = 0; y < height; y++) {1676for (x = 0; x < width; x++) {1677#if 11678/* libpng style Intensity = (6969 * R + 23434 * G + 2365 * B)/32768 */1679*dest = (int)((((*src >> 16) & 0xFF) * 6969 +1680((*src >> 8) & 0xFF) * 23434 +1681((*src ) & 0xFF) * 2365) / 32768) & 0xFF;1682#else1683/* 3dfx style Intensity = R * 0.299 + G * 0.587 + B * 0.1141684* this is same as the standard NTSC gray scale conversion. */1685*dest = (int)((((*src >>16) & 0xFF) * 299 +1686((*src >> 8) & 0xFF) * 587 +1687((*src ) & 0xFF) * 114) / 1000) & 0xFF;1688#endif1689dest++;1690src++;1691}1692}1693}16941695void1696TxQuantize::P8_16BPP(uint32* src, uint32* dest, int width, int height, uint32* palette)1697{1698/* passed in palette is RGBA5551 format */1699#if 11700int i;1701int size = width * height;1702for (i = 0; i < size; i++) {1703((uint16*)dest)[i] = ((uint16*)palette)[(int)(((uint8*)src)[i])];1704((uint16*)dest)[i] = ((((uint16*)dest)[i] << 15) | (((uint16*)dest)[i] >> 1));1705}1706#else17071708/* not finished yet... */17091710int siz = (width * height) >> 2;17111712__asm {1713push ebx;1714push esi;1715push edi;17161717mov esi, dword ptr [src];1718mov edi, dword ptr [dest];1719mov ecx, dword ptr [siz];1720mov edx, dword ptr [palette];17211722tc1_loop:1723mov eax, dword ptr [esi];1724add esi, 4;17251726dec ecx;1727jnz tc1_loop;17281729pop edi;1730pop esi;1731pop ebx;1732}1733#endif1734}17351736boolean1737TxQuantize::quantize(uint8* src, uint8* dest, int width, int height, uint16 srcformat, uint16 destformat, boolean fastQuantizer)1738{1739typedef void (TxQuantize::*quantizerFunc)(uint32* src, uint32* dest, int width, int height);1740quantizerFunc quantizer;1741int bpp_shift = 0;17421743if (destformat == GR_TEXFMT_ARGB_8888) {1744switch (srcformat) {1745case GR_TEXFMT_ARGB_1555:1746quantizer = &TxQuantize::ARGB1555_ARGB8888;1747bpp_shift = 1;1748break;1749case GR_TEXFMT_ARGB_4444:1750quantizer = &TxQuantize::ARGB4444_ARGB8888;1751bpp_shift = 1;1752break;1753case GR_TEXFMT_RGB_565:1754quantizer = &TxQuantize::RGB565_ARGB8888;1755bpp_shift = 1;1756break;1757case GR_TEXFMT_ALPHA_8:1758quantizer = &TxQuantize::A8_ARGB8888;1759bpp_shift = 2;1760break;1761case GR_TEXFMT_ALPHA_INTENSITY_44:1762quantizer = &TxQuantize::AI44_ARGB8888;1763bpp_shift = 2;1764break;1765case GR_TEXFMT_ALPHA_INTENSITY_88:1766quantizer = &TxQuantize::AI88_ARGB8888;1767bpp_shift = 1;1768break;1769default:1770return 0;1771}17721773#if !defined(NO_FILTER_THREAD)1774unsigned int numcore = _numcore;1775unsigned int blkrow = 0;1776while (numcore > 1 && blkrow == 0) {1777blkrow = (height >> 2) / numcore;1778numcore--;1779}1780if (blkrow > 0 && numcore > 1) {1781std::thread *thrd[MAX_NUMCORE];1782unsigned int i;1783int blkheight = blkrow << 2;1784unsigned int srcStride = (width * blkheight) << (2 - bpp_shift);1785unsigned int destStride = srcStride << bpp_shift;1786for (i = 0; i < numcore - 1; i++) {1787thrd[i] = new std::thread(std::bind(quantizer,1788this,1789(uint32*)src,1790(uint32*)dest,1791width,1792blkheight));1793src += srcStride;1794dest += destStride;1795}1796thrd[i] = new std::thread(std::bind(quantizer,1797this,1798(uint32*)src,1799(uint32*)dest,1800width,1801height - blkheight * i));1802for (i = 0; i < numcore; i++) {1803thrd[i]->join();1804delete thrd[i];1805}1806} else {1807(*this.*quantizer)((uint32*)src, (uint32*)dest, width, height);1808}1809#else1810(*this.*quantizer)((uint32*)src, (uint32*)dest, width, height);1811#endif18121813} else if (srcformat == GR_TEXFMT_ARGB_8888) {1814switch (destformat) {1815case GR_TEXFMT_ARGB_1555:1816quantizer = fastQuantizer ? &TxQuantize::ARGB8888_ARGB1555 : &TxQuantize::ARGB8888_ARGB1555_ErrD;1817bpp_shift = 1;1818break;1819case GR_TEXFMT_ARGB_4444:1820quantizer = fastQuantizer ? &TxQuantize::ARGB8888_ARGB4444 : &TxQuantize::ARGB8888_ARGB4444_ErrD;1821bpp_shift = 1;1822break;1823case GR_TEXFMT_RGB_565:1824quantizer = fastQuantizer ? &TxQuantize::ARGB8888_RGB565 : &TxQuantize::ARGB8888_RGB565_ErrD;1825bpp_shift = 1;1826break;1827case GR_TEXFMT_ALPHA_8:1828case GR_TEXFMT_INTENSITY_8:1829quantizer = fastQuantizer ? &TxQuantize::ARGB8888_A8 : &TxQuantize::ARGB8888_I8_Slow;1830bpp_shift = 2;1831break;1832case GR_TEXFMT_ALPHA_INTENSITY_44:1833quantizer = fastQuantizer ? &TxQuantize::ARGB8888_AI44 : &TxQuantize::ARGB8888_AI44_ErrD;1834bpp_shift = 2;1835break;1836case GR_TEXFMT_ALPHA_INTENSITY_88:1837quantizer = fastQuantizer ? &TxQuantize::ARGB8888_AI88 : &TxQuantize::ARGB8888_AI88_Slow;1838bpp_shift = 1;1839break;1840default:1841return 0;1842}18431844#if !defined(NO_FILTER_THREAD)1845unsigned int numcore = _numcore;1846unsigned int blkrow = 0;1847while (numcore > 1 && blkrow == 0) {1848blkrow = (height >> 2) / numcore;1849numcore--;1850}1851if (blkrow > 0 && numcore > 1) {1852std::thread *thrd[MAX_NUMCORE];1853unsigned int i;1854int blkheight = blkrow << 2;1855unsigned int srcStride = (width * blkheight) << 2;1856unsigned int destStride = srcStride >> bpp_shift;1857for (i = 0; i < numcore - 1; i++) {1858thrd[i] = new std::thread(std::bind(quantizer,1859this,1860(uint32*)src,1861(uint32*)dest,1862width,1863blkheight));1864src += srcStride;1865dest += destStride;1866}1867thrd[i] = new std::thread(std::bind(quantizer,1868this,1869(uint32*)src,1870(uint32*)dest,1871width,1872height - blkheight * i));1873for (i = 0; i < numcore; i++) {1874thrd[i]->join();1875delete thrd[i];1876}1877} else {1878(*this.*quantizer)((uint32*)src, (uint32*)dest, width, height);1879}1880#else1881(*this.*quantizer)((uint32*)src, (uint32*)dest, width, height);1882#endif18831884} else {1885return 0;1886}18871888return 1;1889}18901891boolean1892TxQuantize::FXT1(uint8 *src, uint8 *dest,1893int srcwidth, int srcheight, uint16 srcformat,1894int *destwidth, int *destheight, uint16 *destformat)1895{1896/*1897* NOTE: src must be in ARGB8888 format, srcformat describes1898* the closest 16bbp representation of src.1899*1900* NOTE: I have modified the dxtn library to use ARGB format1901* which originaly was ABGR format.1902*/19031904boolean bRet = 0;19051906if (_tx_compress_fxt1 &&1907srcwidth >= 8 && srcheight >= 4) {1908/* compress to fxt11909* width and height must be larger than 8 and 4 respectively1910*/1911int dstRowStride = ((srcwidth + 7) & ~7) << 1;1912int srcRowStride = (srcwidth << 2);19131914#if !defined(NO_FILTER_THREAD)1915unsigned int numcore = _numcore;1916unsigned int blkrow = 0;1917while (numcore > 1 && blkrow == 0) {1918blkrow = (srcheight >> 2) / numcore;1919numcore--;1920}1921if (blkrow > 0 && numcore > 1) {1922std::thread *thrd[MAX_NUMCORE];1923unsigned int i;1924int blkheight = blkrow << 2;1925unsigned int srcStride = (srcwidth * blkheight) << 2;1926unsigned int destStride = dstRowStride * blkrow;1927for (i = 0; i < numcore - 1; i++) {1928thrd[i] = new std::thread(std::bind(_tx_compress_fxt1,1929srcwidth,1930blkheight,19314,1932src,1933srcRowStride,1934dest,1935dstRowStride));1936src += srcStride;1937dest += destStride;1938}1939thrd[i] = new std::thread(std::bind(_tx_compress_fxt1,1940srcwidth,1941srcheight - blkheight * i,19424,1943src,1944srcRowStride,1945dest,1946dstRowStride));1947for (i = 0; i < numcore; i++) {1948thrd[i]->join();1949delete thrd[i];1950}1951} else {1952(*_tx_compress_fxt1)(srcwidth, /* width */1953srcheight, /* height */19544, /* comps: ARGB8888=4, RGB888=3 */1955src, /* source */1956srcRowStride, /* width*comps */1957dest, /* destination */1958dstRowStride); /* 16 bytes per 8x4 texel */1959}1960#else1961(*_tx_compress_fxt1)(srcwidth, /* width */1962srcheight, /* height */19634, /* comps: ARGB8888=4, RGB888=3 */1964src, /* source */1965srcRowStride, /* width*comps */1966dest, /* destination */1967dstRowStride); /* 16 bytes per 8x4 texel */1968#endif19691970/* dxtn adjusts width and height to M8 and M4 respectively by replication */1971*destwidth = (srcwidth + 7) & ~7;1972*destheight = (srcheight + 3) & ~3;1973*destformat = GR_TEXFMT_ARGB_CMP_FXT1;19741975bRet = 1;1976}19771978return bRet;1979}19801981boolean1982TxQuantize::DXTn(uint8 *src, uint8 *dest,1983int srcwidth, int srcheight, uint16 srcformat,1984int *destwidth, int *destheight, uint16 *destformat)1985{1986/*1987* NOTE: src must be in ARGB8888 format, srcformat describes1988* the closest 16bbp representation of src.1989*1990* NOTE: I have modified the dxtn library to use ARGB format1991* which originaly was ABGR format.1992*/19931994boolean bRet = 0;19951996if (_tx_compress_dxtn &&1997srcwidth >= 4 && srcheight >= 4) {1998/* compress to dxtn1999* width and height must be larger than 42000*/20012002/* skip formats that DXTn won't help in size. */2003if (srcformat == GR_TEXFMT_ALPHA_8 ||2004srcformat == GR_TEXFMT_ALPHA_INTENSITY_44) {2005; /* shutup compiler */2006} else {2007int dstRowStride = ((srcwidth + 3) & ~3) << 2;2008int compression = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;20092010*destformat = GR_TEXFMT_ARGB_CMP_DXT5;20112012#if !GLIDE64_DXTN2013/* okay... we are going to disable DXT1 with 1bit alpha2014* for Glide64. some textures have all 0 alpha values.2015* see "N64 Kobe Bryant in NBA Courtside"2016*/2017if (srcformat == GR_TEXFMT_ARGB_1555) {2018dstRowStride >>= 1;2019compression = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;2020*destformat = GR_TEXFMT_ARGB_CMP_DXT1;2021} else2022#endif2023if (srcformat == GR_TEXFMT_RGB_565 ||2024srcformat == GR_TEXFMT_INTENSITY_8) {2025dstRowStride >>= 1;2026compression = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;2027*destformat = GR_TEXFMT_ARGB_CMP_DXT1;2028}20292030#if !defined(NO_FILTER_THREAD)2031unsigned int numcore = _numcore;2032unsigned int blkrow = 0;2033while (numcore > 1 && blkrow == 0) {2034blkrow = (srcheight >> 2) / numcore;2035numcore--;2036}2037if (blkrow > 0 && numcore > 1) {2038std::thread *thrd[MAX_NUMCORE];2039unsigned int i;2040int blkheight = blkrow << 2;2041unsigned int srcStride = (srcwidth * blkheight) << 2;2042unsigned int destStride = dstRowStride * blkrow;2043for (i = 0; i < numcore - 1; i++) {2044thrd[i] = new std::thread(std::bind(_tx_compress_dxtn,20454,2046srcwidth,2047blkheight,2048src,2049compression,2050dest,2051dstRowStride));2052src += srcStride;2053dest += destStride;2054}2055thrd[i] = new std::thread(std::bind(_tx_compress_dxtn,20564,2057srcwidth,2058srcheight - blkheight * i,2059src,2060compression,2061dest,2062dstRowStride));2063for (i = 0; i < numcore; i++) {2064thrd[i]->join();2065delete thrd[i];2066}2067} else {2068(*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */2069srcwidth, /* width */2070srcheight, /* height */2071src, /* source */2072compression, /* format */2073dest, /* destination */2074dstRowStride); /* DXT1 = 8 bytes per 4x4 texel2075* others = 16 bytes per 4x4 texel */2076}2077#else2078(*_tx_compress_dxtn)(4, /* comps: ARGB8888=4, RGB888=3 */2079srcwidth, /* width */2080srcheight, /* height */2081src, /* source */2082compression, /* format */2083dest, /* destination */2084dstRowStride); /* DXT1 = 8 bytes per 4x4 texel2085* others = 16 bytes per 4x4 texel */2086#endif20872088/* dxtn adjusts width and height to M4 by replication */2089*destwidth = (srcwidth + 3) & ~3;2090*destheight = (srcheight + 3) & ~3;20912092bRet = 1;2093}2094}20952096return bRet;2097}20982099boolean2100TxQuantize::compress(uint8 *src, uint8 *dest,2101int srcwidth, int srcheight, uint16 srcformat,2102int *destwidth, int *destheight, uint16 *destformat,2103int compressionType)2104{2105boolean bRet = 0;21062107switch (compressionType) {2108case FXT1_COMPRESSION:2109bRet = FXT1(src, dest,2110srcwidth, srcheight, srcformat,2111destwidth, destheight, destformat);2112break;2113case S3TC_COMPRESSION:2114bRet = DXTn(src, dest,2115srcwidth, srcheight, srcformat,2116destwidth, destheight, destformat);2117break;2118case NCC_COMPRESSION:2119/* TODO: narrow channel compression */2120;2121}21222123return bRet;2124}21252126#if 0 /* unused */2127void2128TxQuantize::I8_ARGB8888(uint32* src, uint32* dest, int width, int height)2129{2130int siz = (width * height) >> 2;21312132__asm {2133push ebx;2134push esi;2135push edi;21362137mov esi, dword ptr [src];2138mov edi, dword ptr [dest];2139mov ecx, dword ptr [siz];21402141tc1_loop:2142mov eax, dword ptr [esi];2143add esi, 4;21442145// aaaaaaaa2146// 11111111 aaaaaaaa aaaaaaaa aaaaaaaa2147mov edx, eax;2148and eax, 0x000000ff;2149mov ebx, eax; // 00000000 00000000 00000000 aaaaaaaa2150shl ebx, 8; // 00000000 00000000 aaaaaaaa 000000002151or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa2152shl ebx, 8; // 00000000 aaaaaaaa 00000000 000000002153or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa2154or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa21552156mov dword ptr [edi], eax;2157add edi, 4;21582159mov eax, edx;2160and eax, 0x0000ff00;2161mov ebx, eax; // 00000000 00000000 aaaaaaaa 000000002162shr ebx, 8; // 00000000 00000000 00000000 aaaaaaaa2163or eax, ebx; // 00000000 00000000 aaaaaaaa aaaaaaaa2164shl ebx, 16; // 00000000 aaaaaaaa 00000000 000000002165or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa2166or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa21672168mov dword ptr [edi], eax;2169add edi, 4;21702171mov eax, edx;2172and eax, 0x00ff0000;2173mov ebx, eax; // 00000000 aaaaaaaa 00000000 000000002174shr ebx, 8; // 00000000 00000000 aaaaaaaa 000000002175or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa 000000002176shr ebx, 8; // 00000000 00000000 00000000 aaaaaaaa2177or eax, ebx; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa2178or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa21792180mov dword ptr [edi], eax;2181add edi, 4;21822183mov eax, edx;2184and eax, 0xff000000;2185mov ebx, eax; // aaaaaaaa 00000000 00000000 000000002186shr ebx, 8; // 00000000 aaaaaaaa 00000000 000000002187or eax, ebx; // aaaaaaaa aaaaaaaa 00000000 000000002188shr ebx, 8; // 00000000 00000000 aaaaaaaa 000000002189or eax, ebx; // aaaaaaaa aaaaaaaa aaaaaaaa 000000002190shr eax, 8; // 00000000 aaaaaaaa aaaaaaaa aaaaaaaa2191or eax, 0xff000000; // 11111111 aaaaaaaa aaaaaaaa aaaaaaaa21922193mov dword ptr [edi], eax;2194add edi, 4;21952196dec ecx;2197jnz tc1_loop;21982199pop edi;2200pop esi;2201pop ebx;2202}2203}22042205void2206TxQuantize::ARGB8888_I8(uint32* src, uint32* dest, int width, int height)2207{2208ARGB8888_A8(src, dest, width, height);2209}22102211void2212TxQuantize::ARGB1555_ABGR8888(uint32* src, uint32* dest, int width, int height)2213{2214int siz = (width * height) >> 1;22152216__asm {2217push ebx;2218push esi;2219push edi;22202221mov esi, dword ptr [src];2222mov edi, dword ptr [dest];2223mov ecx, dword ptr [siz];22242225tc1_loop:2226mov eax, dword ptr [esi];2227add esi, 4;22282229// arrr rrgg gggb bbbb2230// aaaaaaaa bbbbbbbb gggggggg rrrrrrrr2231mov edx, eax; // edx = arrrrrgg gggbbbbb arrrrrgg gggbbbbb2232and ebx, 0x00000000;2233and eax, 0x00008000; // eax = 00000000 00000000 a0000000 000000002234jz transparent1;2235or ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 0000000022362237transparent1:2238mov eax, edx; // eax = arrrrrgg gggbbbbb arrrrrgg gggbbbbb2239and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb2240shl edx, 14; // edx = 00000000 00000bbb bb000000 000000002241or ebx, edx; // ebx = aaaaaaaa 00000bbb bb000000 000000002242shl edx, 5; // edx = 00000000 bbbbb000 00000000 000000002243or ebx, edx; // ebx = aaaaaaaa bbbbbbbb bb000000 000000002244and ebx, 0xffff0000; // ebx = aaaaaaaa bbbbbbbb 00000000 000000002245mov edx, eax;2246and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg000002247shl edx, 1; // edx = 00000000 00000000 00000ggg gg0000002248or ebx, edx; // ebx = aaaaaaaa bbbbbbbb 00000ggg gg0000002249shl edx, 5; // edx = 00000000 00000000 ggggg000 000000002250or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg gg0000002251and ebx, 0xffffff00; // ebx = aaaaaaaa bbbbbbbb gggggggg 000000002252mov edx, eax;2253and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 000000002254shr edx, 7; // edx = 00000000 00000000 00000000 rrrrr0002255or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrr0002256shr edx, 5; // edx = 00000000 00000000 00000000 00000rrr2257or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrrrrr22582259mov dword ptr [edi], ebx;2260add edi, 4;22612262shr eax, 16; // eax = 00000000 00000000 arrrrrgg gggbbbbb2263mov edx, eax; // edx = 00000000 00000000 arrrrrgg gggbbbbb2264and ebx, 0x00000000;2265and eax, 0x00008000; // eax = 00000000 00000000 a0000000 000000002266jz transparent2;2267or ebx, 0xff000000; // ebx = aaaaaaaa 00000000 00000000 0000000022682269transparent2:2270mov eax, edx; // eax = arrrrrgg gggbbbbb arrrrrgg gggbbbbb2271and edx, 0x0000001f; // edx = 00000000 00000000 00000000 000bbbbb2272shl edx, 14; // edx = 00000000 00000bbb bb000000 000000002273or ebx, edx; // ebx = aaaaaaaa 00000bbb bb000000 000000002274shl edx, 5; // edx = 00000000 bbbbb000 00000000 000000002275or ebx, edx; // ebx = aaaaaaaa bbbbbbbb bb000000 000000002276and ebx, 0xffff0000; // ebx = aaaaaaaa bbbbbbbb 00000000 000000002277mov edx, eax;2278and edx, 0x000003e0; // edx = 00000000 00000000 000000gg ggg000002279shl edx, 1; // edx = 00000000 00000000 00000ggg gg0000002280or ebx, edx; // ebx = aaaaaaaa bbbbbbbb 00000ggg gg0000002281shl edx, 5; // edx = 00000000 00000000 ggggg000 000000002282or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg gg0000002283and ebx, 0xffffff00; // ebx = aaaaaaaa bbbbbbbb gggggggg 000000002284mov edx, eax;2285and edx, 0x00007c00; // edx = 00000000 00000000 0rrrrr00 000000002286shr edx, 7; // edx = 00000000 00000000 00000000 rrrrr0002287or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrr0002288shr edx, 5; // edx = 00000000 00000000 00000000 00000rrr2289or ebx, edx; // ebx = aaaaaaaa bbbbbbbb gggggggg rrrrrrrr22902291mov dword ptr [edi], ebx;2292add edi, 4;22932294dec ecx;2295jnz tc1_loop;22962297pop edi;2298pop esi;2299pop ebx;2300}2301}23022303void2304TxQuantize::ARGB4444_ABGR8888(uint32* src, uint32* dest, int width, int height)2305{2306int siz = (width * height) >> 1;23072308__asm {2309push ebx;2310push esi;2311push edi;23122313mov esi, dword ptr [src];2314mov edi, dword ptr [dest];2315mov ecx, dword ptr [siz];23162317tc1_loop:2318mov eax, dword ptr [esi];2319add esi, 4;23202321// aaaa rrrr gggg bbbb2322// aaaaaaaa bbbbbbbb gggggggg rrrrrrrr2323mov edx, eax;2324and eax, 0x0000ffff;2325mov ebx, eax; // 00000000 00000000 aaaarrrr ggggbbbb2326and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 000000002327shl ebx, 12; // 0000aaaa 00000000 00000000 000000002328or eax, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb2329mov ebx, eax;2330and ebx, 0x0000000f; // 00000000 00000000 00000000 0000bbbb2331shl ebx, 16; // 00000000 0000bbbb 00000000 000000002332or eax, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggbbbb2333mov ebx, eax;2334and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 000000002335shr ebx, 8; // 00000000 00000000 00000000 0000rrrr2336and eax, 0xfffffff0;2337or eax, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggrrrr2338mov ebx, eax;2339and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg00002340shl ebx, 4; // 00000000 00000000 0000gggg 000000002341and eax, 0x0f0f000f; // 0000aaaa 0000bbbb 00000000 0000rrrr2342or eax, ebx; // 0000aaaa 0000bbbb 0000gggg 0000rrrr2343mov ebx, eax;2344shl ebx, 4; // aaaa0000 bbbb0000 gggg0000 rrrr00002345or eax, ebx; // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr23462347mov dword ptr [edi], eax;23482349add edi, 4;23502351shr edx, 16;2352mov ebx, edx; // 00000000 00000000 aaaarrrr ggggbbbb2353and ebx, 0x0000f000; // 00000000 00000000 aaaa0000 000000002354shl ebx, 12; // 0000aaaa 00000000 00000000 000000002355or edx, ebx; // 0000aaaa 00000000 aaaarrrr ggggbbbb2356mov ebx, edx;2357and ebx, 0x0000000f; // 00000000 00000000 00000000 0000bbbb2358shl ebx, 16; // 00000000 0000bbbb 00000000 000000002359or edx, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggbbbb2360mov ebx, edx;2361and ebx, 0x00000f00; // 00000000 00000000 0000rrrr 000000002362shr ebx, 8; // 00000000 00000000 00000000 0000rrrr2363and edx, 0xfffffff0;2364or edx, ebx; // 0000aaaa 0000bbbb aaaarrrr ggggrrrr2365mov ebx, edx;2366and ebx, 0x000000f0; // 00000000 00000000 00000000 gggg00002367shl ebx, 4; // 00000000 00000000 0000gggg 000000002368and edx, 0x0f0f000f; // 0000aaaa 0000bbbb 00000000 0000rrrr2369or edx, ebx; // 0000aaaa 0000bbbb 0000gggg 0000rrrr2370mov ebx, edx;2371shl ebx, 4; // aaaa0000 bbbb0000 gggg0000 rrrr00002372or edx, ebx; // aaaaaaaa bbbbbbbb gggggggg rrrrrrrr23732374mov dword ptr [edi], edx;2375add edi, 4;23762377dec ecx;2378jnz tc1_loop;23792380pop edi;2381pop esi;2382pop ebx;2383}2384}23852386void2387TxQuantize::ARGB8888_ABGR8888(uint32* src, uint32* dest, int width, int height)2388{2389int siz = width * height;23902391__asm {2392push ebx;2393push esi;2394push edi;23952396mov esi, dword ptr [src];2397mov edi, dword ptr [dest];2398mov ecx, dword ptr [siz];23992400tc1_loop:2401mov eax, dword ptr [esi];2402add esi, 4;24032404// aaaaaaaa bbbbbbbb gggggggg rrrrrrrr2405mov edx, eax;2406bswap edx;2407shr edx, 8;2408and eax, 0xff000000;24092410or eax, edx;24112412mov dword ptr [edi], eax;2413add edi, 4;24142415dec ecx;2416jnz tc1_loop;24172418pop edi;2419pop esi;2420pop ebx;2421}2422}2423#endif242424252426