diff --git a/source/lib/res/graphics/tests/test_tex.h b/source/lib/res/graphics/tests/test_tex.h index bb9ff945e4..069a95b44d 100644 --- a/source/lib/res/graphics/tests/test_tex.h +++ b/source/lib/res/graphics/tests/test_tex.h @@ -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 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(); + } }; diff --git a/source/lib/tex/tex_dds.cpp b/source/lib/tex/tex_dds.cpp index 67830c6093..2149693084 100644 --- a/source/lib/tex/tex_dds.cpp +++ b/source/lib/tex/tex_dds.cpp @@ -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; }