diff --git a/PVRTCEncoder/src/Image.cpp b/PVRTCEncoder/src/Image.cpp index 0de9335..ff1d277 100644 --- a/PVRTCEncoder/src/Image.cpp +++ b/PVRTCEncoder/src/Image.cpp @@ -73,11 +73,6 @@ inline T Clamp(const T &v, const T &a, const T &b) { return ::std::min(::std::max(a, v), b); } -static float ConvertChannelToFloat(uint8 channel, uint8 bitDepth) { - float denominator = static_cast((1 << bitDepth) - 1); - return static_cast(channel) / denominator; -} - namespace PVRTCC { Image::Image(uint32 height, uint32 width) @@ -280,14 +275,7 @@ void Image::ContentAwareDownscale(uint32 xtimes, uint32 ytimes, // Then, compute the intensity of the image for(uint32 i = 0; i < w * h; i++) { - // First convert the pixel values to floats using - // premultiplied alpha... - float a = ConvertChannelToFloat(m_Pixels[i].A(), bitDepth[0]); - float r = a * ConvertChannelToFloat(m_Pixels[i].R(), bitDepth[1]); - float g = a * ConvertChannelToFloat(m_Pixels[i].G(), bitDepth[2]); - float b = a * ConvertChannelToFloat(m_Pixels[i].B(), bitDepth[3]); - - I[i] = r * 0.21f + g * 0.71f + b * 0.07f; + I[i] = m_Pixels[i].ToIntensity(); } // Use central differences to calculate Ix, Iy, Ixx, Iyy... @@ -308,7 +296,7 @@ void Image::ContentAwareDownscale(uint32 xtimes, uint32 ytimes, Iy[idx] = (I[yphidx] - I[ymhidx]) / 2.0f; for(uint32 c = 0; c <= 3; c++) { - #define CPNT(dx) ConvertChannelToFloat(m_Pixels[dx].Component(c), bitDepth[c]) +#define CPNT(dx) Pixel::ConvertChannelToFloat(m_Pixels[dx].Component(c), bitDepth[c]) Ix[c][idx] = (CPNT(xphidx) - CPNT(xmhidx)) / 2.0f; Ixx[c][idx] = (CPNT(xphidx) - 2.0f*CPNT(idx) + CPNT(xmhidx)) / 2.0f; Iyy[c][idx] = (CPNT(yphidx) - 2.0f*CPNT(idx) + CPNT(ymhidx)) / 2.0f; @@ -349,7 +337,7 @@ void Image::ContentAwareDownscale(uint32 xtimes, uint32 ytimes, float denom = Ixsq + Iysq; for(uint32 c = 0; c < 4; c++) { - float I0 = ConvertChannelToFloat(current.Component(c), bitDepth[c]); + float I0 = Pixel::ConvertChannelToFloat(current.Component(c), bitDepth[c]); float It = Ixx[c][idx] + Iyy[c][idx]; if(fabs(denom) > 1e-6) { It -= (Ixsq * Ixx[c][idx] + diff --git a/PVRTCEncoder/src/Pixel.cpp b/PVRTCEncoder/src/Pixel.cpp index 8ea763d..3e3acd8 100644 --- a/PVRTCEncoder/src/Pixel.cpp +++ b/PVRTCEncoder/src/Pixel.cpp @@ -190,6 +190,15 @@ namespace PVRTCC { } } + float Pixel::ToIntensity() const { + // First convert the pixel values to floats using premultiplied alpha... + float a = ConvertChannelToFloat(A(), m_BitDepth[0]); + float r = a * ConvertChannelToFloat(R(), m_BitDepth[1]); + float g = a * ConvertChannelToFloat(G(), m_BitDepth[2]); + float b = a * ConvertChannelToFloat(B(), m_BitDepth[3]); + return r * 0.21f + g * 0.71f + b * 0.07f; + } + uint32 Pixel::PackRGBA() const { Pixel eightBit(*this); const uint8 eightBitDepth[4] = { 8, 8, 8, 8 }; diff --git a/PVRTCEncoder/src/Pixel.h b/PVRTCEncoder/src/Pixel.h index f8821f4..160417d 100644 --- a/PVRTCEncoder/src/Pixel.h +++ b/PVRTCEncoder/src/Pixel.h @@ -96,6 +96,16 @@ class Pixel { // smaller to larger bit depths. void ChangeBitDepth(const uint8 (&newDepth)[4]); + static float ConvertChannelToFloat(uint8 channel, uint8 bitDepth) { + float denominator = static_cast((1 << bitDepth) - 1); + return static_cast(channel) / denominator; + } + + // Returns the intensity of the pixel. Computed using the following + // formula: + // a*r*0.21f + a*g*0.71f + a*b*0.07f; + float ToIntensity() const; + // Changes the bit depth of a single component. See the comment // above for how we do this. static uint8 ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth);