Evas DDS: Implement support for DXT4 and DXT5

This commit is contained in:
Jean-Philippe Andre 2014-06-19 18:01:46 +09:00
parent d9d0ff2088
commit 79ed3c4516
3 changed files with 57 additions and 3 deletions

View File

@ -254,7 +254,6 @@ evas_image_load_file_head_dds(void *loader_data,
prop->alpha = EINA_TRUE;
prop->cspaces = cspaces_s3tc_dxt5;
break;
#if 0
case FOURCC('D', 'X', 'T', '4'):
loader->format = EVAS_COLORSPACE_RGBA_S3TC_DXT4;
prop->alpha = EINA_TRUE;
@ -266,10 +265,8 @@ evas_image_load_file_head_dds(void *loader_data,
prop->cspaces = cspaces_s3tc_dxt5;
break;
case FOURCC('D', 'X', '1', '0'):
loader->format = DX10;
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
FAIL();
#endif
default:
// TODO: Implement decoding support for uncompressed formats
FAIL();
@ -363,6 +360,14 @@ evas_image_load_file_data_dds(void *loader_data,
func = s3tc_decode_dxt3_rgba;
prop->premul = EINA_TRUE;
break;
case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
func = s3tc_decode_dxt4_rgba;
prop->premul = EINA_FALSE;
break;
case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
func = s3tc_decode_dxt5_rgba;
prop->premul = EINA_TRUE;
break;
default:
FAIL();
}

View File

@ -5,5 +5,7 @@ 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_dxt2_rgba(unsigned int *bgra, const unsigned char *s3tc);
void s3tc_decode_dxt3_rgba(unsigned int *bgra, const unsigned char *s3tc);
void s3tc_decode_dxt4_rgba(unsigned int *bgra, const unsigned char *s3tc);
void s3tc_decode_dxt5_rgba(unsigned int *bgra, const unsigned char *s3tc);
#endif // EFL_S3TC_H

View File

@ -60,6 +60,41 @@ _decode_alpha4(unsigned int *bgra, const unsigned char *s3tc)
}
}
static void
_decode_dxt_alpha(unsigned int *bgra, const unsigned char *s3tc)
{
unsigned char a0 = s3tc[0];
unsigned char a1 = s3tc[1];
unsigned long long bits = 0ull;
unsigned char alpha[8];
for (int k = 5; k >= 0; k--)
bits = (bits << 8) | s3tc[k + 2];
alpha[0] = a0;
alpha[1] = a1;
if (a0 > a1)
{
for (int k = 0; k < 6; k++)
alpha[2 + k] = ((6 - k) * a0 + (k + 1) * a1) / 7;
}
else
{
for (int k = 0; k < 4; k++)
alpha[2 + k] = ((4 - k) * a0 + (k + 1) * a1) / 5;
alpha[6] = 0;
alpha[7] = 255;
}
for (int k = 0; k < 16; k++)
{
int index = (int) (bits & 0x7ull);
*bgra++ |= (alpha[index] << 24);
bits >>= 3;
}
}
void s3tc_decode_dxt1_rgb(unsigned int *bgra, const unsigned char *s3tc)
{
_decode_dxt1_rgb(bgra, s3tc, 0xFF000000, EINA_TRUE, EINA_FALSE);
@ -81,3 +116,15 @@ 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);
}
void s3tc_decode_dxt4_rgba(unsigned int *bgra, const unsigned char *s3tc)
{
_decode_dxt1_rgb(bgra, s3tc + 8, 0x0, EINA_FALSE, EINA_FALSE);
_decode_dxt_alpha(bgra, s3tc);
}
void s3tc_decode_dxt5_rgba(unsigned int *bgra, const unsigned char *s3tc)
{
_decode_dxt1_rgb(bgra, s3tc + 8, 0x0, EINA_FALSE, EINA_FALSE);
_decode_dxt_alpha(bgra, s3tc);
}