mirror of
https://github.com/yuzu-emu/FasTC
synced 2024-11-22 11:43:56 +00:00
Add DXT5 decompression, as mentioned in #21
This commit is contained in:
parent
5dd85e5896
commit
2f8ea3dc07
4 changed files with 67 additions and 3 deletions
|
@ -326,6 +326,8 @@ int main(int argc, char **argv) {
|
|||
strcat(basename, "-pvrtc-4bpp.png");
|
||||
} else if(format == FasTC::eCompressionFormat_DXT1) {
|
||||
strcat(basename, "-dxt1.png");
|
||||
} else if(format == FasTC::eCompressionFormat_DXT5) {
|
||||
strcat(basename, "-dxt5.png");
|
||||
} else if(format == FasTC::eCompressionFormat_ETC1) {
|
||||
strcat(basename, "-etc1.png");
|
||||
}
|
||||
|
|
|
@ -91,7 +91,9 @@ bool CompressedImage::DecompressImage(unsigned char *outBuf, unsigned int outBuf
|
|||
DecompressionJob dj (m_Format, byteData, outBuf, GetWidth(), GetHeight());
|
||||
if(m_Format == FasTC::eCompressionFormat_DXT1) {
|
||||
DXTC::DecompressDXT1(dj);
|
||||
} else if(m_Format == FasTC::eCompressionFormat_ETC1) {
|
||||
} else if(m_Format == FasTC::eCompressionFormat_DXT5) {
|
||||
DXTC::DecompressDXT5(dj);
|
||||
} else if (m_Format == FasTC::eCompressionFormat_ETC1) {
|
||||
ETCC::Decompress(dj);
|
||||
} else if(FasTC::COMPRESSION_FORMAT_PVRTC_BEGIN <= m_Format &&
|
||||
FasTC::COMPRESSION_FORMAT_PVRTC_END >= m_Format) {
|
||||
|
|
|
@ -25,4 +25,5 @@ namespace DXTC
|
|||
void CompressImageDXT5(const FasTC::CompressionJob &);
|
||||
|
||||
void DecompressDXT1(const FasTC::DecompressionJob &);
|
||||
void DecompressDXT5(const FasTC::DecompressionJob &);
|
||||
}
|
||||
|
|
|
@ -57,11 +57,39 @@ namespace {
|
|||
FasTC::Pixel *colors[4] = { &a, &b, &c, &d };
|
||||
|
||||
uint32 *outPixels = reinterpret_cast<uint32 *>(outBuf);
|
||||
for(uint32 i = 0; i < 16; i++) {
|
||||
outPixels[i] = colors[(mod >> (i*2)) & 3]->Pack();
|
||||
for (uint32 i = 0; i < 16; i++) {
|
||||
outPixels[i] &= 0xFF000000;
|
||||
outPixels[i] |= colors[(mod >> (i * 2)) & 3]->Pack() & 0x00FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void DecompressDXT5Block(const uint8 *block, uint32 *outBuf) {
|
||||
int alpha0 = block[0];
|
||||
int alpha1 = block[1];
|
||||
|
||||
int palette[8];
|
||||
palette[0] = alpha0;
|
||||
palette[1] = alpha1;
|
||||
|
||||
if (alpha0 > alpha1) {
|
||||
for (int i = 2; i < 8; ++i) {
|
||||
palette[i] = ((8 - i) * alpha0 + (i - 1) * alpha1) / 7;
|
||||
}
|
||||
} else {
|
||||
for (int i = 2; i < 6; ++i) {
|
||||
palette[i] = ((6 - i) * alpha0 + (i - 1) * alpha1) / 5;
|
||||
}
|
||||
palette[6] = 0;
|
||||
palette[7] = 255;
|
||||
}
|
||||
|
||||
uint64 mod = *reinterpret_cast<const uint64 *>(block) >> 16;
|
||||
uint32 *outPixels = reinterpret_cast<uint32 *>(outBuf);
|
||||
for (uint32 i = 0; i < 16; i++) {
|
||||
outPixels[i] &= 0x00FFFFFF;
|
||||
outPixels[i] |= palette[(mod >> (i * 3)) & 7] << 24;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace DXTC
|
||||
|
@ -95,4 +123,35 @@ namespace DXTC
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecompressDXT5(const FasTC::DecompressionJob &dcj)
|
||||
{
|
||||
assert(!(dcj.Height() & 3));
|
||||
assert(!(dcj.Width() & 3));
|
||||
|
||||
uint32 blockW = dcj.Width() >> 2;
|
||||
uint32 blockH = dcj.Height() >> 2;
|
||||
|
||||
const uint32 blockSz = GetBlockSize(FasTC::eCompressionFormat_DXT5);
|
||||
|
||||
uint32 *outPixels = reinterpret_cast<uint32 *>(dcj.OutBuf());
|
||||
|
||||
uint32 outBlock[16];
|
||||
memset(outBlock, 0xFF, sizeof(outBlock));
|
||||
|
||||
for (uint32 j = 0; j < blockH; j++) {
|
||||
for (uint32 i = 0; i < blockW; i++) {
|
||||
|
||||
uint32 offset = (j * blockW + i) * blockSz;
|
||||
DecompressDXT5Block(dcj.InBuf() + offset, outBlock);
|
||||
DecompressDXT1Block(dcj.InBuf() + offset + blockSz / 2, outBlock, false);
|
||||
|
||||
for (uint32 y = 0; y < 4; y++)
|
||||
for (uint32 x = 0; x < 4; x++) {
|
||||
offset = (j * 4 + y)*dcj.Width() + ((i * 4) + x);
|
||||
outPixels[offset] = outBlock[y * 4 + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue