From ab598c9ef7f1b26e36ffb0fedb2980e494c187f0 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 3 Oct 2013 17:25:15 -0400 Subject: [PATCH] Move Pixel class from PVRTCEncoder to FasTCBase. --- Base/CMakeLists.txt | 9 + {PVRTCEncoder/src => Base/include}/Pixel.h | 68 +++-- {PVRTCEncoder => Base}/src/Pixel.cpp | 12 +- Base/test/CMakeLists.txt | 66 +++++ .../test/TestARGBPixel.cpp | 58 ++-- Base/test/TestPixel.cpp | 250 ++++++++++++++++++ PVRTCEncoder/CMakeLists.txt | 3 +- PVRTCEncoder/src/Block.h | 1 + PVRTCEncoder/src/Compressor.cpp | 2 +- PVRTCEncoder/src/Decompressor.cpp | 4 +- PVRTCEncoder/src/Image.cpp | 2 +- PVRTCEncoder/src/Image.h | 8 +- PVRTCEncoder/test/CMakeLists.txt | 2 +- PVRTCEncoder/test/ImageTest.cpp | 2 +- 14 files changed, 404 insertions(+), 83 deletions(-) rename {PVRTCEncoder/src => Base/include}/Pixel.h (80%) rename {PVRTCEncoder => Base}/src/Pixel.cpp (96%) create mode 100644 Base/test/CMakeLists.txt rename PVRTCEncoder/test/PixelTest.cpp => Base/test/TestARGBPixel.cpp (80%) create mode 100644 Base/test/TestPixel.cpp diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt index 53fb033..0d43519 100644 --- a/Base/CMakeLists.txt +++ b/Base/CMakeLists.txt @@ -52,12 +52,21 @@ SET( SOURCES "src/Image.cpp" "src/CompressionJob.cpp" + "src/Pixel.cpp" ) SET( HEADERS "include/TexCompTypes.h" "include/Image.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) diff --git a/PVRTCEncoder/src/Pixel.h b/Base/include/Pixel.h similarity index 80% rename from PVRTCEncoder/src/Pixel.h rename to Base/include/Pixel.h index f8821f4..4fa9312 100644 --- a/PVRTCEncoder/src/Pixel.h +++ b/Base/include/Pixel.h @@ -50,27 +50,33 @@ * */ -#ifndef PVRTCENCODER_SRC_PIXEL_H_ -#define PVRTCENCODER_SRC_PIXEL_H_ +#ifndef BASE_INCLUDE_PIXEL_H_ +#define BASE_INCLUDE_PIXEL_H_ #include "TexCompTypes.h" +#include "Vector4.h" -namespace PVRTCC { +namespace FasTC { + +class Pixel : public Vector4 { + private: + uint8 m_BitDepth[4]; -class Pixel { public: - Pixel(): m_A(0), m_R(0), m_G(0), m_B(0) { - for(int i = 0; i < 4; i++) m_BitDepth[i] = 8; + Pixel() : Vector4(0, 0, 0, 0) { + for(int i = 0; i < 4; i++) + m_BitDepth[i] = 8; } - explicit Pixel(uint32 rgba) { - for(int i = 0; i < 4; i++) m_BitDepth[i] = 8; - UnpackRGBA(rgba); + explicit Pixel(uint32 rgba) : Vector4() { + for(int i = 0; i < 4; i++) + m_BitDepth[i] = 8; + Unpack(rgba); } Pixel(const uint8 *bits, const uint8 channelDepth[4] = static_cast(0), - uint8 bitOffset = 0) { + uint8 bitOffset = 0) : Vector4() { FromBits(bits, channelDepth, bitOffset); } @@ -100,16 +106,16 @@ class Pixel { // above for how we do this. static uint8 ChangeBitDepth(uint8 val, uint8 oldDepth, uint8 newDepth); - const uint8 &A() const { return m_A; } - uint8 &A() { return m_A; } - const uint8 &R() const { return m_R; } - uint8 &R() { return m_R; } - const uint8 &G() const { return m_G; } - uint8 &G() { return m_G; } - const uint8 &B() const { return m_B; } - uint8 &B() { return m_B; } - const uint8 &Component(uint32 idx) const { return m_Component[idx]; } - uint8 &Component(uint32 idx) { return m_Component[idx]; } + const uint8 &A() const { return X(); } + uint8 &A() { return X(); } + const uint8 &R() const { return Y(); } + uint8 &R() { return Y(); } + const uint8 &G() const { return Z(); } + uint8 &G() { return Z(); } + const uint8 &B() const { return W(); } + uint8 &B() { return W(); } + const uint8 &Component(uint32 idx) const { return vec[idx]; } + uint8 &Component(uint32 idx) { return vec[idx]; } void GetBitDepth(uint8 (&outDepth)[4]) const { 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 // that the architecture is little-endian, so the alpha channel will end // up in the most-significant byte. - uint32 PackRGBA() const; - void UnpackRGBA(uint32 rgba); + uint32 Pack() const; + void Unpack(uint32 rgba); // Tests for equality by comparing the values and the bit depths. 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_ diff --git a/PVRTCEncoder/src/Pixel.cpp b/Base/src/Pixel.cpp similarity index 96% rename from PVRTCEncoder/src/Pixel.cpp rename to Base/src/Pixel.cpp index 8ea763d..2b047bd 100644 --- a/PVRTCEncoder/src/Pixel.cpp +++ b/Base/src/Pixel.cpp @@ -56,7 +56,7 @@ #include #include -namespace PVRTCC { +namespace FasTC { void Pixel::FromBits(const uint8 *bits, const uint8 channelDepth[4], @@ -82,7 +82,7 @@ namespace PVRTCC { } for(int32 i = 0; i < 4; i++) { - uint8 &channel = m_Component[i]; + uint8 &channel = Component(i); uint32 depth = m_BitDepth[i]; assert(depth <= 8); @@ -185,12 +185,12 @@ namespace PVRTCC { void Pixel::ChangeBitDepth(const uint8 (&depth)[4]) { 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]; } } - uint32 Pixel::PackRGBA() const { + uint32 Pixel::Pack() const { Pixel eightBit(*this); const uint8 eightBitDepth[4] = { 8, 8, 8, 8 }; eightBit.ChangeBitDepth(eightBitDepth); @@ -206,7 +206,7 @@ namespace PVRTCC { return r; } - void Pixel::UnpackRGBA(uint32 rgba) { + void Pixel::Unpack(uint32 rgba) { A() = ChangeBitDepth((rgba >> 24) & 0xFF, 8, m_BitDepth[0]); R() = ChangeBitDepth(rgba & 0xFF, 8, m_BitDepth[1]); G() = ChangeBitDepth((rgba >> 8) & 0xFF, 8, m_BitDepth[2]); @@ -228,4 +228,4 @@ namespace PVRTCC { return ok; } -} // namespace PVRTCC +} // namespace FasTC diff --git a/Base/test/CMakeLists.txt b/Base/test/CMakeLists.txt new file mode 100644 index 0000000..43fb154 --- /dev/null +++ b/Base/test/CMakeLists.txt @@ -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 . +# +# 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 . +# +# 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 +# +# + +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() diff --git a/PVRTCEncoder/test/PixelTest.cpp b/Base/test/TestARGBPixel.cpp similarity index 80% rename from PVRTCEncoder/test/PixelTest.cpp rename to Base/test/TestARGBPixel.cpp index decab5b..b3e2234 100644 --- a/PVRTCEncoder/test/PixelTest.cpp +++ b/Base/test/TestARGBPixel.cpp @@ -54,7 +54,7 @@ #include "Pixel.h" TEST(Pixel, DefaultConstructor) { - PVRTCC::Pixel p; + FasTC::Pixel p; EXPECT_EQ(p.R(), 0); EXPECT_EQ(p.G(), 0); EXPECT_EQ(p.B(), 0); @@ -70,12 +70,12 @@ TEST(Pixel, DefaultConstructor) { TEST(Pixel, FromBitsAndAssociatedConstructor) { const uint8 bits[8] = { 0xA8, 0xB3, 0x7C, 0x21, 0xBD, 0xD4, 0x09, 0x92 }; - PVRTCC::Pixel ps[2]; - ps[0] = PVRTCC::Pixel(bits); + FasTC::Pixel ps[2]; + ps[0] = FasTC::Pixel(bits); ps[1].FromBits(bits); 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.R(), 0xB3); @@ -90,11 +90,11 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) { } 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); 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.R(), 0x00); @@ -112,11 +112,11 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) { 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); 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.R(), 0x3A); @@ -134,7 +134,7 @@ TEST(Pixel, FromBitsAndAssociatedConstructor) { } TEST(Pixel, ToBits) { - PVRTCC::Pixel p; + FasTC::Pixel p; uint8 bitDepth[4] = { 2, 8, 1, 7 }; p.ChangeBitDepth(bitDepth); @@ -163,39 +163,39 @@ TEST(Pixel, ChangeChannelBitDepth) { uint8 val = 0x43; uint8 depth = 7; - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 8), 0x87); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 7), 0x43); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 6), 0x22); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 2), 0x2); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF); + 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(PVRTCC::Pixel::ChangeBitDepth(val, depth, 8), 0x6D); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 6), 0x1B); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 3), 0x03); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 2), 0x02); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 0), 0xFF); + 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(PVRTCC::Pixel::ChangeBitDepth(val, depth, 8), 0xFF); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 7), 0x7F); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 6), 0x3F); - EXPECT_EQ(PVRTCC::Pixel::ChangeBitDepth(val, depth, 2), 0x03); + 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(PVRTCC::Pixel::ChangeBitDepth(val, depth, 0), 0x43); + 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}; - PVRTCC::Pixel p(bits, depth); + FasTC::Pixel p(bits, depth); const uint8 newDepth[4] = { 8, 8, 8, 8 }; p.ChangeBitDepth(newDepth); @@ -216,7 +216,7 @@ TEST(Pixel, ChangePixelBitDepth) { TEST(Pixel, PackRGBA) { const uint8 bits[4] = { 0x86, 0xC0, 0x0, 0x0 }; const uint8 depth[4] = {7, 3, 0, 0}; - PVRTCC::Pixel p(bits, depth); + FasTC::Pixel p(bits, depth); uint32 val = p.PackRGBA(); EXPECT_EQ(val, 0x87FFFF6D); @@ -224,7 +224,7 @@ TEST(Pixel, PackRGBA) { TEST(Pixel, UnpackRGBA) { uint32 rgba = 0x4619B3FE; - PVRTCC::Pixel p; + FasTC::Pixel p; p.UnpackRGBA(rgba); EXPECT_EQ(p.A(), 0x46); @@ -232,13 +232,13 @@ TEST(Pixel, UnpackRGBA) { EXPECT_EQ(p.G(), 0xB3); EXPECT_EQ(p.R(), 0xFE); - p = PVRTCC::Pixel(rgba); + 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 = PVRTCC::Pixel(); + p = FasTC::Pixel(); uint8 newBitDepth[4] = { 3, 5, 2, 1 }; // A R G B p.ChangeBitDepth(newBitDepth); p.UnpackRGBA(rgba); diff --git a/Base/test/TestPixel.cpp b/Base/test/TestPixel.cpp new file mode 100644 index 0000000..0a630b8 --- /dev/null +++ b/Base/test/TestPixel.cpp @@ -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 . + * + * 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 . + * + * 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 + * + * + */ + +#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); +} diff --git a/PVRTCEncoder/CMakeLists.txt b/PVRTCEncoder/CMakeLists.txt index 80ef77c..9c3ff6c 100644 --- a/PVRTCEncoder/CMakeLists.txt +++ b/PVRTCEncoder/CMakeLists.txt @@ -56,7 +56,6 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) SET( HEADERS include/PVRTCCompressor.h - src/Pixel.h src/Block.h src/Image.h ) @@ -64,7 +63,6 @@ SET( HEADERS SET( SOURCES src/Compressor.cpp src/Decompressor.cpp - src/Pixel.cpp src/Block.cpp src/Image.cpp ) @@ -74,5 +72,6 @@ ADD_LIBRARY( PVRTCEncoder ${SOURCES} ) +TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCBase ) TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCCore ) TARGET_LINK_LIBRARIES( PVRTCEncoder FasTCIO ) diff --git a/PVRTCEncoder/src/Block.h b/PVRTCEncoder/src/Block.h index 7404f40..cd5dc91 100644 --- a/PVRTCEncoder/src/Block.h +++ b/PVRTCEncoder/src/Block.h @@ -58,6 +58,7 @@ namespace PVRTCC { +using FasTC::Pixel; class Block { public: Block(): m_LongData(0) { } diff --git a/PVRTCEncoder/src/Compressor.cpp b/PVRTCEncoder/src/Compressor.cpp index 56183b7..7126d6f 100644 --- a/PVRTCEncoder/src/Compressor.cpp +++ b/PVRTCEncoder/src/Compressor.cpp @@ -130,7 +130,7 @@ namespace PVRTCC { uint32 y = i / dcj.width; const uint32 *pixels = reinterpret_cast(dcj.inBuf); - img(x, y).UnpackRGBA(pixels[i]); + img(x, y).Unpack(pixels[i]); } Image original = img; diff --git a/PVRTCEncoder/src/Decompressor.cpp b/PVRTCEncoder/src/Decompressor.cpp index 4365aac..9b7bb5b 100644 --- a/PVRTCEncoder/src/Decompressor.cpp +++ b/PVRTCEncoder/src/Decompressor.cpp @@ -160,7 +160,7 @@ namespace PVRTCC { } uint32 *outPixels = reinterpret_cast(outBuf); - outPixels[(j * w) + i] = result.PackRGBA(); + outPixels[(j * w) + i] = result.Pack(); } } @@ -269,7 +269,7 @@ namespace PVRTCC { } uint32 *outPixels = reinterpret_cast(outBuf); - outPixels[(j * w) + i] = result.PackRGBA(); + outPixels[(j * w) + i] = result.Pack(); } } diff --git a/PVRTCEncoder/src/Image.cpp b/PVRTCEncoder/src/Image.cpp index 0de9335..9ac282f 100644 --- a/PVRTCEncoder/src/Image.cpp +++ b/PVRTCEncoder/src/Image.cpp @@ -476,7 +476,7 @@ void Image::DebugOutput(const char *filename) const { p.ChangeBitDepth(fullDepth); p.A() = 255; - outPixels[idx] = p.PackRGBA(); + outPixels[idx] = p.Pack(); } } diff --git a/PVRTCEncoder/src/Image.h b/PVRTCEncoder/src/Image.h index 959ba4c..33616d3 100644 --- a/PVRTCEncoder/src/Image.h +++ b/PVRTCEncoder/src/Image.h @@ -56,10 +56,14 @@ #include "TexCompTypes.h" #include "PVRTCCompressor.h" +// Forward include +namespace FasTC { + class Pixel; +} + namespace PVRTCC { -class Pixel; - +using FasTC::Pixel; class Image { public: Image(uint32 height, uint32 width); diff --git a/PVRTCEncoder/test/CMakeLists.txt b/PVRTCEncoder/test/CMakeLists.txt index 67a5b20..3f2e1ec 100644 --- a/PVRTCEncoder/test/CMakeLists.txt +++ b/PVRTCEncoder/test/CMakeLists.txt @@ -56,7 +56,7 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS - Block Pixel Image Decompressor + Block Image Decompressor ) FOREACH(TEST ${TESTS}) diff --git a/PVRTCEncoder/test/ImageTest.cpp b/PVRTCEncoder/test/ImageTest.cpp index 527e530..ead8ba4 100644 --- a/PVRTCEncoder/test/ImageTest.cpp +++ b/PVRTCEncoder/test/ImageTest.cpp @@ -179,7 +179,7 @@ TEST(Image, BilinearUpscaleMaintainsPixels) { for(uint32 j = 2; j < img.GetHeight(); j+=4) { PVRTCC::Pixel p = img(i, j); 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())); } } }