123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- /*
- ================================================================================================
- Contains the DxtDecoder implementation.
- ================================================================================================
- */
- #pragma hdrstop
- #include "DXTCodec_local.h"
- #include "DXTCodec.h"
- /*
- ========================
- idDxtDecoder::EmitBlock
- ========================
- */
- void idDxtDecoder::EmitBlock( byte *outPtr, int x, int y, const byte *colorBlock ) {
- outPtr += ( y * width + x ) * 4;
- for ( int j = 0; j < 4; j++ ) {
- memcpy( outPtr, &colorBlock[j*4*4], 4*4 );
- outPtr += width * 4;
- }
- }
- /*
- ========================
- idDxtDecoder::DecodeAlphaValues
- ========================
- */
- void idDxtDecoder::DecodeAlphaValues( byte *colorBlock, const int offset ) {
- int i;
- unsigned int indexes;
- byte alphas[8];
- alphas[0] = ReadByte();
- alphas[1] = ReadByte();
- if ( alphas[0] > alphas[1] ) {
- alphas[2] = ( 6 * alphas[0] + 1 * alphas[1] ) / 7;
- alphas[3] = ( 5 * alphas[0] + 2 * alphas[1] ) / 7;
- alphas[4] = ( 4 * alphas[0] + 3 * alphas[1] ) / 7;
- alphas[5] = ( 3 * alphas[0] + 4 * alphas[1] ) / 7;
- alphas[6] = ( 2 * alphas[0] + 5 * alphas[1] ) / 7;
- alphas[7] = ( 1 * alphas[0] + 6 * alphas[1] ) / 7;
- } else {
- alphas[2] = ( 4 * alphas[0] + 1 * alphas[1] ) / 5;
- alphas[3] = ( 3 * alphas[0] + 2 * alphas[1] ) / 5;
- alphas[4] = ( 2 * alphas[0] + 3 * alphas[1] ) / 5;
- alphas[5] = ( 1 * alphas[0] + 4 * alphas[1] ) / 5;
- alphas[6] = 0;
- alphas[7] = 255;
- }
- colorBlock += offset;
- indexes = (int)ReadByte() | ( (int)ReadByte() << 8 ) | ( (int)ReadByte() << 16 );
- for ( i = 0; i < 8; i++ ) {
- colorBlock[i*4] = alphas[indexes & 7];
- indexes >>= 3;
- }
- indexes = (int)ReadByte() | ( (int)ReadByte() << 8 ) | ( (int)ReadByte() << 16 );
- for ( i = 8; i < 16; i++ ) {
- colorBlock[i*4] = alphas[indexes & 7];
- indexes >>= 3;
- }
- }
- /*
- ========================
- idDxtDecoder::DecodeColorValues
- ========================
- */
- void idDxtDecoder::DecodeColorValues( byte *colorBlock, bool noBlack, bool writeAlpha ) {
- byte colors[4][4];
- unsigned short color0 = ReadUShort();
- unsigned short color1 = ReadUShort();
- ColorFrom565( color0, colors[0] );
- ColorFrom565( color1, colors[1] );
- colors[0][3] = 255;
- colors[1][3] = 255;
- if ( noBlack || color0 > color1 ) {
- colors[2][0] = ( 2 * colors[0][0] + 1 * colors[1][0] ) / 3;
- colors[2][1] = ( 2 * colors[0][1] + 1 * colors[1][1] ) / 3;
- colors[2][2] = ( 2 * colors[0][2] + 1 * colors[1][2] ) / 3;
- colors[2][3] = 255;
- colors[3][0] = ( 1 * colors[0][0] + 2 * colors[1][0] ) / 3;
- colors[3][1] = ( 1 * colors[0][1] + 2 * colors[1][1] ) / 3;
- colors[3][2] = ( 1 * colors[0][2] + 2 * colors[1][2] ) / 3;
- colors[3][3] = 255;
- } else {
- colors[2][0] = ( 1 * colors[0][0] + 1 * colors[1][0] ) / 2;
- colors[2][1] = ( 1 * colors[0][1] + 1 * colors[1][1] ) / 2;
- colors[2][2] = ( 1 * colors[0][2] + 1 * colors[1][2] ) / 2;
- colors[2][3] = 255;
- colors[3][0] = 0;
- colors[3][1] = 0;
- colors[3][2] = 0;
- colors[3][3] = 0;
- }
- unsigned int indexes = ReadUInt();
- for ( int i = 0; i < 16; i++ ) {
- colorBlock[i*4+0] = colors[indexes & 3][0];
- colorBlock[i*4+1] = colors[indexes & 3][1];
- colorBlock[i*4+2] = colors[indexes & 3][2];
- if ( writeAlpha ) {
- colorBlock[i*4+3] = colors[indexes & 3][3];
- }
- indexes >>= 2;
- }
- }
- /*
- ========================
- idDxtDecoder::DecodeCTX1Values
- ========================
- */
- void idDxtDecoder::DecodeCTX1Values( byte *colorBlock ) {
- byte colors[4][2];
- colors[0][0] = ReadByte();
- colors[0][1] = ReadByte();
- colors[1][0] = ReadByte();
- colors[1][1] = ReadByte();
- colors[2][0] = ( 2 * colors[0][0] + 1 * colors[1][0] ) / 3;
- colors[2][1] = ( 2 * colors[0][1] + 1 * colors[1][1] ) / 3;
- colors[3][0] = ( 1 * colors[0][0] + 2 * colors[1][0] ) / 3;
- colors[3][1] = ( 1 * colors[0][1] + 2 * colors[1][1] ) / 3;
- unsigned int indexes = ReadUInt();
- for ( int i = 0; i < 16; i++ ) {
- colorBlock[i*4+0] = colors[indexes & 3][0];
- colorBlock[i*4+1] = colors[indexes & 3][1];
- indexes >>= 2;
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressImageDXT1
- ========================
- */
- void idDxtDecoder::DecompressImageDXT1( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeColorValues( block, false, true );
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressImageDXT5
- ========================
- */
- void idDxtDecoder::DecompressImageDXT5( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeAlphaValues( block, 3 );
- DecodeColorValues( block, true, false );
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressImageDXT5_nVidia7x
- ========================
- */
- void idDxtDecoder::DecompressImageDXT5_nVidia7x( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeAlphaValues( block, 3 );
- DecodeColorValues( block, false, false );
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressYCoCgDXT5
- ========================
- */
- void idDxtDecoder::DecompressYCoCgDXT5( const byte *inBuf, byte *outBuf, int width, int height ) {
- DecompressImageDXT5_nVidia7x( inBuf, outBuf, width, height );
- // descale the CoCg values and set the scale factor effectively to 1
- for ( int i = 0; i < width * height; i++ ) {
- int scale = ( outBuf[i*4+2] >> 3 ) + 1;
- outBuf[i*4+0] = byte( ( outBuf[i*4+0] - 128 ) / scale + 128 );
- outBuf[i*4+1] = byte( ( outBuf[i*4+1] - 128 ) / scale + 128 );
- outBuf[i*4+2] = 0; // this translates to a scale factor of 1 for uncompressed
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressYCoCgCTX1DXT5A
- ========================
- */
- void idDxtDecoder::DecompressYCoCgCTX1DXT5A( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeAlphaValues( block, 3 );
- DecodeCTX1Values( block );
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecodeNormalYValues
- ========================
- */
- void idDxtDecoder::DecodeNormalYValues( byte *normalBlock, const int offsetY, byte &c0, byte &c1 ) {
- int i;
- unsigned int indexes;
- unsigned short normal0, normal1;
- byte normalsY[4];
- normal0 = ReadUShort();
- normal1 = ReadUShort();
- assert( normal0 >= normal1 );
- normalsY[0] = NormalYFrom565( normal0 );
- normalsY[1] = NormalYFrom565( normal1 );
- normalsY[2] = ( 2 * normalsY[0] + 1 * normalsY[1] ) / 3;
- normalsY[3] = ( 1 * normalsY[0] + 2 * normalsY[1] ) / 3;
- c0 = NormalBiasFrom565( normal0 );
- c1 = NormalScaleFrom565( normal0 );
- byte *normalYPtr = normalBlock + offsetY;
- indexes = ReadUInt();
- for ( i = 0; i < 16; i++ ) {
- normalYPtr[i*4] = normalsY[indexes & 3];
- indexes >>= 2;
- }
- }
- /*
- ========================
- UShortSqrt
- ========================
- */
- byte UShortSqrt( unsigned short s ) {
- #if 1
- int t, b, r, x;
- r = 0;
- for ( b = 0x10000000; b != 0; b >>= 2 ) {
- t = r + b;
- r >>= 1;
- x = -( t <= s );
- s = s - (unsigned short)( t & x );
- r += b & x;
- }
- return byte( r );
- #else
- int t, b, r;
- r = 0;
- for ( b = 0x10000000; b != 0; b >>= 2 ) {
- t = r + b;
- r >>= 1;
- if ( t <= s ) {
- s -= t;
- r += b;
- }
- }
- return r;
- #endif
- }
- /*
- ========================
- idDxtDecoder::DeriveNormalZValues
- ========================
- */
- void idDxtDecoder::DeriveNormalZValues( byte *normalBlock ) {
- int i;
- for ( i = 0; i < 16; i++ ) {
- int x = normalBlock[i*4+0] - 127;
- int y = normalBlock[i*4+1] - 127;
- normalBlock[i*4+2] = 128 + UShortSqrt( (unsigned short)( 16383 - x * x - y * y ) );
- }
- }
- /*
- ========================
- idDxtDecoder::UnRotateNormals
- ========================
- */
- void UnRotateNormals( const byte *block, float *normals, byte c0, byte c1 ) {
- int rotation = c0;
- float angle = -( rotation / 255.0f ) * idMath::PI;
- float s = sin( angle );
- float c = cos( angle );
- int scale = ( c1 >> 3 ) + 1;
- for ( int i = 0; i < 16; i++ ) {
- float x = block[i*4+0] / 255.0f * 2.0f - 1.0f;
- float y = ( ( block[i*4+1] - 128 ) / scale + 128 ) / 255.0f * 2.0f - 1.0f;
- float rx = c * x - s * y;
- float ry = s * x + c * y;
- normals[i*4+0] = rx;
- normals[i*4+1] = ry;
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressNormalMapDXT1
- ========================
- */
- void idDxtDecoder::DecompressNormalMapDXT1( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeColorValues( block, false, true );
- #if 1
- float normals[16*4];
- /*
- for ( int k = 0; k < 16; k++ ) {
- normals[k*4+0] = block[k*4+0] / 255.0f * 2.0f - 1.0f;
- normals[k*4+1] = block[k*4+1] / 255.0f * 2.0f - 1.0f;
- }
- */
- UnRotateNormals( block, normals, block[0*4+2], 0 );
- for ( int k = 0; k < 16; k++ ) {
- float x = normals[k*4+0];
- float y = normals[k*4+1];
- float z = 1.0f - x * x - y * y;
- if ( z < 0.0f ) z = 0.0f;
- normals[k*4+2] = sqrt( z );
- }
- for ( int k = 0; k < 16; k++ ) {
- block[k*4+0] = idMath::Ftob( ( normals[k*4+0] + 1.0f ) / 2.0f * 255.0f );
- block[k*4+1] = idMath::Ftob( ( normals[k*4+1] + 1.0f ) / 2.0f * 255.0f );
- block[k*4+2] = idMath::Ftob( ( normals[k*4+2] + 1.0f ) / 2.0f * 255.0f );
- }
- #else
- DeriveNormalZValues( block );
- #endif
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressNormalMapDXT1Renormalize
- ========================
- */
- void idDxtDecoder::DecompressNormalMapDXT1Renormalize( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeColorValues( block, false, true );
- for ( int k = 0; k < 16; k++ ) {
- float normal[3];
- normal[0] = block[k*4+0] / 255.0f * 2.0f - 1.0f;
- normal[1] = block[k*4+1] / 255.0f * 2.0f - 1.0f;
- normal[2] = block[k*4+2] / 255.0f * 2.0f - 1.0f;
- float rsq = idMath::InvSqrt( normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2] );
- normal[0] *= rsq;
- normal[1] *= rsq;
- normal[2] *= rsq;
- block[k*4+0] = idMath::Ftob( ( normal[0] + 1.0f ) / 2.0f * 255.0f + 0.5f );
- block[k*4+1] = idMath::Ftob( ( normal[1] + 1.0f ) / 2.0f * 255.0f + 0.5f );
- block[k*4+2] = idMath::Ftob( ( normal[2] + 1.0f ) / 2.0f * 255.0f + 0.5f );
- }
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressNormalMapDXT5Renormalize
- ========================
- */
- void idDxtDecoder::DecompressNormalMapDXT5Renormalize( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeAlphaValues( block, 3 );
- DecodeColorValues( block, false, false );
- for ( int k = 0; k < 16; k++ ) {
- float normal[3];
- #if 0 // object-space
- normal[0] = block[k*4+0] / 255.0f * 2.0f - 1.0f;
- normal[1] = block[k*4+1] / 255.0f * 2.0f - 1.0f;
- normal[2] = block[k*4+3] / 255.0f * 2.0f - 1.0f;
- #else
- normal[0] = block[k*4+3] / 255.0f * 2.0f - 1.0f;
- normal[1] = block[k*4+1] / 255.0f * 2.0f - 1.0f;
- normal[2] = block[k*4+2] / 255.0f * 2.0f - 1.0f;
- #endif
- float rsq = idMath::InvSqrt( normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2] );
- normal[0] *= rsq;
- normal[1] *= rsq;
- normal[2] *= rsq;
- block[k*4+0] = idMath::Ftob( ( normal[0] + 1.0f ) / 2.0f * 255.0f + 0.5f );
- block[k*4+1] = idMath::Ftob( ( normal[1] + 1.0f ) / 2.0f * 255.0f + 0.5f );
- block[k*4+2] = idMath::Ftob( ( normal[2] + 1.0f ) / 2.0f * 255.0f + 0.5f );
- }
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::BiasScaleNormalY
- ========================
- */
- void BiasScaleNormalY( byte *normals, const int offsetY, const byte c0, const byte c1 ) {
- int bias = c0 - 4;
- int scale = ( c1 >> 3 ) + 1;
- for ( int i = 0; i < 16; i++ ) {
- normals[i*4+offsetY] = byte( ( normals[i*4+offsetY] - 128 ) / scale + bias );
- }
- }
- /*
- ========================
- idDxtDecoder::BiasScaleNormals
- ========================
- */
- void BiasScaleNormals( const byte *block, float *normals, const byte c0, const byte c1 ) {
- int bias = c0 - 4;
- int scale = ( c1 >> 3 ) + 1;
- for ( int i = 0; i < 16; i++ ) {
- normals[i*4+0] = block[i*4+0] / 255.0f * 2.0f - 1.0f;
- normals[i*4+1] = ( ( block[i*4+1] - 128.0f ) / scale + bias ) / 255.0f * 2.0f - 1.0f;
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressNormalMapDXT5
- ========================
- */
- void idDxtDecoder::DecompressNormalMapDXT5( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- byte c0, c1;
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeAlphaValues( block, 0 );
- DecodeNormalYValues( block, 1, c0, c1 );
- #if 1
- float normals[16*4];
- //BiasScaleNormals( block, normals, c0, c1 );
- UnRotateNormals( block, normals, c0, c1 );
- for ( int k = 0; k < 16; k++ ) {
- float x = normals[k*4+0];
- float y = normals[k*4+1];
- float z = 1.0f - x * x - y * y;
- if ( z < 0.0f ) z = 0.0f;
- normals[k*4+2] = sqrt( z );
- }
- for ( int k = 0; k < 16; k++ ) {
- block[k*4+0] = idMath::Ftob( ( normals[k*4+0] + 1.0f ) / 2.0f * 255.0f );
- block[k*4+1] = idMath::Ftob( ( normals[k*4+1] + 1.0f ) / 2.0f * 255.0f );
- block[k*4+2] = idMath::Ftob( ( normals[k*4+2] + 1.0f ) / 2.0f * 255.0f );
- }
- #else
- BiasScaleNormalY( block, 1, c0, c1 );
- DeriveNormalZValues( block );
- #endif
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecompressNormalMapDXN2
- ========================
- */
- void idDxtDecoder::DecompressNormalMapDXN2( const byte *inBuf, byte *outBuf, int width, int height ) {
- byte block[64];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecodeAlphaValues( block, 0 );
- DecodeAlphaValues( block, 1 );
- #if 1
- float normals[16*4];
- for ( int k = 0; k < 16; k++ ) {
- normals[k*4+0] = block[k*4+0] / 255.0f * 2.0f - 1.0f;
- normals[k*4+1] = block[k*4+1] / 255.0f * 2.0f - 1.0f;
- }
- for ( int k = 0; k < 16; k++ ) {
- float x = normals[k*4+0];
- float y = normals[k*4+1];
- float z = 1.0f - x * x - y * y;
- if ( z < 0.0f ) z = 0.0f;
- normals[k*4+2] = sqrt( z );
- }
- for ( int k = 0; k < 16; k++ ) {
- block[k*4+0] = idMath::Ftob( ( normals[k*4+0] + 1.0f ) / 2.0f * 255.0f );
- block[k*4+1] = idMath::Ftob( ( normals[k*4+1] + 1.0f ) / 2.0f * 255.0f );
- block[k*4+2] = idMath::Ftob( ( normals[k*4+2] + 1.0f ) / 2.0f * 255.0f );
- }
- #else
- DeriveNormalZValues( block );
- #endif
- EmitBlock( outBuf, i, j, block );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecomposeColorBlock
- ========================
- */
- void idDxtDecoder::DecomposeColorBlock( byte colors[2][4], byte colorIndices[16], bool noBlack ) {
- int i;
- unsigned int indices;
- unsigned short color0, color1;
- int colorRemap1[] = { 3, 0, 2, 1 };
- int colorRemap2[] = { 1, 3, 2, 0 };
- int *crm;
- color0 = ReadUShort();
- color1 = ReadUShort();
- ColorFrom565( color0, colors[0] );
- ColorFrom565( color1, colors[1] );
- if ( noBlack || color0 > color1 ) {
- crm = colorRemap1;
- } else {
- crm = colorRemap2;
- }
- indices = ReadUInt();
- for ( i = 0; i < 16; i++ ) {
- colorIndices[i] = (byte)crm[ indices & 3 ];
- indices >>= 2;
- }
- }
- /*
- ========================
- idDxtDecoder::DecomposeAlphaBlock
- ========================
- */
- void idDxtDecoder::DecomposeAlphaBlock( byte colors[2][4], byte alphaIndices[16] ) {
- int i;
- unsigned char alpha0, alpha1;
- unsigned int indices;
- int alphaRemap1[] = { 7, 0, 6, 5, 4, 3, 2, 1 };
- int alphaRemap2[] = { 1, 6, 2, 3, 4, 5, 0, 7 };
- int *arm;
- alpha0 = ReadByte();
- alpha1 = ReadByte();
- colors[0][3] = alpha0;
- colors[1][3] = alpha1;
- if ( alpha0 > alpha1 ) {
- arm = alphaRemap1;
- } else {
- arm = alphaRemap2;
- }
- indices = (int)ReadByte() | ( (int)ReadByte() << 8 ) | ( (int)ReadByte() << 16 );
- for ( i = 0; i < 8; i++ ) {
- alphaIndices[i] = (byte)arm[ indices & 7 ];
- indices >>= 3;
- }
- indices = (int)ReadByte() | ( (int)ReadByte() << 8 ) | ( (int)ReadByte() << 16 );
- for ( i = 8; i < 16; i++ ) {
- alphaIndices[i] = (byte)arm[ indices & 7 ];
- indices >>= 3;
- }
- }
- /*
- ========================
- idDxtDecoder::DecomposeImageDXT1
- ========================
- */
- void idDxtDecoder::DecomposeImageDXT1( const byte *inBuf, byte *colorIndices, byte *pic1, byte *pic2, int width, int height ) {
- byte colors[2][4];
- byte indices[16];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- // extract the colors from the DXT
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecomposeColorBlock( colors, indices, false );
- memcpy( colorIndices + (j+0) * width + i, indices+ 0, 4 );
- memcpy( colorIndices + (j+1) * width + i, indices+ 4, 4 );
- memcpy( colorIndices + (j+2) * width + i, indices+ 8, 4 );
- memcpy( colorIndices + (j+3) * width + i, indices+12, 4 );
- memcpy( pic1 + j * width / 4 + i, colors[0], 4 );
- memcpy( pic2 + j * width / 4 + i, colors[1], 4 );
- }
- }
- }
- /*
- ========================
- idDxtDecoder::DecomposeImageDXT5
- ========================
- */
- void idDxtDecoder::DecomposeImageDXT5( const byte *inBuf, byte *colorIndices, byte *alphaIndices, byte *pic1, byte *pic2, int width, int height ) {
- byte colors[2][4];
- byte colorInd[16];
- byte alphaInd[16];
- this->width = width;
- this->height = height;
- this->inData = inBuf;
- // extract the colors from the DXT
- for ( int j = 0; j < height; j += 4 ) {
- for ( int i = 0; i < width; i += 4 ) {
- DecomposeAlphaBlock( colors, alphaInd );
- DecomposeColorBlock( colors, colorInd, true );
- memcpy( colorIndices + (j+0) * width + i, colorInd+ 0, 4 );
- memcpy( colorIndices + (j+1) * width + i, colorInd+ 4, 4 );
- memcpy( colorIndices + (j+2) * width + i, colorInd+ 8, 4 );
- memcpy( colorIndices + (j+3) * width + i, colorInd+12, 4 );
- memcpy( colorIndices + (j+0) * width + i, alphaInd+ 0, 4 );
- memcpy( colorIndices + (j+1) * width + i, alphaInd+ 4, 4 );
- memcpy( colorIndices + (j+2) * width + i, alphaInd+ 8, 4 );
- memcpy( colorIndices + (j+3) * width + i, alphaInd+12, 4 );
- memcpy( pic1 + j * width / 4 + i, colors[0], 4 );
- memcpy( pic2 + j * width / 4 + i, colors[1], 4 );
- }
- }
- }
|