forked from enlightenment/efl
Evas DDS: Implement decoding of DXT2 and DXT3
This commit is contained in:
parent
18e969f644
commit
d9d0ff2088
|
@ -34,8 +34,6 @@ struct _Evas_Loader_Internal
|
||||||
unsigned int g_mask;
|
unsigned int g_mask;
|
||||||
unsigned int b_mask;
|
unsigned int b_mask;
|
||||||
unsigned int a_mask;
|
unsigned int a_mask;
|
||||||
|
|
||||||
Eina_Bool has_alpha : 1;
|
|
||||||
// TODO: check mipmaps to load faster a small image :)
|
// TODO: check mipmaps to load faster a small image :)
|
||||||
} pf; // pixel format
|
} pf; // pixel format
|
||||||
};
|
};
|
||||||
|
@ -159,7 +157,7 @@ _dword_read(const char **m)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FAIL() do { fprintf(stderr, "DDS: ERROR at %s:%d", \
|
#define FAIL() do { fprintf(stderr, "DDS: ERROR at %s:%d\n", \
|
||||||
__FUNCTION__, __LINE__); goto on_error; } while (0)
|
__FUNCTION__, __LINE__); goto on_error; } while (0)
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
|
@ -228,7 +226,6 @@ evas_image_load_file_head_dds(void *loader_data,
|
||||||
if (!(loader->pf.flags & DDPF_FOURCC))
|
if (!(loader->pf.flags & DDPF_FOURCC))
|
||||||
FAIL(); // Unsupported (uncompressed formats may not have a FOURCC)
|
FAIL(); // Unsupported (uncompressed formats may not have a FOURCC)
|
||||||
loader->pf.fourcc = _dword_read(&m);
|
loader->pf.fourcc = _dword_read(&m);
|
||||||
loader->pf.has_alpha = EINA_TRUE;
|
|
||||||
loader->block_size = 16;
|
loader->block_size = 16;
|
||||||
switch (loader->pf.fourcc)
|
switch (loader->pf.fourcc)
|
||||||
{
|
{
|
||||||
|
@ -238,7 +235,6 @@ evas_image_load_file_head_dds(void *loader_data,
|
||||||
{
|
{
|
||||||
prop->alpha = EINA_FALSE;
|
prop->alpha = EINA_FALSE;
|
||||||
prop->cspaces = cspaces_s3tc_dxt1_rgb;
|
prop->cspaces = cspaces_s3tc_dxt1_rgb;
|
||||||
loader->pf.has_alpha = EINA_FALSE;
|
|
||||||
loader->format = EVAS_COLORSPACE_RGB_S3TC_DXT1;
|
loader->format = EVAS_COLORSPACE_RGB_S3TC_DXT1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -248,7 +244,6 @@ evas_image_load_file_head_dds(void *loader_data,
|
||||||
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT1;
|
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
case FOURCC('D', 'X', 'T', '2'):
|
case FOURCC('D', 'X', 'T', '2'):
|
||||||
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT2;
|
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT2;
|
||||||
prop->alpha = EINA_TRUE;
|
prop->alpha = EINA_TRUE;
|
||||||
|
@ -259,6 +254,7 @@ evas_image_load_file_head_dds(void *loader_data,
|
||||||
prop->alpha = EINA_TRUE;
|
prop->alpha = EINA_TRUE;
|
||||||
prop->cspaces = cspaces_s3tc_dxt5;
|
prop->cspaces = cspaces_s3tc_dxt5;
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
case FOURCC('D', 'X', 'T', '4'):
|
case FOURCC('D', 'X', 'T', '4'):
|
||||||
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT4;
|
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT4;
|
||||||
prop->alpha = EINA_TRUE;
|
prop->alpha = EINA_TRUE;
|
||||||
|
@ -353,9 +349,19 @@ evas_image_load_file_data_dds(void *loader_data,
|
||||||
{
|
{
|
||||||
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
|
case EVAS_COLORSPACE_RGB_S3TC_DXT1:
|
||||||
func = s3tc_decode_dxt1_rgb;
|
func = s3tc_decode_dxt1_rgb;
|
||||||
|
prop->premul = EINA_FALSE;
|
||||||
break;
|
break;
|
||||||
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
|
||||||
func = s3tc_decode_dxt1_rgba;
|
func = s3tc_decode_dxt1_rgba;
|
||||||
|
prop->premul = EINA_FALSE;
|
||||||
|
break;
|
||||||
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
|
||||||
|
func = s3tc_decode_dxt2_rgba;
|
||||||
|
prop->premul = EINA_FALSE;
|
||||||
|
break;
|
||||||
|
case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
|
||||||
|
func = s3tc_decode_dxt3_rgba;
|
||||||
|
prop->premul = EINA_TRUE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FAIL();
|
FAIL();
|
||||||
|
|
|
@ -3,5 +3,7 @@
|
||||||
|
|
||||||
void s3tc_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc);
|
void s3tc_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc);
|
||||||
void s3tc_decode_dxt1_rgba(unsigned int *bgra, const unsigned char *s3tc);
|
void s3tc_decode_dxt1_rgba(unsigned int *bgra, const unsigned char *s3tc);
|
||||||
|
void s3tc_decode_dxt2_rgba(unsigned int *bgra, const unsigned char *s3tc);
|
||||||
|
void s3tc_decode_dxt3_rgba(unsigned int *bgra, const unsigned char *s3tc);
|
||||||
|
|
||||||
#endif // EFL_S3TC_H
|
#endif // EFL_S3TC_H
|
||||||
|
|
|
@ -10,15 +10,11 @@
|
||||||
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
|
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
|
||||||
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
|
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
|
||||||
|
|
||||||
static inline unsigned int
|
#define ALPHA4(a) (((a) << 4) | (a))
|
||||||
_rgb565_to_rgba8888(unsigned short s)
|
|
||||||
{
|
|
||||||
return 0xFF000000 | CONVERT_RGB_565_TO_RGB_888(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc,
|
_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc,
|
||||||
Eina_Bool alpha)
|
unsigned int amask, Eina_Bool dxt1, Eina_Bool alpha)
|
||||||
{
|
{
|
||||||
unsigned short color0, color1;
|
unsigned short color0, color1;
|
||||||
unsigned int colors[4];
|
unsigned int colors[4];
|
||||||
|
@ -27,18 +23,18 @@ _decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc,
|
||||||
color0 = s3tc[0] | (s3tc[1] << 8);
|
color0 = s3tc[0] | (s3tc[1] << 8);
|
||||||
color1 = s3tc[2] | (s3tc[3] << 8);
|
color1 = s3tc[2] | (s3tc[3] << 8);
|
||||||
|
|
||||||
colors[0] = _rgb565_to_rgba8888(color0);
|
colors[0] = amask | CONVERT_RGB_565_TO_RGB_888(color0);
|
||||||
colors[1] = _rgb565_to_rgba8888(color1);
|
colors[1] = amask | CONVERT_RGB_565_TO_RGB_888(color1);
|
||||||
if (color0 > color1)
|
if (!dxt1 || (color0 > color1))
|
||||||
{
|
{
|
||||||
// This is what's not supported by S2TC.
|
// This is what's not supported by S2TC.
|
||||||
colors[2] = 0xFF000000 | INTERP_RGB_256((2*256)/3, colors[0], colors[1]);
|
colors[2] = amask | INTERP_RGB_256((2*256)/3, colors[0], colors[1]);
|
||||||
colors[3] = 0xFF000000 | INTERP_RGB_256((1*256)/3, colors[0], colors[1]);
|
colors[3] = amask | INTERP_RGB_256((1*256)/3, colors[0], colors[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
colors[2] = 0xFF000000 | INTERP_RGB_256(128, colors[0], colors[1]);
|
colors[2] = amask | INTERP_RGB_256(128, colors[0], colors[1]);
|
||||||
colors[3] = (alpha ? 0x00000000 : 0xFF000000);
|
colors[3] = (alpha ? 0x00000000 : amask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bits = s3tc[4] + ((s3tc[5] + ((s3tc[6] + (s3tc[7] << 8)) << 8)) << 8);
|
bits = s3tc[4] + ((s3tc[5] + ((s3tc[6] + (s3tc[7] << 8)) << 8)) << 8);
|
||||||
|
@ -46,18 +42,42 @@ _decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc,
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
int idx = bits & 0x3;
|
int idx = bits & 0x3;
|
||||||
bits >>= 2;
|
|
||||||
|
|
||||||
bgra[(j * 4) + i] = colors[idx];
|
bgra[(j * 4) + i] = colors[idx];
|
||||||
|
bits >>= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_decode_alpha4(unsigned int *bgra, const unsigned char *s3tc)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 16; k += 2)
|
||||||
|
{
|
||||||
|
unsigned int a0 = ALPHA4((*s3tc) & 0x0F);
|
||||||
|
unsigned int a1 = ALPHA4(((*s3tc) & 0xF0) >> 4);
|
||||||
|
*bgra++ |= (a0 << 24);
|
||||||
|
*bgra++ |= (a1 << 24);
|
||||||
|
s3tc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void s3tc_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc)
|
void s3tc_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc)
|
||||||
{
|
{
|
||||||
_decode_dxt1_rgb(bgra, s3tc, EINA_FALSE);
|
_decode_dxt1_rgb(bgra, s3tc, 0xFF000000, EINA_TRUE, EINA_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void s3tc_decode_dxt1_rgba(unsigned int *bgra, const unsigned char *s3tc)
|
void s3tc_decode_dxt1_rgba(unsigned int *bgra, const unsigned char *s3tc)
|
||||||
{
|
{
|
||||||
_decode_dxt1_rgb(bgra, s3tc, EINA_TRUE);
|
_decode_dxt1_rgb(bgra, s3tc, 0xFF000000, EINA_TRUE, EINA_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void s3tc_decode_dxt2_rgba(unsigned int *bgra, const unsigned char *s3tc)
|
||||||
|
{
|
||||||
|
_decode_dxt1_rgb(bgra, s3tc + 8, 0x0, EINA_FALSE, EINA_FALSE);
|
||||||
|
_decode_alpha4(bgra, s3tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void s3tc_decode_dxt3_rgba(unsigned int *bgra, const unsigned char *s3tc)
|
||||||
|
{
|
||||||
|
_decode_dxt1_rgb(bgra, s3tc + 8, 0x0, EINA_FALSE, EINA_FALSE);
|
||||||
|
_decode_alpha4(bgra, s3tc);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue