Refactor software DDS decoder
* Use C++ memory API (new/delete) instead of malloc/free * Remove unneeded variables * Format using clang-format * Use PackRGBA instead of hardcoding color valuepull/932/head
parent
2f7662fd3b
commit
b8dd1d2282
|
@ -10,6 +10,7 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <celutil/debug.h>
|
||||
#include <celutil/bytes.h>
|
||||
#include <celengine/image.h>
|
||||
|
@ -71,7 +72,10 @@ struct DDSurfaceDesc
|
|||
};
|
||||
|
||||
|
||||
static uint32_t FourCC(const char* s)
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr uint32_t FourCC(const char* s)
|
||||
{
|
||||
return (((uint32_t) s[3] << 24) |
|
||||
((uint32_t) s[2] << 16) |
|
||||
|
@ -79,20 +83,13 @@ static uint32_t FourCC(const char* s)
|
|||
(uint32_t) s[0]);
|
||||
}
|
||||
|
||||
|
||||
#define DDPF_RGB 0x40
|
||||
#define DDPF_FOURCC 0x04
|
||||
|
||||
|
||||
// decompress a DXTc texture, taken from https://github.com/ptitSeb/gl4es
|
||||
GLvoid *decompressDXTc(GLsizei width, GLsizei height, GLenum format, int transparent0, int* simpleAlpha, int* complexAlpha, ifstream &in) {
|
||||
// decompress a DXTc image
|
||||
// get pixel size of decompressed image => fixed RGBA
|
||||
int pixelsize = 4;
|
||||
// decompress a DXTc texture to a RGBA texture, taken from https://github.com/ptitSeb/gl4es
|
||||
uint32_t* decompressDXTc(uint32_t width, uint32_t height, GLenum format, bool transparent0, ifstream &in)
|
||||
{
|
||||
// TODO: check with the size of the input data stream if the stream is in fact decompressed
|
||||
// alloc memory
|
||||
GLvoid *pixels = malloc(((width + 3) & ~3) * ((height + 3) & ~3) * pixelsize);
|
||||
// decompress loop
|
||||
auto *pixels = new uint32_t[((width + 3) & ~3) * ((height + 3) & ~3)];
|
||||
|
||||
int blocksize = 0;
|
||||
#define DDS_MAX_BLOCK_SIZE 16
|
||||
switch (format)
|
||||
|
@ -105,27 +102,27 @@ GLvoid *decompressDXTc(GLsizei width, GLsizei height, GLenum format, int transpa
|
|||
blocksize = 16;
|
||||
break;
|
||||
}
|
||||
char block[DDS_MAX_BLOCK_SIZE]; // enough to hold DXT1/3/5 blocks
|
||||
uint8_t block[DDS_MAX_BLOCK_SIZE]; // enough to hold DXT1/3/5 blocks
|
||||
for (int y = 0; y < height; y += 4)
|
||||
{
|
||||
for (int x = 0; x < width; x += 4)
|
||||
{
|
||||
if (!in.good())
|
||||
{
|
||||
free(pixels);
|
||||
delete[] pixels;
|
||||
return nullptr;
|
||||
}
|
||||
in.read(block, blocksize);
|
||||
in.read((char*)block, blocksize);
|
||||
switch(format)
|
||||
{
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
DecompressBlockDXT1(x, y, width, (uint8_t*)block, transparent0, simpleAlpha, complexAlpha, (uint32_t *)pixels);
|
||||
DecompressBlockDXT1(x, y, width, block, transparent0, pixels);
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
DecompressBlockDXT3(x, y, width, (uint8_t*)block, transparent0, simpleAlpha, complexAlpha, (uint32_t *)pixels);
|
||||
DecompressBlockDXT3(x, y, width, block, transparent0, pixels);
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
DecompressBlockDXT5(x, y, width, (uint8_t*)block, transparent0, simpleAlpha, complexAlpha, (uint32_t *)pixels);
|
||||
DecompressBlockDXT5(x, y, width, block, transparent0, pixels);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +130,8 @@ GLvoid *decompressDXTc(GLsizei width, GLsizei height, GLenum format, int transpa
|
|||
return pixels;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
Image* LoadDDSImage(const fs::path& filename)
|
||||
{
|
||||
ifstream in(filename.string(), ios::in | ios::binary);
|
||||
|
@ -240,30 +239,25 @@ Image* LoadDDSImage(const fs::path& filename)
|
|||
if (!gl::EXT_texture_compression_s3tc)
|
||||
{
|
||||
// DXTc texture not supported, decompress DXTc to RGBA
|
||||
GLvoid *pixels = NULL;
|
||||
int simpleAlpha = 0;
|
||||
int complexAlpha = 0;
|
||||
int transparent0 = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 1 : 0;
|
||||
if ((ddsd.width & 3) || (ddsd.height & 3))
|
||||
uint32_t *pixels = nullptr;
|
||||
bool transparent0 = format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
if ((ddsd.width & 3 != 0) || (ddsd.height & 3 != 0))
|
||||
{
|
||||
GLvoid *tmp;
|
||||
GLsizei nw = ddsd.width;
|
||||
GLsizei nh = ddsd.height;
|
||||
if (nw < 4) nw = 4;
|
||||
if (nh < 4) nh = 4;
|
||||
tmp = decompressDXTc(nw, nh, format, transparent0, &simpleAlpha, &complexAlpha, in);
|
||||
uint32_t nw = max(ddsd.width, 4u);
|
||||
uint32_t nh = max(ddsd.height, 4u);
|
||||
auto *tmp = decompressDXTc(nw, nh, format, transparent0, in);
|
||||
if (tmp != nullptr)
|
||||
{
|
||||
pixels = malloc(4 * ddsd.width * ddsd.height);
|
||||
pixels = new uint32_t[ddsd.width * ddsd.height];
|
||||
// crop
|
||||
for (int y=0; y<ddsd.height; y++)
|
||||
for (uint32_t y = 0; y < ddsd.height; y++)
|
||||
memcpy((char *)pixels + y * ddsd.width * 4, (char *)tmp + y * nw * 4, ddsd.width * 4);
|
||||
free(tmp);
|
||||
delete[] tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixels = decompressDXTc(ddsd.width, ddsd.height, format, transparent0, &simpleAlpha, &complexAlpha, in);
|
||||
pixels = decompressDXTc(ddsd.width, ddsd.height, format, transparent0, in);
|
||||
}
|
||||
|
||||
if (pixels == nullptr)
|
||||
|
@ -274,7 +268,7 @@ Image* LoadDDSImage(const fs::path& filename)
|
|||
|
||||
Image *img = new Image(GL_RGBA, ddsd.width, ddsd.height);
|
||||
memcpy(img->getPixels(), pixels, 4 * ddsd.width * ddsd.height);
|
||||
free(pixels);
|
||||
delete[] pixels;
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
DXT1/DXT3/DXT5 texture decompression
|
||||
|
@ -55,16 +55,16 @@ SOFTWARE.
|
|||
|
||||
---
|
||||
*/
|
||||
static uint32_t PackRGBA (uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
constexpr uint32_t PackRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
return r | (g << 8) | (b << 16) | (a << 24);
|
||||
}
|
||||
|
||||
static void DecompressBlockDXT1Internal (const uint8_t* block,
|
||||
uint32_t* output,
|
||||
uint32_t outputStride,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
const uint8_t* alphaValues)
|
||||
static void DecompressBlockDXT1Internal(const uint8_t* block,
|
||||
uint32_t* output,
|
||||
uint32_t outputStride,
|
||||
bool transparent0,
|
||||
const uint8_t* alphaValues)
|
||||
{
|
||||
uint32_t temp, code;
|
||||
|
||||
|
@ -77,33 +77,37 @@ static void DecompressBlockDXT1Internal (const uint8_t* block,
|
|||
color1 = *(const uint16_t*)(block + 2);
|
||||
|
||||
temp = (color0 >> 11) * 255 + 16;
|
||||
r0 = (uint8_t)((temp/32 + temp)/32);
|
||||
r0 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
|
||||
g0 = (uint8_t)((temp/64 + temp)/64);
|
||||
g0 = (uint8_t)((temp / 64 + temp) / 64);
|
||||
temp = (color0 & 0x001F) * 255 + 16;
|
||||
b0 = (uint8_t)((temp/32 + temp)/32);
|
||||
b0 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
|
||||
temp = (color1 >> 11) * 255 + 16;
|
||||
r1 = (uint8_t)((temp/32 + temp)/32);
|
||||
r1 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
|
||||
g1 = (uint8_t)((temp/64 + temp)/64);
|
||||
g1 = (uint8_t)((temp / 64 + temp) / 64);
|
||||
temp = (color1 & 0x001F) * 255 + 16;
|
||||
b1 = (uint8_t)((temp/32 + temp)/32);
|
||||
b1 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
|
||||
code = *(const uint32_t*)(block + 4);
|
||||
|
||||
if (color0 > color1) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (color0 > color1)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
uint32_t finalColor, positionCode;
|
||||
uint8_t alpha;
|
||||
|
||||
alpha = alphaValues [j*4+i];
|
||||
alpha = alphaValues[j * 4 + i];
|
||||
|
||||
finalColor = 0;
|
||||
positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
positionCode = (code >> 2 * (4 * j + i)) & 0x03;
|
||||
|
||||
switch (positionCode) {
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, alpha);
|
||||
break;
|
||||
|
@ -111,35 +115,39 @@ static void DecompressBlockDXT1Internal (const uint8_t* block,
|
|||
finalColor = PackRGBA(r1, g1, b1, alpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, alpha);
|
||||
finalColor = PackRGBA((2 * r0 + r1) / 3, (2 * g0 + g1) / 3,
|
||||
(2 * b0 + b1) / 3, alpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, alpha);
|
||||
finalColor = PackRGBA((r0 + 2 * r1) / 3, (g0 + 2 * g1) / 3,
|
||||
(b0 + 2 * b1) / 3, alpha);
|
||||
break;
|
||||
}
|
||||
if(transparent0 && (finalColor==0xff000000)) {
|
||||
alpha=0;
|
||||
if (transparent0 && (finalColor == PackRGBA(0, 0, 0, 0xff)))
|
||||
{
|
||||
alpha = 0;
|
||||
finalColor = 0;
|
||||
}
|
||||
if(!alpha)
|
||||
*simpleAlpha = 1;
|
||||
else if(alpha<0xff)
|
||||
*complexAlpha = 1;
|
||||
output [j*outputStride + i] = finalColor;
|
||||
output[j * outputStride + i] = finalColor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
for (i = 0; i < 4; ++i) {
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
uint32_t finalColor, positionCode;
|
||||
uint8_t alpha;
|
||||
|
||||
alpha = alphaValues [j*4+i];
|
||||
alpha = alphaValues[j * 4 + i];
|
||||
|
||||
finalColor = 0;
|
||||
positionCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
positionCode = (code >> 2 * (4 * j + i)) & 0x03;
|
||||
|
||||
switch (positionCode) {
|
||||
switch (positionCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, alpha);
|
||||
break;
|
||||
|
@ -147,23 +155,20 @@ static void DecompressBlockDXT1Internal (const uint8_t* block,
|
|||
finalColor = PackRGBA(r1, g1, b1, alpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, alpha);
|
||||
finalColor = PackRGBA((r0 + r1) / 2, (g0 + g1) / 2, (b0 + b1) / 2, alpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA(0, 0, 0, alpha);
|
||||
break;
|
||||
}
|
||||
|
||||
if(transparent0 && (finalColor==0xff000000)) {
|
||||
if (transparent0 && (finalColor == PackRGBA(0, 0, 0, 0xff)))
|
||||
{
|
||||
alpha = 0;
|
||||
finalColor = 0;
|
||||
}
|
||||
if(!alpha)
|
||||
*simpleAlpha = 1;
|
||||
else if(alpha<0xff)
|
||||
*complexAlpha = 1;
|
||||
|
||||
output [j*outputStride + i] = finalColor;
|
||||
output[j * outputStride + i] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,41 +177,42 @@ static void DecompressBlockDXT1Internal (const uint8_t* block,
|
|||
/*
|
||||
void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t width: width of the texture being decompressed.
|
||||
const uint8_t *blockStorage: pointer to the block to decompress.
|
||||
uint32_t *image: pointer to image where the decompressed pixel data should be stored.
|
||||
*/
|
||||
void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image)
|
||||
void DecompressBlockDXT1(uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
bool transparent0,
|
||||
uint32_t* image)
|
||||
{
|
||||
static const uint8_t const_alpha [] = {
|
||||
255, 255, 255, 255,
|
||||
255, 255, 255, 255,
|
||||
255, 255, 255, 255,
|
||||
255, 255, 255, 255
|
||||
};
|
||||
static const uint8_t const_alpha[] = { 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255 };
|
||||
|
||||
DecompressBlockDXT1Internal (blockStorage,
|
||||
image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, const_alpha);
|
||||
DecompressBlockDXT1Internal(blockStorage, image + x + (y * width), width,
|
||||
transparent0, const_alpha);
|
||||
}
|
||||
|
||||
/*
|
||||
void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t width: width of the texture being decompressed.
|
||||
const uint8_t *blockStorage: pointer to the block to decompress.
|
||||
uint32_t *image: pointer to image where the decompressed pixel data should be stored.
|
||||
*/
|
||||
void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image)
|
||||
void DecompressBlockDXT5(uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
bool transparent0,
|
||||
uint32_t* image)
|
||||
{
|
||||
uint8_t alpha0, alpha1;
|
||||
const uint8_t* bits;
|
||||
|
@ -231,59 +237,80 @@ void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
|||
color1 = *(const uint16_t*)(blockStorage + 10);
|
||||
|
||||
temp = (color0 >> 11) * 255 + 16;
|
||||
r0 = (uint8_t)((temp/32 + temp)/32);
|
||||
r0 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
|
||||
g0 = (uint8_t)((temp/64 + temp)/64);
|
||||
g0 = (uint8_t)((temp / 64 + temp) / 64);
|
||||
temp = (color0 & 0x001F) * 255 + 16;
|
||||
b0 = (uint8_t)((temp/32 + temp)/32);
|
||||
b0 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
|
||||
temp = (color1 >> 11) * 255 + 16;
|
||||
r1 = (uint8_t)((temp/32 + temp)/32);
|
||||
r1 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
|
||||
g1 = (uint8_t)((temp/64 + temp)/64);
|
||||
g1 = (uint8_t)((temp / 64 + temp) / 64);
|
||||
temp = (color1 & 0x001F) * 255 + 16;
|
||||
b1 = (uint8_t)((temp/32 + temp)/32);
|
||||
b1 = (uint8_t)((temp / 32 + temp) / 32);
|
||||
|
||||
code = *(const uint32_t*)(blockStorage + 12);
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
uint8_t finalAlpha;
|
||||
int alphaCode, alphaCodeIndex;
|
||||
uint8_t colorCode;
|
||||
uint32_t finalColor;
|
||||
|
||||
alphaCodeIndex = 3*(4*j+i);
|
||||
if (alphaCodeIndex <= 12) {
|
||||
alphaCodeIndex = 3 * (4 * j + i);
|
||||
if (alphaCodeIndex <= 12)
|
||||
{
|
||||
alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
|
||||
} else if (alphaCodeIndex == 15) {
|
||||
}
|
||||
else if (alphaCodeIndex == 15)
|
||||
{
|
||||
alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06);
|
||||
} else /* alphaCodeIndex >= 18 && alphaCodeIndex <= 45 */ {
|
||||
}
|
||||
else /* alphaCodeIndex >= 18 && alphaCodeIndex <= 45 */
|
||||
{
|
||||
alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07;
|
||||
}
|
||||
|
||||
if (alphaCode == 0) {
|
||||
if (alphaCode == 0)
|
||||
{
|
||||
finalAlpha = alpha0;
|
||||
} else if (alphaCode == 1) {
|
||||
}
|
||||
else if (alphaCode == 1)
|
||||
{
|
||||
finalAlpha = alpha1;
|
||||
} else {
|
||||
if (alpha0 > alpha1) {
|
||||
finalAlpha = (uint8_t)(((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7);
|
||||
} else {
|
||||
if (alphaCode == 6) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha0 > alpha1)
|
||||
{
|
||||
finalAlpha = (uint8_t)(((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alphaCode == 6)
|
||||
{
|
||||
finalAlpha = 0;
|
||||
} else if (alphaCode == 7) {
|
||||
}
|
||||
else if (alphaCode == 7)
|
||||
{
|
||||
finalAlpha = 255;
|
||||
} else {
|
||||
finalAlpha = (uint8_t)(((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5);
|
||||
}
|
||||
else
|
||||
{
|
||||
finalAlpha = (uint8_t)(((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
colorCode = (code >> 2*(4*j+i)) & 0x03;
|
||||
colorCode = (code >> 2 * (4 * j + i)) & 0x03;
|
||||
finalColor = 0;
|
||||
|
||||
switch (colorCode) {
|
||||
switch (colorCode)
|
||||
{
|
||||
case 0:
|
||||
finalColor = PackRGBA(r0, g0, b0, finalAlpha);
|
||||
break;
|
||||
|
@ -291,17 +318,16 @@ void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
|||
finalColor = PackRGBA(r1, g1, b1, finalAlpha);
|
||||
break;
|
||||
case 2:
|
||||
finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha);
|
||||
finalColor = PackRGBA((2 * r0 + r1) / 3, (2 * g0 + g1) / 3,
|
||||
(2 * b0 + b1) / 3, finalAlpha);
|
||||
break;
|
||||
case 3:
|
||||
finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha);
|
||||
finalColor = PackRGBA((r0 + 2 * r1) / 3, (g0 + 2 * g1) / 3,
|
||||
(b0 + 2 * b1) / 3, finalAlpha);
|
||||
break;
|
||||
}
|
||||
|
||||
if(finalAlpha==0) *simpleAlpha = 1;
|
||||
else if(finalAlpha<0xff) *complexAlpha = 1;
|
||||
|
||||
image [i + x + (width* (y+j))] = finalColor;
|
||||
image[i + x + (width * (y + j))] = finalColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,32 +335,35 @@ void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
|||
/*
|
||||
void DecompressBlockDXT3(): Decompresses one block of a DXT3 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t x: x-coordinate of the first pixel in the block.
|
||||
uint32_t y: y-coordinate of the first pixel in the block.
|
||||
uint32_t height: height of the texture being decompressed.
|
||||
const uint8_t *blockStorage: pointer to the block to decompress.
|
||||
uint32_t *image: pointer to image where the decompressed pixel data should be stored.
|
||||
*/
|
||||
void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
uint32_t* image)
|
||||
void DecompressBlockDXT3(uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
bool transparent0,
|
||||
uint32_t* image)
|
||||
{
|
||||
int i;
|
||||
|
||||
uint8_t alphaValues [16] = { 0 };
|
||||
uint8_t alphaValues[16] = { 0 };
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
const uint16_t* alphaData = (const uint16_t*) (blockStorage);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
const uint16_t* alphaData = (const uint16_t*)(blockStorage);
|
||||
|
||||
alphaValues [i*4 + 0] = (((*alphaData) >> 0) & 0xF ) * 17;
|
||||
alphaValues [i*4 + 1] = (((*alphaData) >> 4) & 0xF ) * 17;
|
||||
alphaValues [i*4 + 2] = (((*alphaData) >> 8) & 0xF ) * 17;
|
||||
alphaValues [i*4 + 3] = (((*alphaData) >> 12) & 0xF) * 17;
|
||||
alphaValues[i * 4 + 0] = (((*alphaData) >> 0) & 0xF) * 17;
|
||||
alphaValues[i * 4 + 1] = (((*alphaData) >> 4) & 0xF) * 17;
|
||||
alphaValues[i * 4 + 2] = (((*alphaData) >> 8) & 0xF) * 17;
|
||||
alphaValues[i * 4 + 3] = (((*alphaData) >> 12) & 0xF) * 17;
|
||||
|
||||
blockStorage += 2;
|
||||
}
|
||||
|
||||
DecompressBlockDXT1Internal (blockStorage,
|
||||
image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, alphaValues);
|
||||
DecompressBlockDXT1Internal(blockStorage, image + x + (y * width), width,
|
||||
transparent0, alphaValues);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
bool transparent0,
|
||||
uint32_t* image);
|
||||
|
||||
void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
bool transparent0,
|
||||
uint32_t* image);
|
||||
|
||||
void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width,
|
||||
const uint8_t* blockStorage,
|
||||
int transparent0, int* simpleAlpha, int *complexAlpha,
|
||||
bool transparent0,
|
||||
uint32_t* image);
|
||||
|
|
Loading…
Reference in New Issue