Add pixel packing routines

This commit is contained in:
Pavel Krajcevski 2013-09-24 19:29:03 -04:00
parent 75e570ed16
commit 340f4f3141
3 changed files with 71 additions and 0 deletions

View file

@ -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);

View file

@ -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

View file

@ -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;