|
|
@ -168,88 +168,6 @@ namespace { |
|
|
namespace BC6H { |
|
|
namespace BC6H { |
|
|
static constexpr int32_t MaxPartitions = 64; |
|
|
static constexpr int32_t MaxPartitions = 64; |
|
|
|
|
|
|
|
|
// @fmt:off
|
|
|
|
|
|
|
|
|
|
|
|
static constexpr uint8_t PartitionTable2[MaxPartitions][16] = { |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, |
|
|
|
|
|
{ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 }, |
|
|
|
|
|
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 }, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
static constexpr uint8_t AnchorTable2[MaxPartitions] = { |
|
|
|
|
|
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, |
|
|
|
|
|
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, |
|
|
|
|
|
0xf, 0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0xf, |
|
|
|
|
|
0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0x2, 0x2, |
|
|
|
|
|
0xf, 0xf, 0x6, 0x8, 0x2, 0x8, 0xf, 0xf, |
|
|
|
|
|
0x2, 0x8, 0x2, 0x2, 0x2, 0xf, 0xf, 0x6, |
|
|
|
|
|
0x6, 0x2, 0x6, 0x8, 0xf, 0xf, 0x2, 0x2, |
|
|
|
|
|
0xf, 0xf, 0xf, 0xf, 0xf, 0x2, 0x2, 0xf, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// @fmt:on
|
|
|
|
|
|
|
|
|
|
|
|
// 1.0f in half-precision floating point format
|
|
|
// 1.0f in half-precision floating point format
|
|
|
static constexpr uint16_t halfFloat1 = 0x3C00; |
|
|
static constexpr uint16_t halfFloat1 = 0x3C00; |
|
|
union Color { |
|
|
union Color { |
|
|
@ -793,15 +711,56 @@ namespace { |
|
|
uint64_t high64; |
|
|
uint64_t high64; |
|
|
|
|
|
|
|
|
void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch, size_t dstBpp, bool isSigned) const { |
|
|
void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch, size_t dstBpp, bool isSigned) const { |
|
|
uint8_t mode = 0; |
|
|
|
|
|
|
|
|
// @fmt:off
|
|
|
|
|
|
static const uint32_t p_table[MaxPartitions] = { |
|
|
|
|
|
0b01010000010100000101000001010000, 0b01000000010000000100000001000000, |
|
|
|
|
|
0b01010100010101000101010001010100, 0b01010100010100000101000001000000, |
|
|
|
|
|
0b01010000010000000100000000000000, 0b01010101010101000101010001010000, |
|
|
|
|
|
0b01010101010101000101000001000000, 0b01010100010100000100000000000000, |
|
|
|
|
|
0b01010000010000000000000000000000, 0b01010101010101010101010001010000, |
|
|
|
|
|
0b01010101010101000100000000000000, 0b01010100010000000000000000000000, |
|
|
|
|
|
0b01010101010101010101010001000000, 0b01010101010101010000000000000000, |
|
|
|
|
|
0b01010101010101010101010100000000, 0b01010101000000000000000000000000, |
|
|
|
|
|
0b01010101000101010000000100000000, 0b00000000000000000100000001010100, |
|
|
|
|
|
0b00010101000000010000000000000000, 0b00000000010000000101000001010100, |
|
|
|
|
|
0b00000000000000000100000001010000, 0b00010101000001010000000100000000, |
|
|
|
|
|
0b00000101000000010000000000000000, 0b01000000010100000101000001010100, |
|
|
|
|
|
0b00000000010000000100000001010000, 0b00000101000000010000000100000000, |
|
|
|
|
|
0b00010100000101000001010000010100, 0b00000101000101000001010001010000, |
|
|
|
|
|
0b00000001000101010101010001000000, 0b00000000010101010101010100000000, |
|
|
|
|
|
0b00010101000000010100000001010100, 0b00000101010000010100000101010000, |
|
|
|
|
|
0b01000100010001000100010001000100, 0b01010101000000000101010100000000, |
|
|
|
|
|
0b00010001010001000001000101000100, 0b00000101000001010101000001010000, |
|
|
|
|
|
0b00000101010100000000010101010000, 0b00010001000100010100010001000100, |
|
|
|
|
|
0b01000001000101000100000100010100, 0b01000100000100010001000101000100, |
|
|
|
|
|
0b00010101000001010101000001010100, 0b00000001000001010101000001000000, |
|
|
|
|
|
0b00000101000001000001000001010000, 0b00000101010001010101000101010000, |
|
|
|
|
|
0b00010100010000010100000100010100, 0b01010000000001010000010101010000, |
|
|
|
|
|
0b01000001010000010001010000010100, 0b00000000000101000001010000000000, |
|
|
|
|
|
0b00000000000001000001010100000100, 0b00000000000100000101010000010000, |
|
|
|
|
|
0b00010000010101000001000000000000, 0b00000100000101010000010000000000, |
|
|
|
|
|
0b01010000010000010000010100010100, 0b01000001000001010001010001010000, |
|
|
|
|
|
0b00000101010000010101000000010100, 0b00010100000001010100000101010000, |
|
|
|
|
|
0b01000001000001010000010100010100, 0b01000001010100000101000000010100, |
|
|
|
|
|
0b01000000000000010001010101010100, 0b01010100000101010000000101000000, |
|
|
|
|
|
0b01010000010100000101010100000000, 0b00000000010101010101000001010000, |
|
|
|
|
|
0b00010101000101010001000000010000, 0b01010100010101000000010000000100, |
|
|
|
|
|
}; |
|
|
|
|
|
static const uint8_t AnchorTable2[MaxPartitions] = { |
|
|
|
|
|
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, |
|
|
|
|
|
0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, |
|
|
|
|
|
0xf, 0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0xf, |
|
|
|
|
|
0x2, 0x8, 0x2, 0x2, 0x8, 0x8, 0x2, 0x2, |
|
|
|
|
|
0xf, 0xf, 0x6, 0x8, 0x2, 0x8, 0xf, 0xf, |
|
|
|
|
|
0x2, 0x8, 0x2, 0x2, 0x2, 0xf, 0xf, 0x6, |
|
|
|
|
|
0x6, 0x2, 0x6, 0x8, 0xf, 0xf, 0x2, 0x2, |
|
|
|
|
|
0xf, 0xf, 0xf, 0xf, 0xf, 0x2, 0x2, 0xf, |
|
|
|
|
|
}; |
|
|
|
|
|
// @fmt:on
|
|
|
|
|
|
|
|
|
Data data(low64, high64); |
|
|
Data data(low64, high64); |
|
|
assert(dstBpp == sizeof(Color)); |
|
|
assert(dstBpp == sizeof(Color)); |
|
|
|
|
|
|
|
|
if ((data.low64 & 0x2) == 0) { |
|
|
|
|
|
mode = data.consumeBits(1, 0); |
|
|
|
|
|
} else { |
|
|
|
|
|
mode = data.consumeBits(4, 0); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
uint8_t mode = data.consumeBits((data.low64 & 0x2) == 0 ? 1 : 4, 0); |
|
|
|
|
|
|
|
|
int32_t blockIndex = modeToIndex(mode); |
|
|
int32_t blockIndex = modeToIndex(mode); |
|
|
// Handle illegal or reserved mode
|
|
|
// Handle illegal or reserved mode
|
|
|
@ -894,7 +853,7 @@ namespace { |
|
|
idx.num_bits = 3; |
|
|
idx.num_bits = 3; |
|
|
// There are 2 indices with implicit leading 0-bits.
|
|
|
// There are 2 indices with implicit leading 0-bits.
|
|
|
isAnchor = ((pixelNum == 0) || (pixelNum == AnchorTable2[partition])); |
|
|
isAnchor = ((pixelNum == 0) || (pixelNum == AnchorTable2[partition])); |
|
|
firstEndpoint = PartitionTable2[partition][pixelNum] * 2; |
|
|
|
|
|
|
|
|
firstEndpoint = ((p_table[partition] >> pixelNum) & 0x03) * 2; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
idx.value = data.consumeBits(idx.num_bits - isAnchor - 1, 0); |
|
|
idx.value = data.consumeBits(idx.num_bits - isAnchor - 1, 0); |
|
|
@ -931,7 +890,7 @@ namespace { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
struct Mode { |
|
|
struct Mode { |
|
|
const uint32_t IDX; // Mode index
|
|
|
|
|
|
|
|
|
const int32_t IDX; // Mode index
|
|
|
const uint32_t NS; // Number of subsets in each partition
|
|
|
const uint32_t NS; // Number of subsets in each partition
|
|
|
const uint32_t PB; // Partition bits
|
|
|
const uint32_t PB; // Partition bits
|
|
|
const uint32_t RB; // Rotation bits
|
|
|
const uint32_t RB; // Rotation bits
|
|
|
@ -946,7 +905,7 @@ namespace { |
|
|
|
|
|
|
|
|
constexpr uint32_t NumColors() const { return NS * 2; } |
|
|
constexpr uint32_t NumColors() const { return NS * 2; } |
|
|
|
|
|
|
|
|
constexpr Bitfield Partition() const { return {IDX + 1, PB}; } |
|
|
|
|
|
|
|
|
constexpr Bitfield Partition() const { return {uint32_t(IDX) + 1, PB}; } |
|
|
|
|
|
|
|
|
constexpr Bitfield Rotation() const { return Partition().Then(RB); } |
|
|
constexpr Bitfield Rotation() const { return Partition().Then(RB); } |
|
|
|
|
|
|
|
|
@ -1028,7 +987,7 @@ namespace { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Mode const& mode() const { |
|
|
Mode const& mode() const { |
|
|
static const Mode m_table[8] = { |
|
|
|
|
|
|
|
|
static const Mode m_table[8 + 1] = { |
|
|
// IDX NS PB RB ISB CB AB EPB SPB IB IBC, IB2
|
|
|
// IDX NS PB RB ISB CB AB EPB SPB IB IBC, IB2
|
|
|
/**/ {0x0, 0x3, 0x4, 0x0, 0x0, 0x4, 0x0, 0x1, 0x0, 0x3, 0x2d, 0x0}, |
|
|
/**/ {0x0, 0x3, 0x4, 0x0, 0x0, 0x4, 0x0, 0x1, 0x0, 0x3, 0x2d, 0x0}, |
|
|
/**/ {0x1, 0x2, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0x1, 0x3, 0x2e, 0x0}, |
|
|
/**/ {0x1, 0x2, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0x1, 0x3, 0x2e, 0x0}, |
|
|
@ -1038,6 +997,7 @@ namespace { |
|
|
/**/ {0x5, 0x1, 0x0, 0x2, 0x0, 0x7, 0x8, 0x0, 0x0, 0x2, 0x1f, 0x2}, |
|
|
/**/ {0x5, 0x1, 0x0, 0x2, 0x0, 0x7, 0x8, 0x0, 0x0, 0x2, 0x1f, 0x2}, |
|
|
/**/ {0x6, 0x1, 0x0, 0x0, 0x0, 0x7, 0x7, 0x1, 0x0, 0x4, 0x3f, 0x0}, |
|
|
/**/ {0x6, 0x1, 0x0, 0x0, 0x0, 0x7, 0x7, 0x1, 0x0, 0x4, 0x3f, 0x0}, |
|
|
/**/ {0x7, 0x2, 0x6, 0x0, 0x0, 0x5, 0x5, 0x1, 0x0, 0x2, 0x1e, 0x0}, |
|
|
/**/ {0x7, 0x2, 0x6, 0x0, 0x0, 0x5, 0x5, 0x1, 0x0, 0x2, 0x1e, 0x0}, |
|
|
|
|
|
/**/ {-1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x00, 0x0}, |
|
|
}; |
|
|
}; |
|
|
// Fun historical fact: this is basically ffs(), however, windows does NOT have ffs()
|
|
|
// Fun historical fact: this is basically ffs(), however, windows does NOT have ffs()
|
|
|
// This is because ffs() comes from VAX which had an instruction for ffs(), but
|
|
|
// This is because ffs() comes from VAX which had an instruction for ffs(), but
|
|
|
@ -1053,21 +1013,20 @@ namespace { |
|
|
else if ((low & 0b00100000) != 0) return m_table[5]; |
|
|
else if ((low & 0b00100000) != 0) return m_table[5]; |
|
|
else if ((low & 0b01000000) != 0) return m_table[6]; |
|
|
else if ((low & 0b01000000) != 0) return m_table[6]; |
|
|
else if ((low & 0b10000000) != 0) return m_table[7]; |
|
|
else if ((low & 0b10000000) != 0) return m_table[7]; |
|
|
return m_table[0]; //invalid but pretend it's fine
|
|
|
|
|
|
|
|
|
return m_table[8]; //invalid but pretend it's fine
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
struct IndexInfo { |
|
|
struct IndexInfo { |
|
|
uint64_t value; |
|
|
uint64_t value; |
|
|
int64_t num_bits; |
|
|
|
|
|
|
|
|
uint32_t num_bits; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
uint8_t interpolate(uint8_t e0, uint8_t e1, const IndexInfo &index) const { |
|
|
uint8_t interpolate(uint8_t e0, uint8_t e1, const IndexInfo &index) const { |
|
|
static const uint16_t weightsN[5][16] = { |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{ 0, 0, 0, 0, 0, 0 }, |
|
|
|
|
|
{0, 21, 43, 64}, // {0, 21, 43, 64} = (21 * n) + 1
|
|
|
|
|
|
{0, 9, 18, 27, 37, 46, 55, 64}, |
|
|
|
|
|
{0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64} |
|
|
|
|
|
|
|
|
static constexpr uint16_t weights2[] = {0, 21, 43, 64}; |
|
|
|
|
|
static constexpr uint16_t weights3[] = {0, 9, 18, 27, 37, 46, 55, 64}; |
|
|
|
|
|
static constexpr uint16_t weights4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64}; |
|
|
|
|
|
static constexpr uint16_t const *weightsN[] = { |
|
|
|
|
|
nullptr, nullptr, weights2, weights3, weights4 |
|
|
}; |
|
|
}; |
|
|
auto weights = weightsN[index.num_bits]; |
|
|
auto weights = weightsN[index.num_bits]; |
|
|
assert(weights != nullptr); |
|
|
assert(weights != nullptr); |
|
|
@ -1077,6 +1036,17 @@ namespace { |
|
|
void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch) const { |
|
|
void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch) const { |
|
|
assert(low <= 0b11111111); |
|
|
assert(low <= 0b11111111); |
|
|
auto const& mode = this->mode(); |
|
|
auto const& mode = this->mode(); |
|
|
|
|
|
if (mode.IDX < 0) { |
|
|
|
|
|
for (size_t y = 0; y < 4 && y + dstY < dstHeight; y++) { |
|
|
|
|
|
for (size_t x = 0; x < 4 && x + dstX < dstWidth; x++) { |
|
|
|
|
|
auto out = reinterpret_cast<Color *>(dst + sizeof(Color) * x + dstPitch * y); |
|
|
|
|
|
out->rgb = {0, 0, 0}; |
|
|
|
|
|
out->a = 0; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
std::array<std::array<Color, 2>, 3> subsets; |
|
|
std::array<std::array<Color, 2>, 3> subsets; |
|
|
for (size_t i = 0; i < mode.NS; i++) { |
|
|
for (size_t i = 0; i < mode.NS; i++) { |
|
|
auto& subset = subsets[i]; |
|
|
auto& subset = subsets[i]; |
|
|
|