1
0
forked from 0ad/0ad

Fix S3TC decoder bug.

Add S3TC decoder test.
Fix texture codec test to not be a no-op, then disable it since it
fails.
Add DDS mipmap removal transform.

This was SVN commit r8094.
This commit is contained in:
Ykkrosh 2010-09-10 20:25:23 +00:00
parent aadbf53a2a
commit dee3cb84b5
2 changed files with 51 additions and 4 deletions

View File

@ -62,8 +62,10 @@ class TestTex : public CxxTest::TestSuite
public:
// this also covers BGR and orientation transforms.
void test_encode_decode()
void DISABLED_test_encode_decode() // disabled because it's completely broken
{
tex_codec_register_all();
// for each codec
const TexCodecVTbl* c = 0;
for(;;)
@ -94,6 +96,8 @@ public:
flags |= (TEX_DXT&3); // DXT3
if(bpp == 8)
flags |= TEX_GREY;
else if(bpp == 16)
continue; // not supported
else if(bpp == 32)
flags |= TEX_ALPHA;
@ -120,6 +124,8 @@ public:
} // for bpp
} // for width/height
} // foreach codec
tex_codec_unregister_all();
}
// have mipmaps be created for a test image; check resulting size and pixels
@ -151,4 +157,36 @@ public:
TS_ASSERT_OK(tex_wrap(97, 97, 4, DXT1A, img, 0, &t2));
TS_ASSERT_EQUALS((int)tex_img_size(&t2), 5000);
}
void test_s3tc_decode()
{
tex_codec_register_all();
const size_t w = 4, h = 4, bpp = 4;
const size_t size = w*h/2;
shared_ptr<u8> img(new u8[size], ArrayDeleter());
memcpy(img.get(), "\xFF\xFF\x00\x00\x00\xAA\xFF\x55", 8); // gradient from white to black
const u8 expected[] =
"\xFF\xFF\xFF" "\xFF\xFF\xFF" "\xFF\xFF\xFF" "\xFF\xFF\xFF"
"\xAA\xAA\xAA" "\xAA\xAA\xAA" "\xAA\xAA\xAA" "\xAA\xAA\xAA"
"\x55\x55\x55" "\x55\x55\x55" "\x55\x55\x55" "\x55\x55\x55"
"\x00\x00\x00" "\x00\x00\x00" "\x00\x00\x00" "\x00\x00\x00";
const size_t flags = TEX_DXT&1;
// wrap in Tex
Tex t;
TS_ASSERT_OK(tex_wrap(w, h, bpp, flags, img, 0, &t));
// decompress S3TC
TS_ASSERT_OK(tex_transform_to(&t, 0));
// compare img
TS_ASSERT_SAME_DATA(tex_get_data(&t), expected, 48);
// cleanup
tex_free(&t);
tex_codec_unregister_all();
}
};

View File

@ -127,7 +127,7 @@ private:
{
const size_t num_filler_bits = 8-num_bits;
const size_t field = (size_t)bits(c, bits_below, bits_below+num_bits-1);
const size_t filler = field >> (8-num_bits);
const size_t filler = field >> (num_bits-num_filler_bits);
return (field << num_filler_bits) | filler;
}
@ -609,10 +609,20 @@ static LibError dds_encode(Tex* RESTRICT UNUSED(t), DynArray* RESTRICT UNUSED(da
static LibError dds_transform(Tex* t, size_t transforms)
{
size_t mipmaps = t->flags & TEX_MIPMAPS;
size_t dxt = t->flags & TEX_DXT;
debug_assert(is_valid_dxt(dxt));
const size_t transform_mipmaps = transforms & TEX_MIPMAPS;
const size_t transform_dxt = transforms & TEX_DXT;
// requesting removal of mipmaps
if(mipmaps && transform_mipmaps)
{
// we don't need to actually change anything except the flag - the
// mipmap levels will just be treated as trailing junk
t->flags &= ~TEX_MIPMAPS;
return INFO::OK;
}
// requesting decompression
if(dxt && transform_dxt)
{
@ -622,8 +632,7 @@ static LibError dds_transform(Tex* t, size_t transforms)
// both are DXT (unsupported; there are no flags we can change while
// compressed) or requesting compression (not implemented) or
// both not DXT (nothing we can do) - bail.
else
return INFO::TEX_CODEC_CANNOT_HANDLE;
return INFO::TEX_CODEC_CANNOT_HANDLE;
}