mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2025-01-09 15:15:38 +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) {
|
||||
assert(newDepth <= 8);
|
||||
assert(oldDepth <= 8);
|
||||
|
|
|
@ -82,6 +82,13 @@ class Pixel {
|
|||
const uint8 channelDepth[4] = static_cast<uint8 *>(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
|
||||
// the appropriate bit depth by either truncating the least
|
||||
// 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) {
|
||||
uint8 val = 0x43;
|
||||
uint8 depth = 7;
|
||||
|
|
Loading…
Reference in a new issue