1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/* Copyright (C) 2010 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "lib/self_test.h"
#include "lib/tex/tex.h"
#include "lib/tex/tex_codec.h"
#include "lib/allocators/shared_ptr.h"
class TestTex : public CxxTest::TestSuite
{
void generate_encode_decode_compare(size_t w, size_t h, size_t flags, size_t bpp, const OsPath& extension)
{
// generate test data
const size_t size = w*h*bpp/8;
shared_ptr<u8> img(new u8[size], ArrayDeleter());
std::generate(img.get(), img.get()+size, rand);
// create the DynArray that will be wrapped in a Tex Object
DynArray da;
// Once the Tex created here goes out of scope, the DynArray should be freed
{
// wrap in Tex
Tex t;
TS_ASSERT_OK(t.wrap(w, h, bpp, flags, img, 0));
// encode to file format
TS_ASSERT_OK(t.encode(extension, &da));
memset(&t, 0, sizeof(t));
// decode from file format
shared_ptr<u8> ptr = DummySharedPtr(da.base);
TS_ASSERT_OK(t.decode(ptr, da.cur_size));
// make sure pixel format gets converted completely to plain
TS_ASSERT_OK(t.transform_to(0));
// compare img
TS_ASSERT_SAME_DATA(t.get_data(), img.get(), size);
}
// cleanup
TS_ASSERT_OK(da_free(&da));
}
public:
// have mipmaps be created for a test image; check resulting size and pixels
void test_mipmap_create()
{
static u8 imgData[] = { 0x10,0x20,0x30, 0x40,0x60,0x80, 0xA0,0xA4,0xA8, 0xC0,0xC1,0xC2 };
shared_ptr<u8> img = DummySharedPtr(imgData);
// assumes 2x2 box filter algorithm with rounding
static const u8 mipmap[] = { 0x6C,0x79,0x87 };
Tex t;
TS_ASSERT_OK(t.wrap(2, 2, 24, 0, img, 0));
TS_ASSERT_OK(t.transform_to(TEX_MIPMAPS));
const u8* const out_img = t.get_data();
TS_ASSERT_EQUALS((int)t.img_size(), 12+3);
TS_ASSERT_SAME_DATA(out_img, imgData, 12);
TS_ASSERT_SAME_DATA(out_img+12, mipmap, 3);
}
void test_img_size()
{
shared_ptr<u8> img(new u8[100*100*4], ArrayDeleter());
Tex t;
TS_ASSERT_OK(t.wrap(100, 100, 32, TEX_ALPHA, img, 0));
TS_ASSERT_EQUALS((int)t.img_size(), 40000);
// DXT rounds up to 4x4 blocks; DXT1a is 4bpp
Tex t2;
TS_ASSERT_OK(t2.wrap(97, 97, 4, DXT1A, img, 0));
TS_ASSERT_EQUALS((int)t2.img_size(), 5000);
}
void test_s3tc_decode()
{
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(t.wrap(w, h, bpp, flags, img, 0));
// decompress S3TC
TS_ASSERT_OK(t.transform_to(0));
// compare img
TS_ASSERT_SAME_DATA(t.get_data(), expected, 48);
}
};
|