mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2025-01-09 15:05:36 +00:00
Add pixel packing routines
This commit is contained in:
parent
75e570ed16
commit
340f4f3141
|
@ -108,6 +108,44 @@ namespace PVRTCC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pixel::ToBits(uint8 *bits, uint32 numBytes, uint32 bitOffset) const {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
uint32 bitDepthSum = bitOffset;
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
bitDepthSum += m_BitDepth[i];
|
||||||
|
}
|
||||||
|
assert((bitDepthSum / 8) < numBytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8 byteIdx = 0;
|
||||||
|
while(bitOffset > 8) {
|
||||||
|
byteIdx++;
|
||||||
|
bitOffset -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 bitIdx = bitOffset;
|
||||||
|
for(int i = 3; i >= 0; i--) {
|
||||||
|
uint8 val = Component(i);
|
||||||
|
uint8 depth = m_BitDepth[i];
|
||||||
|
|
||||||
|
if(depth + bitIdx > 8) {
|
||||||
|
uint8 nextBitIdx = depth - (8 - bitIdx);
|
||||||
|
uint16 v = static_cast<uint16>(val);
|
||||||
|
bits[byteIdx++] |= (v << bitIdx) & 0xFF;
|
||||||
|
bitIdx = nextBitIdx;
|
||||||
|
bits[byteIdx] = (v >> (depth - bitIdx)) & 0xFF;
|
||||||
|
} else {
|
||||||
|
bits[byteIdx] |= (val << bitIdx) & 0xFF;
|
||||||
|
bitIdx += depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bitIdx == 8) {
|
||||||
|
bitIdx = 0;
|
||||||
|
byteIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8 Pixel::ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth) {
|
uint8 Pixel::ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth) {
|
||||||
assert(newDepth <= 8);
|
assert(newDepth <= 8);
|
||||||
assert(oldDepth <= 8);
|
assert(oldDepth <= 8);
|
||||||
|
|
|
@ -82,6 +82,13 @@ class Pixel {
|
||||||
const uint8 channelDepth[4] = static_cast<uint8 *>(0),
|
const uint8 channelDepth[4] = static_cast<uint8 *>(0),
|
||||||
uint8 bitOffset = 0);
|
uint8 bitOffset = 0);
|
||||||
|
|
||||||
|
// This function is the converse of FromBits. It will pack a pixel
|
||||||
|
// into a specified buffer based on the bit depth of the pixel. The
|
||||||
|
// bitOffset determines at which bit to start from. The bits are written
|
||||||
|
// starting from the LSB of bits[0]. numBytes is a sanity check and isn't
|
||||||
|
// used in release mode.
|
||||||
|
void ToBits(uint8 *bits, uint32 numBytes, uint32 bitOffset = 0) const;
|
||||||
|
|
||||||
// Changes the depth of each pixel. This scales the values to
|
// Changes the depth of each pixel. This scales the values to
|
||||||
// the appropriate bit depth by either truncating the least
|
// the appropriate bit depth by either truncating the least
|
||||||
// significant bits when going from larger to smaller bit depth
|
// significant bits when going from larger to smaller bit depth
|
||||||
|
|
|
@ -133,6 +133,32 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Pixel, ToBits) {
|
||||||
|
PVRTCC::Pixel p;
|
||||||
|
|
||||||
|
uint8 bitDepth[4] = { 2, 8, 1, 7 };
|
||||||
|
p.ChangeBitDepth(bitDepth);
|
||||||
|
|
||||||
|
p.A() = 0x2;
|
||||||
|
p.R() = 0x56;
|
||||||
|
p.G() = 0;
|
||||||
|
p.B() = 0x4F;
|
||||||
|
|
||||||
|
uint8 bits[3];
|
||||||
|
memset(bits, 0, sizeof(bits));
|
||||||
|
p.ToBits(bits, sizeof(bits));
|
||||||
|
|
||||||
|
EXPECT_EQ(bits[0], 0x4F);
|
||||||
|
EXPECT_EQ(bits[1], 0x56);
|
||||||
|
EXPECT_EQ(bits[2], 0x2);
|
||||||
|
|
||||||
|
memset(bits, 0, sizeof(bits));
|
||||||
|
p.ToBits(bits, 3, 2);
|
||||||
|
EXPECT_EQ(bits[0], 0x3C);
|
||||||
|
EXPECT_EQ(bits[1], 0x59);
|
||||||
|
EXPECT_EQ(bits[2], 0x09);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Pixel, ChangeChannelBitDepth) {
|
TEST(Pixel, ChangeChannelBitDepth) {
|
||||||
uint8 val = 0x43;
|
uint8 val = 0x43;
|
||||||
uint8 depth = 7;
|
uint8 depth = 7;
|
||||||
|
|
Loading…
Reference in a new issue