Move Pixel class from PVRTCEncoder to FasTCBase.

This commit is contained in:
Pavel Krajcevski 2013-10-03 17:25:15 -04:00
parent cb348c3598
commit ab598c9ef7
14 changed files with 404 additions and 83 deletions

View File

@ -52,12 +52,21 @@
SET( SOURCES SET( SOURCES
"src/Image.cpp" "src/Image.cpp"
"src/CompressionJob.cpp" "src/CompressionJob.cpp"
"src/Pixel.cpp"
) )
SET( HEADERS SET( HEADERS
"include/TexCompTypes.h" "include/TexCompTypes.h"
"include/Image.h" "include/Image.h"
"include/CompressionJob.h" "include/CompressionJob.h"
"include/Pixel.h"
"include/VectorBase.h"
"include/Vector2.h"
"include/Vector3.h"
"include/Vector4.h"
"include/MatrixBase.h"
"include/MatrixSquare.h"
"include/Matrix3x3.h"
) )
INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include)

View File

@ -50,27 +50,33 @@
* <http://gamma.cs.unc.edu/FasTC/> * <http://gamma.cs.unc.edu/FasTC/>
*/ */
#ifndef PVRTCENCODER_SRC_PIXEL_H_ #ifndef BASE_INCLUDE_PIXEL_H_
#define PVRTCENCODER_SRC_PIXEL_H_ #define BASE_INCLUDE_PIXEL_H_
#include "TexCompTypes.h" #include "TexCompTypes.h"
#include "Vector4.h"
namespace PVRTCC { namespace FasTC {
class Pixel : public Vector4<uint8> {
private:
uint8 m_BitDepth[4];
class Pixel {
public: public:
Pixel(): m_A(0), m_R(0), m_G(0), m_B(0) { Pixel() : Vector4<uint8>(0, 0, 0, 0) {
for(int i = 0; i < 4; i++) m_BitDepth[i] = 8; for(int i = 0; i < 4; i++)
m_BitDepth[i] = 8;
} }
explicit Pixel(uint32 rgba) { explicit Pixel(uint32 rgba) : Vector4<uint8>() {
for(int i = 0; i < 4; i++) m_BitDepth[i] = 8; for(int i = 0; i < 4; i++)
UnpackRGBA(rgba); m_BitDepth[i] = 8;
Unpack(rgba);
} }
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) { uint8 bitOffset = 0) : Vector4<uint8>() {
FromBits(bits, channelDepth, bitOffset); FromBits(bits, channelDepth, bitOffset);
} }
@ -100,16 +106,16 @@ class Pixel {
// above for how we do this. // above for how we do this.
static uint8 ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth); static uint8 ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth);
const uint8 &A() const { return m_A; } const uint8 &A() const { return X(); }
uint8 &A() { return m_A; } uint8 &A() { return X(); }
const uint8 &R() const { return m_R; } const uint8 &R() const { return Y(); }
uint8 &R() { return m_R; } uint8 &R() { return Y(); }
const uint8 &G() const { return m_G; } const uint8 &G() const { return Z(); }
uint8 &G() { return m_G; } uint8 &G() { return Z(); }
const uint8 &B() const { return m_B; } const uint8 &B() const { return W(); }
uint8 &B() { return m_B; } uint8 &B() { return W(); }
const uint8 &Component(uint32 idx) const { return m_Component[idx]; } const uint8 &Component(uint32 idx) const { return vec[idx]; }
uint8 &Component(uint32 idx) { return m_Component[idx]; } uint8 &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++) {
@ -121,27 +127,13 @@ class Pixel {
// and then pack each channel into an R8G8B8A8 32-bit integer. We assume // and then pack each channel into an R8G8B8A8 32-bit integer. We assume
// that the architecture is little-endian, so the alpha channel will end // that the architecture is little-endian, so the alpha channel will end
// up in the most-significant byte. // up in the most-significant byte.
uint32 PackRGBA() const; uint32 Pack() const;
void UnpackRGBA(uint32 rgba); void Unpack(uint32 rgba);
// Tests for equality by comparing the values and the bit depths. // Tests for equality by comparing the values and the bit depths.
bool operator==(const Pixel &) const; bool operator==(const Pixel &) const;
private:
union {
struct {
uint8 m_A;
uint8 m_R;
uint8 m_G;
uint8 m_B;
};
uint8 m_Component[4];
};
// This contains the number of bits that each pixel has.
uint8 m_BitDepth[4];
}; };
} // namespace PVRTCC } // namespace FasTC
#endif // PVRTCENCODER_SRC_PIXEL_H_ #endif // BASE_INCLUDE_PIXEL_H_

View File

@ -56,7 +56,7 @@
#include <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
namespace PVRTCC { namespace FasTC {
void Pixel::FromBits(const uint8 *bits, void Pixel::FromBits(const uint8 *bits,
const uint8 channelDepth[4], const uint8 channelDepth[4],
@ -82,7 +82,7 @@ namespace PVRTCC {
} }
for(int32 i = 0; i < 4; i++) { for(int32 i = 0; i < 4; i++) {
uint8 &channel = m_Component[i]; uint8 &channel = Component(i);
uint32 depth = m_BitDepth[i]; uint32 depth = m_BitDepth[i];
assert(depth <= 8); assert(depth <= 8);
@ -185,12 +185,12 @@ namespace PVRTCC {
void Pixel::ChangeBitDepth(const uint8 (&depth)[4]) { void Pixel::ChangeBitDepth(const uint8 (&depth)[4]) {
for(uint32 i = 0; i < 4; i++) { for(uint32 i = 0; i < 4; i++) {
m_Component[i] = ChangeBitDepth(m_Component[i], m_BitDepth[i], depth[i]); Component(i) = ChangeBitDepth(Component(i), m_BitDepth[i], depth[i]);
m_BitDepth[i] = depth[i]; m_BitDepth[i] = depth[i];
} }
} }
uint32 Pixel::PackRGBA() const { uint32 Pixel::Pack() const {
Pixel eightBit(*this); Pixel eightBit(*this);
const uint8 eightBitDepth[4] = { 8, 8, 8, 8 }; const uint8 eightBitDepth[4] = { 8, 8, 8, 8 };
eightBit.ChangeBitDepth(eightBitDepth); eightBit.ChangeBitDepth(eightBitDepth);
@ -206,7 +206,7 @@ namespace PVRTCC {
return r; return r;
} }
void Pixel::UnpackRGBA(uint32 rgba) { void Pixel::Unpack(uint32 rgba) {
A() = ChangeBitDepth((rgba >> 24) & 0xFF, 8, m_BitDepth[0]); A() = ChangeBitDepth((rgba >> 24) & 0xFF, 8, m_BitDepth[0]);
R() = ChangeBitDepth(rgba & 0xFF, 8, m_BitDepth[1]); R() = ChangeBitDepth(rgba & 0xFF, 8, m_BitDepth[1]);
G() = ChangeBitDepth((rgba >> 8) & 0xFF, 8, m_BitDepth[2]); G() = ChangeBitDepth((rgba >> 8) & 0xFF, 8, m_BitDepth[2]);
@ -228,4 +228,4 @@ namespace PVRTCC {
return ok; return ok;
} }
} // namespace PVRTCC } // namespace FasTC

66
Base/test/CMakeLists.txt Normal file
View File

@ -0,0 +1,66 @@
# FasTC
# Copyright (c) 2013 University of North Carolina at Chapel Hill.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for educational, research, and non-profit purposes, without
# fee, and without a written agreement is hereby granted, provided that the
# above copyright notice, this paragraph, and the following four paragraphs
# appear in all copies.
#
# Permission to incorporate this software into commercial products may be
# obtained by contacting the authors or the Office of Technology Development
# at the University of North Carolina at Chapel Hill <otd@unc.edu>.
#
# This software program and documentation are copyrighted by the University of
# North Carolina at Chapel Hill. The software program and documentation are
# supplied "as is," without any accompanying services from the University of
# North Carolina at Chapel Hill or the authors. The University of North
# Carolina at Chapel Hill and the authors do not warrant that the operation of
# the program will be uninterrupted or error-free. The end-user understands
# that the program was developed for research purposes and is advised not to
# rely exclusively on the program for any reason.
#
# IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
# AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
# OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
# AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
# DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
# STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
# AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND
# THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
# ENHANCEMENTS, OR MODIFICATIONS.
#
# Please send all BUG REPORTS to <pavel@cs.unc.edu>.
#
# The authors may be contacted via:
#
# Pavel Krajcevski
# Dept of Computer Science
# 201 S Columbia St
# Frederick P. Brooks, Jr. Computer Science Bldg
# Chapel Hill, NC 27599-3175
# USA
#
# <http://gamma.cs.unc.edu/FasTC/>
INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include)
INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include)
SET(TESTS
Pixel
)
FOREACH(TEST ${TESTS})
SET(TEST_NAME Test${TEST})
SET(TEST_MODULE Test${TEST}.cpp)
ADD_EXECUTABLE(${TEST_NAME} ${TEST_MODULE})
TARGET_LINK_LIBRARIES(${TEST_NAME} FasTCBase)
TARGET_LINK_LIBRARIES(${TEST_NAME} gtest_main)
ADD_TEST(${TEST_NAME} ${TEST_NAME})
ENDFOREACH()

View File

@ -54,7 +54,7 @@
#include "Pixel.h" #include "Pixel.h"
TEST(Pixel, DefaultConstructor) { TEST(Pixel, DefaultConstructor) {
PVRTCC::Pixel p; FasTC::Pixel p;
EXPECT_EQ(p.R(), 0); EXPECT_EQ(p.R(), 0);
EXPECT_EQ(p.G(), 0); EXPECT_EQ(p.G(), 0);
EXPECT_EQ(p.B(), 0); EXPECT_EQ(p.B(), 0);
@ -70,12 +70,12 @@ TEST(Pixel, DefaultConstructor) {
TEST(Pixel, FromBitsAndAssociatedConstructor) { TEST(Pixel, FromBitsAndAssociatedConstructor) {
const uint8 bits[8] = { 0xA8, 0xB3, 0x7C, 0x21, 0xBD, 0xD4, 0x09, 0x92 }; const uint8 bits[8] = { 0xA8, 0xB3, 0x7C, 0x21, 0xBD, 0xD4, 0x09, 0x92 };
PVRTCC::Pixel ps[2]; FasTC::Pixel ps[2];
ps[0] = PVRTCC::Pixel(bits); ps[0] = FasTC::Pixel(bits);
ps[1].FromBits(bits); ps[1].FromBits(bits);
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
PVRTCC::Pixel &p = ps[i]; FasTC::Pixel &p = ps[i];
EXPECT_EQ(p.A(), 0xA8); EXPECT_EQ(p.A(), 0xA8);
EXPECT_EQ(p.R(), 0xB3); EXPECT_EQ(p.R(), 0xB3);
@ -90,11 +90,11 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) {
} }
const uint8 depth1[4] = { 3, 2, 0, 8 }; const uint8 depth1[4] = { 3, 2, 0, 8 };
ps[0] = PVRTCC::Pixel(bits + 3, depth1); ps[0] = FasTC::Pixel(bits + 3, depth1);
ps[1].FromBits(bits + 3, depth1); ps[1].FromBits(bits + 3, depth1);
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
PVRTCC::Pixel &p = ps[i]; FasTC::Pixel &p = ps[i];
EXPECT_EQ(p.A(), 0x01); EXPECT_EQ(p.A(), 0x01);
EXPECT_EQ(p.R(), 0x00); EXPECT_EQ(p.R(), 0x00);
@ -112,11 +112,11 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) {
const uint8 depth2[4] = { 5, 6, 2, 4 }; const uint8 depth2[4] = { 5, 6, 2, 4 };
ps[0] = PVRTCC::Pixel(bits + 4, depth2, 2); ps[0] = FasTC::Pixel(bits + 4, depth2, 2);
ps[1].FromBits(bits + 4, depth2, 2); ps[1].FromBits(bits + 4, depth2, 2);
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
PVRTCC::Pixel &p = ps[i]; FasTC::Pixel &p = ps[i];
EXPECT_EQ(p.A(), 0x1E); EXPECT_EQ(p.A(), 0x1E);
EXPECT_EQ(p.R(), 0x3A); EXPECT_EQ(p.R(), 0x3A);
@ -134,7 +134,7 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) {
} }
TEST(Pixel, ToBits) { TEST(Pixel, ToBits) {
PVRTCC::Pixel p; FasTC::Pixel p;
uint8 bitDepth[4] = { 2, 8, 1, 7 }; uint8 bitDepth[4] = { 2, 8, 1, 7 };
p.ChangeBitDepth(bitDepth); p.ChangeBitDepth(bitDepth);
@ -163,39 +163,39 @@ TEST(Pixel, ChangeChannelBitDepth) {
uint8 val = 0x43; uint8 val = 0x43;
uint8 depth = 7; uint8 depth = 7;
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 8), 0x87); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 8), 0x87);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 7), 0x43); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 7), 0x43);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 6), 0x22); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 6), 0x22);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 2), 0x2); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 2), 0x2);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF);
val = 0x3; val = 0x3;
depth = 3; depth = 3;
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 8), 0x6D); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 8), 0x6D);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 6), 0x1B); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 6), 0x1B);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 3), 0x03); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 3), 0x03);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 2), 0x02); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 2), 0x02);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF);
} }
TEST(Pixel, ChangeChannelBitDepthFromZero) { TEST(Pixel, ChangeChannelBitDepthFromZero) {
uint8 val = 0x43; uint8 val = 0x43;
uint8 depth = 0; uint8 depth = 0;
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 8), 0xFF); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 8), 0xFF);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 7), 0x7F); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 7), 0x7F);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 6), 0x3F); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 6), 0x3F);
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 2), 0x03); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 2), 0x03);
// Shouldn't change it... // Shouldn't change it...
EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 0), 0x43); EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 0), 0x43);
} }
TEST(Pixel, ChangePixelBitDepth) { TEST(Pixel, ChangePixelBitDepth) {
const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 }; const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 };
const uint8 depth[4] = {7, 3, 0, 0}; const uint8 depth[4] = {7, 3, 0, 0};
PVRTCC::Pixel p(bits, depth); FasTC::Pixel p(bits, depth);
const uint8 newDepth[4] = { 8, 8, 8, 8 }; const uint8 newDepth[4] = { 8, 8, 8, 8 };
p.ChangeBitDepth(newDepth); p.ChangeBitDepth(newDepth);
@ -216,7 +216,7 @@ TEST(Pixel, ChangePixelBitDepth) {
TEST(Pixel, PackRGBA) { TEST(Pixel, PackRGBA) {
const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 }; const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 };
const uint8 depth[4] = {7, 3, 0, 0}; const uint8 depth[4] = {7, 3, 0, 0};
PVRTCC::Pixel p(bits, depth); FasTC::Pixel p(bits, depth);
uint32 val = p.PackRGBA(); uint32 val = p.PackRGBA();
EXPECT_EQ(val, 0x87FFFF6D); EXPECT_EQ(val, 0x87FFFF6D);
@ -224,7 +224,7 @@ TEST(Pixel, PackRGBA) {
TEST(Pixel, UnpackRGBA) { TEST(Pixel, UnpackRGBA) {
uint32 rgba = 0x4619B3FE; uint32 rgba = 0x4619B3FE;
PVRTCC::Pixel p; FasTC::Pixel p;
p.UnpackRGBA(rgba); p.UnpackRGBA(rgba);
EXPECT_EQ(p.A(), 0x46); EXPECT_EQ(p.A(), 0x46);
@ -232,13 +232,13 @@ TEST(Pixel, UnpackRGBA) {
EXPECT_EQ(p.G(), 0xB3); EXPECT_EQ(p.G(), 0xB3);
EXPECT_EQ(p.R(), 0xFE); EXPECT_EQ(p.R(), 0xFE);
p = PVRTCC::Pixel(rgba); p = FasTC::Pixel(rgba);
EXPECT_EQ(p.A(), 0x46); EXPECT_EQ(p.A(), 0x46);
EXPECT_EQ(p.B(), 0x19); EXPECT_EQ(p.B(), 0x19);
EXPECT_EQ(p.G(), 0xB3); EXPECT_EQ(p.G(), 0xB3);
EXPECT_EQ(p.R(), 0xFE); EXPECT_EQ(p.R(), 0xFE);
p = PVRTCC::Pixel(); p = FasTC::Pixel();
uint8 newBitDepth[4] = { 3, 5, 2, 1 }; // A R G B uint8 newBitDepth[4] = { 3, 5, 2, 1 }; // A R G B
p.ChangeBitDepth(newBitDepth); p.ChangeBitDepth(newBitDepth);
p.UnpackRGBA(rgba); p.UnpackRGBA(rgba);

250
Base/test/TestPixel.cpp Normal file
View File

@ -0,0 +1,250 @@
/* FasTC
* Copyright (c) 2013 University of North Carolina at Chapel Hill.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research, and non-profit purposes, without
* fee, and without a written agreement is hereby granted, provided that the
* above copyright notice, this paragraph, and the following four paragraphs
* appear in all copies.
*
* Permission to incorporate this software into commercial products may be
* obtained by contacting the authors or the Office of Technology Development
* at the University of North Carolina at Chapel Hill <otd@unc.edu>.
*
* This software program and documentation are copyrighted by the University of
* North Carolina at Chapel Hill. The software program and documentation are
* supplied "as is," without any accompanying services from the University of
* North Carolina at Chapel Hill or the authors. The University of North
* Carolina at Chapel Hill and the authors do not warrant that the operation of
* the program will be uninterrupted or error-free. The end-user understands
* that the program was developed for research purposes and is advised not to
* rely exclusively on the program for any reason.
*
* IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
* AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
* AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
* DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
* STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
* AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND
* THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
* Please send all BUG REPORTS to <pavel@cs.unc.edu>.
*
* The authors may be contacted via:
*
* Pavel Krajcevski
* Dept of Computer Science
* 201 S Columbia St
* Frederick P. Brooks, Jr. Computer Science Bldg
* Chapel Hill, NC 27599-3175
* USA
*
* <http://gamma.cs.unc.edu/FasTC/>
*/
#include "gtest/gtest.h"
#include "Pixel.h"
TEST(Pixel, DefaultConstructor) {
FasTC::Pixel p;
EXPECT_EQ(p.R(), 0);
EXPECT_EQ(p.G(), 0);
EXPECT_EQ(p.B(), 0);
EXPECT_EQ(p.A(), 0);
uint8 depth[4];
p.GetBitDepth(depth);
for(int i = 0; i < 4; i++) {
EXPECT_EQ(depth[i], 8);
}
}
TEST(Pixel, FromBitsAndAssociatedConstructor) {
const uint8 bits[8] = { 0xA8, 0xB3, 0x7C, 0x21, 0xBD, 0xD4, 0x09, 0x92 };
FasTC::Pixel ps[2];
ps[0] = FasTC::Pixel(bits);
ps[1].FromBits(bits);
for(int i = 0; i < 2; i++) {
FasTC::Pixel &p = ps[i];
EXPECT_EQ(p.A(), 0xA8);
EXPECT_EQ(p.R(), 0xB3);
EXPECT_EQ(p.G(), 0x7C);
EXPECT_EQ(p.B(), 0x21);
uint8 depth[4];
p.GetBitDepth(depth);
for(int j = 0; j < 4; j++) {
EXPECT_EQ(depth[j], 8);
}
}
const uint8 depth1[4] = { 3, 2, 0, 8 };
ps[0] = FasTC::Pixel(bits + 3, depth1);
ps[1].FromBits(bits + 3, depth1);
for(int i = 0; i < 2; i++) {
FasTC::Pixel &p = ps[i];
EXPECT_EQ(p.A(), 0x01);
EXPECT_EQ(p.R(), 0x00);
EXPECT_EQ(p.G(), 0xFF);
EXPECT_EQ(p.B(), 0x37);
uint8 depth[4];
p.GetBitDepth(depth);
EXPECT_EQ(depth[0], 3);
EXPECT_EQ(depth[1], 2);
EXPECT_EQ(depth[2], 0);
EXPECT_EQ(depth[3], 8);
}
const uint8 depth2[4] = { 5, 6, 2, 4 };
ps[0] = FasTC::Pixel(bits + 4, depth2, 2);
ps[1].FromBits(bits + 4, depth2, 2);
for(int i = 0; i < 2; i++) {
FasTC::Pixel &p = ps[i];
EXPECT_EQ(p.A(), 0x1E);
EXPECT_EQ(p.R(), 0x3A);
EXPECT_EQ(p.G(), 0x02);
EXPECT_EQ(p.B(), 0x00);
uint8 depth[4];
p.GetBitDepth(depth);
EXPECT_EQ(depth[0], 5);
EXPECT_EQ(depth[1], 6);
EXPECT_EQ(depth[2], 2);
EXPECT_EQ(depth[3], 4);
}
}
TEST(Pixel, ToBits) {
FasTC::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;
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 8), 0x87);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 7), 0x43);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 6), 0x22);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 2), 0x2);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF);
val = 0x3;
depth = 3;
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 8), 0x6D);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 6), 0x1B);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 3), 0x03);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 2), 0x02);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF);
}
TEST(Pixel, ChangeChannelBitDepthFromZero) {
uint8 val = 0x43;
uint8 depth = 0;
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 8), 0xFF);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 7), 0x7F);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 6), 0x3F);
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 2), 0x03);
// Shouldn't change it...
EXPECT_EQ(FasTC::Pixel::ChangeBitDepth(val, depth, 0), 0x43);
}
TEST(Pixel, ChangePixelBitDepth) {
const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 };
const uint8 depth[4] = {7, 3, 0, 0};
FasTC::Pixel p(bits, depth);
const uint8 newDepth[4] = { 8, 8, 8, 8 };
p.ChangeBitDepth(newDepth);
EXPECT_EQ(p.A(), 0x87);
EXPECT_EQ(p.R(), 0x6D);
EXPECT_EQ(p.G(), 0xFF);
EXPECT_EQ(p.B(), 0xFF);
uint8 outDepth[4];
p.GetBitDepth(outDepth);
for(uint32 i = 0; i < 4; i++) {
EXPECT_EQ(outDepth[i], 8);
}
}
TEST(Pixel, PackRGBA) {
const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 };
const uint8 depth[4] = {7, 3, 0, 0};
FasTC::Pixel p(bits, depth);
uint32 val = p.Pack();
EXPECT_EQ(val, 0x87FFFF6D);
}
TEST(Pixel, UnpackRGBA) {
uint32 rgba = 0x4619B3FE;
FasTC::Pixel p;
p.Unpack(rgba);
EXPECT_EQ(p.A(), 0x46);
EXPECT_EQ(p.B(), 0x19);
EXPECT_EQ(p.G(), 0xB3);
EXPECT_EQ(p.R(), 0xFE);
p = FasTC::Pixel(rgba);
EXPECT_EQ(p.A(), 0x46);
EXPECT_EQ(p.B(), 0x19);
EXPECT_EQ(p.G(), 0xB3);
EXPECT_EQ(p.R(), 0xFE);
p = FasTC::Pixel();
uint8 newBitDepth[4] = { 3, 5, 2, 1 }; // A R G B
p.ChangeBitDepth(newBitDepth);
p.Unpack(rgba);
EXPECT_EQ(p.A(), 0x2);
EXPECT_EQ(p.B(), 0x0);
EXPECT_EQ(p.G(), 0x3);
EXPECT_EQ(p.R(), 0x1f);
}

View File

@ -56,7 +56,6 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include)
SET( HEADERS SET( HEADERS
include/PVRTCCompressor.h include/PVRTCCompressor.h
src/Pixel.h
src/Block.h src/Block.h
src/Image.h src/Image.h
) )
@ -64,7 +63,6 @@ SET( HEADERS
SET( SOURCES SET( SOURCES
src/Compressor.cpp src/Compressor.cpp
src/Decompressor.cpp src/Decompressor.cpp
src/Pixel.cpp
src/Block.cpp src/Block.cpp
src/Image.cpp src/Image.cpp
) )
@ -74,5 +72,6 @@ ADD_LIBRARY( PVRTCEncoder
${SOURCES} ${SOURCES}
) )
TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCBase )
TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCCore ) TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCCore )
TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCIO ) TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCIO )

View File

@ -58,6 +58,7 @@
namespace PVRTCC { namespace PVRTCC {
using FasTC::Pixel;
class Block { class Block {
public: public:
Block(): m_LongData(0) { } Block(): m_LongData(0) { }

View File

@ -130,7 +130,7 @@ namespace PVRTCC {
uint32 y = i / dcj.width; uint32 y = i / dcj.width;
const uint32 *pixels = reinterpret_cast<const uint32 *>(dcj.inBuf); const uint32 *pixels = reinterpret_cast<const uint32 *>(dcj.inBuf);
img(x, y).UnpackRGBA(pixels[i]); img(x, y).Unpack(pixels[i]);
} }
Image original = img; Image original = img;

View File

@ -160,7 +160,7 @@ namespace PVRTCC {
} }
uint32 *outPixels = reinterpret_cast<uint32 *>(outBuf); uint32 *outPixels = reinterpret_cast<uint32 *>(outBuf);
outPixels[(j * w) + i] = result.PackRGBA(); outPixels[(j * w) + i] = result.Pack();
} }
} }
@ -269,7 +269,7 @@ namespace PVRTCC {
} }
uint32 *outPixels = reinterpret_cast<uint32 *>(outBuf); uint32 *outPixels = reinterpret_cast<uint32 *>(outBuf);
outPixels[(j * w) + i] = result.PackRGBA(); outPixels[(j * w) + i] = result.Pack();
} }
} }

