BC7 decoding WIP.

This commit is contained in:
Branimir Karadžić
2018-05-22 18:09:37 -07:00
parent bd3366bba0
commit 1220e7fe54

View File

@@ -976,6 +976,20 @@ namespace bimg
if (NULL == pack
|| NULL == unpack)
{
switch (_dstFormat)
{
case TextureFormat::RGBA8:
imageDecodeToRgba8(_dst, _src, _width, _height, _width*4, _srcFormat);
return true;
case TextureFormat::BGRA8:
imageDecodeToBgra8(_dst, _src, _width, _height, _width*4, _srcFormat);
return true;
default:
break;
}
return false;
}
@@ -1240,19 +1254,460 @@ namespace bimg
}
}
static const int32_t s_etc1Mod[8][4] =
{
{ 2, 8, -2, -8},
{ 5, 17, -5, -17},
{ 9, 29, -9, -29},
{ 13, 42, -13, -42},
{ 18, 60, -18, -60},
{ 24, 80, -24, -80},
{ 33, 106, -33, -106},
{ 47, 183, -47, -183},
// BC6H, BC7
//
// Reference:
//
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_texture_compression_bptc.txt
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh308952(v=vs.85).aspx
static const uint16_t s_bctcP2[] =
{ // 3210 0000000000 1111111111 2222222222 3333333333
0xcccc, // 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
0x8888, // 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1
0xeeee, // 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1
0xecc8, // 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1
0xc880, // 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1
0xfeec, // 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
0xfec8, // 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1
0xec80, // 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1
0xc800, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1
0xffec, // 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
0xfe80, // 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1
0xe800, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1
0xffe8, // 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
0xff00, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1
0xfff0, // 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
0xf000, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1
0xf710, // 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1
0x008e, // 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
0x7100, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0
0x08ce, // 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0
0x008c, // 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
0x7310, // 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0
0x3100, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0
0x8cce, // 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1
0x088c, // 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0
0x3110, // 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0
0x6666, // 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0
0x366c, // 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0
0x17e8, // 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0
0x0ff0, // 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0
0x718e, // 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0
0x399c, // 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0
0xaaaa, // 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
0xf0f0, // 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1
0x5a5a, // 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0
0x33cc, // 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0
0x3c3c, // 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0
0x55aa, // 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0
0x9696, // 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1
0xa55a, // 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1
0x73ce, // 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0
0x13c8, // 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0
0x324c, // 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0
0x3bdc, // 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0
0x6996, // 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
0xc33c, // 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1
0x9966, // 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1
0x0660, // 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0
0x0272, // 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0
0x04e4, // 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0
0x4e40, // 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0
0x2720, // 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0
0xc936, // 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1
0x936c, // 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1
0x39c6, // 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0
0x639c, // 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0
0x9336, // 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1
0x9cc6, // 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1
0x817e, // 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1
0xe718, // 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1
0xccf0, // 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
0x0fcc, // 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0
0x7744, // 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0
0xee22, // 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1
};
static const uint8_t s_etc2Mod[8] = { 3, 6, 11, 16, 23, 32, 41, 64 };
static const uint32_t s_bctcP3[] =
{ // 76543210 0000 1111 2222 3333 4444 5555 6666 7777
0xaa685050, // 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 1, 2, 2, 2, 2
0x6a5a5040, // 0, 0, 0, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1
0x5a5a4200, // 0, 0, 0, 0, 2, 0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1
0x5450a0a8, // 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 1, 1
0xa5a50000, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2
0xa0a05050, // 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2
0x5555a0a0, // 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
0x5a5a5050, // 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1
0xaa550000, // 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2
0xaa555500, // 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2
0xaaaa5500, // 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2
0x90909090, // 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2
0x94949494, // 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2
0xa4a4a4a4, // 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 2
0xa9a59450, // 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2
0x2a0a4250, // 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0, 2, 2, 2, 0
0xa5945040, // 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 2, 1, 1, 2, 2
0x0a425054, // 0, 1, 1, 1, 0, 0, 1, 1, 2, 0, 0, 1, 2, 2, 0, 0
0xa5a5a500, // 0, 0, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2
0x55a0a0a0, // 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 1, 1, 1
0xa8a85454, // 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 2
0x6a6a4040, // 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 2, 2, 1
0xa4a45000, // 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2
0x1a1a0500, // 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 1, 0, 2, 2, 1, 0
0x0050a4a4, // 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0
0xaaa59090, // 0, 0, 1, 2, 0, 0, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2
0x14696914, // 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1, 0, 1, 1, 0
0x69691400, // 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 2, 2, 1
0xa08585a0, // 0, 0, 2, 2, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 2, 2
0xaa821414, // 0, 1, 1, 0, 0, 1, 1, 0, 2, 0, 0, 2, 2, 2, 2, 2
0x50a4a450, // 0, 0, 1, 1, 0, 1, 2, 2, 0, 1, 2, 2, 0, 0, 1, 1
0x6a5a0200, // 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 1, 1, 2, 2, 2, 1
0xa9a58000, // 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 2, 2, 2
0x5090a0a8, // 0, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 2, 0, 0, 1, 1
0xa8a09050, // 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 2, 2, 2
0x24242424, // 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0
0x00aa5500, // 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0
0x24924924, // 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0
0x24499224, // 0, 1, 2, 0, 2, 0, 1, 2, 1, 2, 0, 1, 0, 1, 2, 0
0x50a50a50, // 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1
0x500aa550, // 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1
0xaaaa4444, // 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2
0x66660000, // 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1
0xa5a0a5a0, // 0, 0, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2, 1, 1, 2, 2
0x50a050a0, // 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1
0x69286928, // 0, 2, 2, 0, 1, 2, 2, 1, 0, 2, 2, 0, 1, 2, 2, 1
0x44aaaa44, // 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 1
0x66666600, // 0, 0, 0, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1
0xaa444444, // 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2
0x54a854a8, // 0, 2, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1
0x95809580, // 0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 2
0x96969600, // 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2
0xa85454a8, // 0, 2, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 0, 2, 2, 2
0x80959580, // 0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 0, 2
0xaa141414, // 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2
0x96960000, // 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2, 2, 1, 1, 2
0xaaaa1414, // 0, 1, 1, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2
0xa05050a0, // 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2
0xa0a5a5a0, // 0, 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0, 0, 2, 2
0x96000000, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 2
0x40804080, // 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1
0xa9a8a9a8, // 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2
0xaaaaaa44, // 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
0x2a4a5254, // 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0
};
static const uint8_t s_bctcA2[] =
{
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 2, 8, 2, 2, 8, 8, 15,
2, 8, 2, 2, 8, 8, 2, 2,
15, 15, 6, 8, 2, 8, 15, 15,
2, 8, 2, 2, 2, 15, 15, 6,
6, 2, 6, 8, 15, 15, 2, 2,
15, 15, 15, 15, 15, 2, 2, 15,
};
static const uint8_t s_bctcA3[2][64] =
{
{
3, 3, 15, 15, 8, 3, 15, 15,
8, 8, 6, 6, 6, 5, 3, 3,
3, 3, 8, 15, 3, 3, 6, 10,
5, 8, 8, 6, 8, 5, 15, 15,
8, 15, 3, 5, 6, 10, 8, 15,
15, 3, 15, 5, 15, 15, 15, 15,
3, 15, 5, 5, 5, 8, 5, 10,
5, 10, 8, 13, 15, 12, 3, 3,
},
{
15, 8, 8, 3, 15, 15, 3, 8,
15, 15, 15, 15, 15, 15, 15, 8,
15, 8, 15, 3, 15, 8, 15, 8,
3, 15, 6, 10, 15, 15, 10, 8,
15, 3, 15, 10, 10, 8, 9, 10,
6, 15, 8, 15, 3, 6, 6, 8,
15, 3, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 3, 15, 15, 8,
},
};
static const uint8_t s_bctcFactors[3][18] =
{
{ 0, 21, 43, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 9, 18, 27, 37, 46, 55, 64, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 },
};
struct BctcModeInfo
{
uint8_t numSubsets;
uint8_t partitionBits;
uint8_t rotationBits;
uint8_t indexSelectionBits;
uint8_t colorBits;
uint8_t alphaBits;
uint8_t endpointPBits;
uint8_t sharedPBits;
uint8_t indexBits[2];
};
static const BctcModeInfo s_bctcModeInfo[] =
{ // +---------------------------- num subsets
// | +------------------------- partition bits
// | | +---------------------- rotation bits
// | | | +------------------- index selection bits
// | | | | +---------------- color bits
// | | | | | +------------- alpha bits
// | | | | | | +---------- endpoint P-bits
// | | | | | | | +------- shared P-bits
// | | | | | | | | +-- 2x index bits
{ 3, 4, 0, 0, 4, 0, 1, 0, { 3, 0 } }, // 0
{ 2, 6, 0, 0, 6, 0, 0, 1, { 3, 0 } }, // 1
{ 3, 6, 0, 0, 5, 0, 0, 0, { 2, 0 } }, // 2
{ 2, 6, 0, 0, 7, 0, 1, 0, { 2, 0 } }, // 3
{ 1, 0, 2, 1, 5, 6, 0, 0, { 2, 3 } }, // 4
{ 1, 0, 2, 0, 7, 8, 0, 0, { 2, 2 } }, // 5
{ 1, 0, 0, 0, 7, 7, 1, 0, { 4, 0 } }, // 6
{ 2, 6, 0, 0, 5, 5, 1, 0, { 2, 0 } }, // 7
};
struct BitReader
{
BitReader(const uint8_t* _data, uint16_t _bitPos = 0)
: m_data(_data)
, m_bitPos(_bitPos)
{
}
uint8_t read(uint8_t _numBits)
{
const uint16_t pos = m_bitPos / 8;
const uint16_t shift = m_bitPos & 7;
const uint16_t data = *( (uint16_t*)&m_data[pos]);
m_bitPos += _numBits;
return uint8_t( (data >> shift) & ( (1 << _numBits)-1) );
}
uint8_t peek(uint16_t _offset, uint8_t _numBits)
{
const uint16_t bitPos = m_bitPos + _offset;
const uint16_t pos = bitPos / 8;
const uint16_t shift = bitPos & 7;
const uint16_t data = *( (uint16_t*)&m_data[pos]);
return uint8_t( (data >> shift) & ( (1 << _numBits)-1) );
}
const uint8_t* m_data;
uint16_t m_bitPos;
};
void decodeBlockBc6(float _dst[16*4], const uint8_t _src[16])
{
BX_UNUSED(_dst, _src);
}
void decodeBlockBc7(uint8_t _dst[16*4], const uint8_t _src[16])
{
BitReader bit(_src);
uint8_t mode = 0;
for (; mode < 8 && 0 == bit.read(1); ++mode)
{
}
if (mode == 8)
{
bx::memSet(_dst, 0, 16*4);
return;
}
const BctcModeInfo& mi = s_bctcModeInfo[mode];
const uint8_t modePBits = 0 != mi.endpointPBits
? mi.endpointPBits
: mi.sharedPBits
;
const uint8_t partitionSetIdx = bit.read(mi.partitionBits);
const uint8_t rotationMode = bit.read(mi.rotationBits);
const uint8_t indexSelectionMode = bit.read(mi.indexSelectionBits);
uint8_t epR[6];
uint8_t epG[6];
uint8_t epB[6];
uint8_t epA[6];
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
epR[ii*2+0] = bit.read(mi.colorBits) << modePBits;
epR[ii*2+1] = bit.read(mi.colorBits) << modePBits;
}
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
epG[ii*2+0] = bit.read(mi.colorBits) << modePBits;
epG[ii*2+1] = bit.read(mi.colorBits) << modePBits;
}
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
epB[ii*2+0] = bit.read(mi.colorBits) << modePBits;
epB[ii*2+1] = bit.read(mi.colorBits) << modePBits;
}
if (mi.alphaBits)
{
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
epA[ii*2+0] = bit.read(mi.alphaBits) << modePBits;
epA[ii*2+1] = bit.read(mi.alphaBits) << modePBits;
}
}
else
{
bx::memSet(epA, 0xff, 6);
}
if (0 != modePBits)
{
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
const uint8_t pda = bit.read(modePBits);
const uint8_t pdb = 0 != mi.sharedPBits ? bit.read(modePBits) : pda;
epR[ii*2+0] |= pda;
epR[ii*2+1] |= pdb;
epG[ii*2+0] |= pda;
epG[ii*2+1] |= pdb;
epB[ii*2+0] |= pda;
epB[ii*2+1] |= pdb;
epA[ii*2+0] |= pda;
epA[ii*2+1] |= pdb;
}
}
const uint8_t colorBits = mi.colorBits + modePBits;
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
epR[ii*2+0] = bitRangeConvert(epR[ii*2+0], colorBits, 8);
epR[ii*2+1] = bitRangeConvert(epR[ii*2+1], colorBits, 8);
epG[ii*2+0] = bitRangeConvert(epG[ii*2+0], colorBits, 8);
epG[ii*2+1] = bitRangeConvert(epG[ii*2+1], colorBits, 8);
epB[ii*2+0] = bitRangeConvert(epB[ii*2+0], colorBits, 8);
epB[ii*2+1] = bitRangeConvert(epB[ii*2+1], colorBits, 8);
}
if (mi.alphaBits)
{
const uint8_t alphaBits = mi.alphaBits + modePBits;
for (uint8_t ii = 0; ii < mi.numSubsets; ++ii)
{
epA[ii*2+0] = bitRangeConvert(epA[ii*2+0], alphaBits, 8);
epA[ii*2+1] = bitRangeConvert(epA[ii*2+1], alphaBits, 8);
}
}
const bool hasIndexBits1 = 0 != mi.indexBits[1];
const uint8_t* factors[] =
{
s_bctcFactors[mi.indexBits[0]-2],
hasIndexBits1 ? s_bctcFactors[mi.indexBits[1]-2] : s_bctcFactors[0],
};
uint16_t offset[2] =
{
0,
uint16_t(mi.numSubsets*(16*mi.indexBits[0]-1) ),
};
for (uint8_t yy = 0; yy < 4; ++yy)
{
for (uint8_t xx = 0; xx < 4; ++xx)
{
const uint8_t idx = yy*4+xx;
uint8_t subsetIndex = 0;
uint8_t indexAnchor = 0;
switch (mi.numSubsets)
{
case 2:
subsetIndex = (s_bctcP2[partitionSetIdx] >> idx) & 1;
indexAnchor = 0 != subsetIndex ? s_bctcA2[partitionSetIdx] : 0;
break;
case 3:
subsetIndex = (s_bctcP3[partitionSetIdx] >> (2*idx) ) & 3;
indexAnchor = 0 != subsetIndex ? s_bctcA3[subsetIndex-1][partitionSetIdx] : 0;
break;
default:
break;
}
const uint8_t anchor = idx == indexAnchor;
const uint8_t num[2] =
{
uint8_t(mi.indexBits[0] - anchor),
uint8_t(hasIndexBits1 ? mi.indexBits[1] - anchor : 0),
};
const uint8_t index[2] =
{
bit.peek(offset[0], num[0]),
hasIndexBits1 ? bit.peek(offset[1], num[1]) : index[0],
};
offset[0] += num[0];
offset[1] += num[1];
const uint8_t fc = factors[ indexSelectionMode][index[ indexSelectionMode] ];
const uint8_t fa = factors[!indexSelectionMode][index[!indexSelectionMode] ];
const uint8_t fca = 64 - fc;
const uint8_t fcb = fc;
const uint8_t faa = 64 - fa;
const uint8_t fab = fa;
subsetIndex *= 2;
uint8_t rr = uint8_t(uint16_t(epR[subsetIndex]*fca + epR[subsetIndex + 1]*fcb + 32) >> 6);
uint8_t gg = uint8_t(uint16_t(epG[subsetIndex]*fca + epG[subsetIndex + 1]*fcb + 32) >> 6);
uint8_t bb = uint8_t(uint16_t(epB[subsetIndex]*fca + epB[subsetIndex + 1]*fcb + 32) >> 6);
uint8_t aa = uint8_t(uint16_t(epA[subsetIndex]*faa + epA[subsetIndex + 1]*fab + 32) >> 6);
switch (rotationMode)
{
case 1: bx::xchg(aa, rr); break;
case 2: bx::xchg(aa, gg); break;
case 3: bx::xchg(aa, bb); break;
default: break;
};
uint8_t* bgra = &_dst[(yy*4+xx)*4];
bgra[0] = bb;
bgra[1] = gg;
bgra[2] = rr;
bgra[3] = aa;
}
}
}
static const int32_t s_etc1Mod[8][4] =
{
{ 2, 8, -2, -8 },
{ 5, 17, -5, -17 },
{ 9, 29, -9, -29 },
{ 13, 42, -13, -42 },
{ 18, 60, -18, -60 },
{ 24, 80, -24, -80 },
{ 33, 106, -33, -106 },
{ 47, 183, -47, -183 },
};
static const uint8_t s_etc2Mod[] = { 3, 6, 11, 16, 23, 32, 41, 64 };
uint8_t uint8_sat(int32_t _a)
{
@@ -3034,6 +3489,23 @@ namespace bimg
}
break;
case TextureFormat::BC7:
for (uint32_t yy = 0; yy < height; ++yy)
{
for (uint32_t xx = 0; xx < width; ++xx)
{
decodeBlockBc7(temp, src);
src += 16;
uint8_t* block = &dst[yy*_dstPitch*4 + xx*16];
bx::memCopy(&block[0*_dstPitch], &temp[ 0], 16);
bx::memCopy(&block[1*_dstPitch], &temp[16], 16);
bx::memCopy(&block[2*_dstPitch], &temp[32], 16);
bx::memCopy(&block[3*_dstPitch], &temp[48], 16);
}
}
break;
case TextureFormat::ETC1:
case TextureFormat::ETC2:
for (uint32_t yy = 0; yy < height; ++yy)