Change the pixel channel size to 16 bits so that our arithmetic operations don't overflow.

This commit is contained in:
Pavel Krajcevski 2013-10-08 18:37:38 -04:00
parent dd12cc92cd
commit a4a289c177
2 changed files with 21 additions and 19 deletions

View file

@ -58,17 +58,19 @@
namespace FasTC { namespace FasTC {
class Pixel : public Vector4<uint8> { class Pixel : public Vector4<uint16> {
private: private:
typedef uint16 ChannelType;
typedef Vector4<ChannelType> VectorType;
uint8 m_BitDepth[4]; uint8 m_BitDepth[4];
public: public:
Pixel() : Vector4<uint8>(0, 0, 0, 0) { Pixel() : VectorType(0, 0, 0, 0) {
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
m_BitDepth[i] = 8; m_BitDepth[i] = 8;
} }
explicit Pixel(uint32 rgba) : Vector4<uint8>() { explicit Pixel(uint32 rgba) : VectorType() {
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
m_BitDepth[i] = 8; m_BitDepth[i] = 8;
Unpack(rgba); Unpack(rgba);
@ -76,7 +78,7 @@ class Pixel : public Vector4<uint8> {
Pixel(const uint8 *bits, Pixel(const uint8 *bits,
const uint8 channelDepth[4] = static_cast<uint8 *>(0), const uint8 channelDepth[4] = static_cast<uint8 *>(0),
uint8 bitOffset = 0) : Vector4<uint8>() { uint8 bitOffset = 0) : VectorType() {
FromBits(bits, channelDepth, bitOffset); FromBits(bits, channelDepth, bitOffset);
} }
@ -104,18 +106,18 @@ class Pixel : public Vector4<uint8> {
// Changes the bit depth of a single component. See the comment // Changes the bit depth of a single component. See the comment
// above for how we do this. // above for how we do this.
static uint8 ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth); static ChannelType ChangeBitDepth(ChannelType val, uint8 oldDepth, uint8 newDepth);
const uint8 &A() const { return X(); } const ChannelType &A() const { return X(); }
uint8 &A() { return X(); } ChannelType &A() { return X(); }
const uint8 &R() const { return Y(); } const ChannelType &R() const { return Y(); }
uint8 &R() { return Y(); } ChannelType &R() { return Y(); }
const uint8 &G() const { return Z(); } const ChannelType &G() const { return Z(); }
uint8 &G() { return Z(); } ChannelType &G() { return Z(); }
const uint8 &B() const { return W(); } const ChannelType &B() const { return W(); }
uint8 &B() { return W(); } ChannelType &B() { return W(); }
const uint8 &Component(uint32 idx) const { return vec[idx]; } const ChannelType &Component(uint32 idx) const { return vec[idx]; }
uint8 &Component(uint32 idx) { return vec[idx]; } ChannelType &Component(uint32 idx) { return vec[idx]; }
void GetBitDepth(uint8 (&outDepth)[4]) const { void GetBitDepth(uint8 (&outDepth)[4]) const {
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {

View file

@ -82,7 +82,7 @@ namespace FasTC {
} }
for(int32 i = 0; i < 4; i++) { for(int32 i = 0; i < 4; i++) {
uint8 &channel = Component(i); ChannelType &channel = Component(i);
uint32 depth = m_BitDepth[i]; uint32 depth = m_BitDepth[i];
assert(depth <= 8); assert(depth <= 8);
@ -125,7 +125,7 @@ namespace FasTC {
uint8 bitIdx = bitOffset; uint8 bitIdx = bitOffset;
for(int i = 3; i >= 0; i--) { for(int i = 3; i >= 0; i--) {
uint8 val = Component(i); ChannelType val = Component(i);
uint8 depth = m_BitDepth[i]; uint8 depth = m_BitDepth[i];
if(depth + bitIdx > 8) { if(depth + bitIdx > 8) {
@ -146,7 +146,7 @@ namespace FasTC {
} }
} }
uint8 Pixel::ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth) { Pixel::ChannelType Pixel::ChangeBitDepth(Pixel::ChannelType val, uint8 oldDepth, uint8 newDepth) {
assert(newDepth <= 8); assert(newDepth <= 8);
assert(oldDepth <= 8); assert(oldDepth <= 8);
@ -222,7 +222,7 @@ namespace FasTC {
ok = ok && m_BitDepth[i] == depths[i]; ok = ok && m_BitDepth[i] == depths[i];
uint8 mask = (1 << depths[i]) - 1; uint8 mask = (1 << depths[i]) - 1;
const uint8 c = other.Component(i) & mask; const ChannelType c = other.Component(i) & mask;
ok = ok && (c == (Component(i) & mask)); ok = ok && (c == (Component(i) & mask));
} }
return ok; return ok;