View File

@ -476,7 +476,7 @@ void Image::DebugOutput(const char *filename) const {
p.ChangeBitDepth(fullDepth); p.ChangeBitDepth(fullDepth);
p.A() = 255; p.A() = 255;
outPixels[idx] = p.PackRGBA(); outPixels[idx] = p.Pack();
} }
} }

View File

@ -56,10 +56,14 @@
#include "TexCompTypes.h" #include "TexCompTypes.h"
#include "PVRTCCompressor.h" #include "PVRTCCompressor.h"
// Forward include
namespace FasTC {
class Pixel;
}
namespace PVRTCC { namespace PVRTCC {
class Pixel; using FasTC::Pixel;
class Image { class Image {
public: public:
Image(uint32 height, uint32 width); Image(uint32 height, uint32 width);

View File

@ -56,7 +56,7 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include)
INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include)
SET(TESTS SET(TESTS
Block Pixel Image Decompressor Block Image Decompressor
) )
FOREACH(TEST ${TESTS}) FOREACH(TEST ${TESTS})

View File

@ -179,7 +179,7 @@ TEST(Image, BilinearUpscaleMaintainsPixels) {
for(uint32 j = 2; j < img.GetHeight(); j+=4) { for(uint32 j = 2; j < img.GetHeight(); j+=4) {
PVRTCC::Pixel p = img(i, j); PVRTCC::Pixel p = img(i, j);
uint32 idx = ((j - 2) / 4) * w + ((i-2)/4); uint32 idx = ((j - 2) / 4) * w + ((i-2)/4);
EXPECT_EQ(PixelPrinter(p.PackRGBA()), PixelPrinter(pxs[idx].PackRGBA())); EXPECT_EQ(PixelPrinter(p.Pack()), PixelPrinter(pxs[idx].Pack()));
} }
} }
} }