diff --git a/BPTCEncoder/CMakeLists.txt b/BPTCEncoder/CMakeLists.txt index 03c3758..05f3e19 100644 --- a/BPTCEncoder/CMakeLists.txt +++ b/BPTCEncoder/CMakeLists.txt @@ -41,6 +41,7 @@ # INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/BPTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/BPTCEncoder/include) diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt index e61bcf5..ebdb4c3 100644 --- a/Base/CMakeLists.txt +++ b/Base/CMakeLists.txt @@ -49,6 +49,28 @@ # # +INCLUDE(CheckCXXSourceCompiles) +CHECK_CXX_SOURCE_COMPILES(" + #include + int main() { + int8_t x8 = 0; + int16_t x16 = 1; + int32_t x32 = 2; + int64_t x64 = 3; + uint8_t ux8 = 0; + uint16_t ux16 = 1; + uint32_t ux32 = 2; + uint64_t ux64 = 3; + return (x8 | ux8 | x16 | ux16 | x32 | ux32 | x64 | ux64); + }" + FASTC_BASE_HAS_CPP11_TYPES +) + +CONFIGURE_FILE( + "config/FasTCBaseConfig.h.in" + "include/FasTCBaseConfig.h" +) + SET( SOURCES "src/Image.cpp" "src/CompressionJob.cpp" @@ -61,6 +83,7 @@ SET( HEADERS "include/BitStream.h" "include/Color.h" "include/CompressionJob.h" + "config/FasTCBaseConfig.h.in" "include/IPixel.h" "include/Image.h" "include/MatrixBase.h" @@ -76,6 +99,7 @@ SET( HEADERS ) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) ADD_LIBRARY( FasTCBase ${HEADERS} diff --git a/Base/config/FasTCBaseConfig.h.in b/Base/config/FasTCBaseConfig.h.in new file mode 100644 index 0000000..b39ac46 --- /dev/null +++ b/Base/config/FasTCBaseConfig.h.in @@ -0,0 +1,54 @@ +/* FasTC + * Copyright (c) 2014 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 + * + * + */ + +// Does our compiler support cpp11 types? +#cmakedefine FASTC_BASE_HAS_CPP11_TYPES diff --git a/Base/include/Image.h b/Base/include/Image.h index f7b97fc..1cddb8b 100644 --- a/Base/include/Image.h +++ b/Base/include/Image.h @@ -87,8 +87,8 @@ namespace FasTC { template void ConvertTo(Image &other) const { - for(uint32 j = 0; j < other.GetWidth(); j++) { - for(uint32 i = 0; i < other.GetHeight(); i++) { + for(uint32 j = 0; j < other.GetHeight(); j++) { + for(uint32 i = 0; i < other.GetWidth(); i++) { other(i, j).Unpack((*this)(i, j).Pack()); } } diff --git a/Base/include/Matrix2x2.h b/Base/include/Matrix2x2.h new file mode 100644 index 0000000..25afd20 --- /dev/null +++ b/Base/include/Matrix2x2.h @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Pavel Krajcevski + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + ******************************************************************************/ + +#ifndef BASE_INCLUDE_MATRIX2X2_H_ +#define BASE_INCLUDE_MATRIX2X2_H_ + +#include "MatrixSquare.h" + +namespace FasTC { + + template + class Matrix2x2 : public MatrixSquare { + public: + // Constructors + Matrix2x2() { } + Matrix2x2(const Matrix2x2 &other) + : MatrixSquare(other) { } + Matrix2x2(const MatrixSquare &other) + : MatrixSquare(other) { } + Matrix2x2(const MatrixBase &other) + : MatrixSquare(other) { } + }; + REGISTER_ONE_TEMPLATE_MATRIX_TYPE(Matrix2x2); +}; + +#endif // BASE_INCLUDE_MATRIX2X2_H_ diff --git a/Base/include/Matrix3x3.h b/Base/include/Matrix3x3.h index b5d226b..60edf73 100644 --- a/Base/include/Matrix3x3.h +++ b/Base/include/Matrix3x3.h @@ -31,17 +31,17 @@ namespace FasTC { template class Matrix3x3 : public MatrixSquare { - public: - // Constructors Matrix3x3() { } - Matrix3x3(const MatrixSquare &other) { - for(int i = 0; i < kNumElements; i++) { - mat[i] = other[i]; - } - } + Matrix3x3(const Matrix3x3 &other) + : MatrixSquare(other) { } + Matrix3x3(const MatrixSquare &other) + : MatrixSquare(other) { } + Matrix3x3(const MatrixBase &other) + : MatrixSquare(other) { } }; + REGISTER_ONE_TEMPLATE_MATRIX_TYPE(Matrix3x3); }; #endif // BASE_INCLUDE_MATRIX3X3_H_ diff --git a/Base/include/Matrix4x4.h b/Base/include/Matrix4x4.h new file mode 100644 index 0000000..5fe18ee --- /dev/null +++ b/Base/include/Matrix4x4.h @@ -0,0 +1,75 @@ +/* FasTC + * Copyright (c) 2014 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 + * + * + */ + +#ifndef BASE_INCLUDE_MATRIX4X4_H_ +#define BASE_INCLUDE_MATRIX4X4_H_ + +#include "MatrixSquare.h" + +namespace FasTC { + + template + class Matrix4x4 : public MatrixSquare { + public: + // Constructors + Matrix4x4() { } + Matrix4x4(const Matrix4x4 &other) + : MatrixSquare(other) { } + Matrix4x4(const MatrixSquare &other) + : MatrixSquare(other) { } + Matrix4x4(const MatrixBase &other) + : MatrixSquare(other) { } + }; + REGISTER_ONE_TEMPLATE_MATRIX_TYPE(Matrix4x4); +}; + +#endif // BASE_INCLUDE_MATRIX3X3_H_ diff --git a/Base/include/MatrixBase.h b/Base/include/MatrixBase.h index 3182b4b..94d8aa2 100644 --- a/Base/include/MatrixBase.h +++ b/Base/include/MatrixBase.h @@ -34,100 +34,52 @@ namespace FasTC { protected: // Vector representation - static const int kNumElements = nRows * nCols; - T mat[kNumElements]; + T mat[nRows * nCols]; public: - + typedef T ScalarType; + static const int kNumRows = nRows; + static const int kNumCols = nCols; + static const int Size = kNumCols * kNumRows; + // Constructors MatrixBase() { } MatrixBase(const MatrixBase &other) { - for(int i = 0; i < kNumElements; i++) { - mat[i] = other[i]; + for(int i = 0; i < Size; i++) { + (*this)[i] = other[i]; } } // Accessors T &operator()(int idx) { return mat[idx]; } - const T &operator()(int idx) const { return mat[idx]; } - T &operator()(int r, int c) { return mat[r * nCols + c]; } - const T &operator() const (int r, int c) { return mat[r * nCols + c]; } - T &operator[](int idx) { return mat[idx]; } + const T &operator()(int idx) const { return mat[idx]; } const T &operator[](int idx) const { return mat[idx]; } - // Operators - template - MatrixBase operator+(const MatrixBase<_T, nRows, nCols> &m) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] + m[i]; - } - return a; - } + T &operator()(int r, int c) { return (*this)[r * nCols + c]; } + const T &operator() (int r, int c) const { return (*this)[r * nCols + c]; } - template - MatrixBase &operator+=(const MatrixBase<_T, nRows, nCols> &m) { - for(int i = 0; i < kNumElements; i++) { - mat[i] += m[i]; - } + // Allow casts to the respective array representation... + operator const T *() const { return this->mat; } + MatrixBase &operator=(const T *v) { + for(int i = 0; i < Size; i++) + (*this)[i] = v[i]; return *this; } + // Allows casting to other vector types if the underlying type system does as well... template - MatrixBase operator-(const MatrixBase<_T, nRows, nCols> &m) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] - m[i]; + operator MatrixBase<_T, nRows, nCols>() const { + MatrixBase<_T, nRows, nCols> ret; + for(int i = 0; i < Size; i++) { + ret[i] = static_cast<_T>(mat[i]); } - return a; - } - - template - MatrixBase &operator-=(const MatrixBase<_T, nRows, nCols> &m) { - for(int i = 0; i < kNumElements; i++) { - mat[i] -= m[i]; - } - return *this; - } - - template - MatrixBase operator*(_T s) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] * s; - } - return a; - } - - template - MatrixBase &operator*=(_T s) { - for(int i = 0; i < kNumElements; i++) { - mat[i] *= s; - } - return *this; - } - - template - MatrixBase operator/(_T s) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] / s; - } - return a; - } - - template - MatrixBase &operator/=(_T s) { - for(int i = 0; i < kNumElements; i++) { - mat[i] /= s; - } - return *this; + return ret; } // Matrix multiplication template - MatrixBase operator*(const MatrixBase<_T, nCols, nTarget> &m) { + MatrixBase MultiplyMatrix(const MatrixBase<_T, nCols, nTarget> &m) const { MatrixBase result; for(int r = 0; r < nRows; r++) for(int c = 0; c < nTarget; c++) { @@ -141,8 +93,20 @@ namespace FasTC { // Vector multiplication -- treat vectors as Nx1 matrices... template - VectorBase operator*(const VectorBase<_T, nCols> &v) { + VectorBase MultiplyVectorLeft(const VectorBase<_T, nRows> &v) const { VectorBase result; + for(int j = 0; j < nCols; j++) { + result(j) = 0; + for(int r = 0; r < nRows; r++) { + result(j) += (*this)(r, j) * v(r); + } + } + return result; + } + + template + VectorBase MultiplyVectorRight(const VectorBase<_T, nCols> &v) const { + VectorBase result; for(int r = 0; r < nRows; r++) { result(r) = 0; for(int j = 0; j < nCols; j++) { @@ -152,40 +116,133 @@ namespace FasTC { return result; } - // Outer product... - template - friend MatrixBase<_T, N, M> operator^( - const VectorBase<_T, N> &a, - const VectorBase<_U, M> &b - ) { - MatrixBase<_T, N, M> result; - - for(int i = 0; i < N; i++) - for(int j = 0; j < M; j++) - result(i, j) = a[i] * b[j]; - - return result; - } - - template - friend MatrixBase<_T, N, M> OuterProduct( - const VectorBase<_T, N> &a, - const VectorBase<_U, M> &b - ) { - return a ^ b; - } - - // Double dot product - template - T DDot(const MatrixBase<_T, nRows, nCols> &m) { - T result = 0; - for(int i = 0; i < kNumElements; i++) { - result += mat[i] * m[i]; + // Transposition + MatrixBase Transpose() const { + MatrixBase result; + for(int r = 0; r < nRows; r++) { + for(int c = 0; c < nCols; c++) { + result(c, r) = (*this)(r, c); + } } return result; } + // Double dot product + template + T DDot(const MatrixBase<_T, nRows, nCols> &m) const { + T result = 0; + for(int i = 0; i < Size; i++) { + result += (*this)[i] * m[i]; + } + return result; + } }; + + template + class VectorTraits > { + public: + static const EVectorType kVectorType = eVectorType_Matrix; + }; + + #define REGISTER_MATRIX_TYPE(TYPE) \ + template<> \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Matrix; \ + } + + #define REGISTER_ONE_TEMPLATE_MATRIX_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Matrix; \ + } + + #define REGISTER_ONE_TEMPLATE_MATRIX_SIZED_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Matrix; \ + } + + // Define matrix multiplication for * operator + template + class MultSwitch< + eVectorType_Matrix, + eVectorType_Vector, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef VectorBase ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_A.MultiplyVectorRight(m_B); } + }; + + template + class MultSwitch< + eVectorType_Vector, + eVectorType_Matrix, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef VectorBase ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_B.MultiplyVectorLeft(m_A); } + }; + + template + class MultSwitch< + eVectorType_Matrix, + eVectorType_Matrix, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef MatrixBase ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_A.MultiplyMatrix(m_B); } + }; + + // Outer product... + template + MatrixBase<_T, N, M> operator^( + const VectorBase<_T, N> &a, + const VectorBase<_U, M> &b + ) { + MatrixBase<_T, N, M> result; + + for(int i = 0; i < N; i++) + for(int j = 0; j < M; j++) + result(i, j) = a[i] * b[j]; + + return result; + } + + template + MatrixBase<_T, N, M> OuterProduct( + const VectorBase<_T, N> &a, + const VectorBase<_U, M> &b + ) { + return a ^ b; + } + }; #endif // BASE_INCLUDE_MATRIXBASE_H_ diff --git a/Base/include/MatrixSquare.h b/Base/include/MatrixSquare.h index 7fdfb48..df887b0 100644 --- a/Base/include/MatrixSquare.h +++ b/Base/include/MatrixSquare.h @@ -26,6 +26,8 @@ #define BASE_INCLUDE_MATRIXSQUARE_H_ #include "MatrixBase.h" +#include +#include namespace FasTC { @@ -35,12 +37,87 @@ namespace FasTC { // Constructors MatrixSquare() { } - MatrixSquare(const MatrixBase &other) { - for(int i = 0; i < kNumElements; i++) { - mat[i] = other[i]; - } + MatrixSquare(const MatrixSquare &other) + : MatrixBase(other) { } + MatrixSquare(const MatrixBase &other) + : MatrixBase(other) { } + + MatrixSquare Transpose() const { + return MatrixBase::Transpose(); } + + // Does power iteration to determine the principal eigenvector and eigenvalue. + // Returns them in eigVec and eigVal after kMaxNumIterations + int PowerMethod(VectorBase &eigVec, + T *eigVal = NULL, + const int kMaxNumIterations = 200, + const unsigned int kSeed = time(NULL)) { + + srand(kSeed); + int numIterations = 0; + + VectorBase b; + for(int i = 0; i < N; i++) + b[i] = static_cast(rand()); + b.Normalize(); + + bool badEigenValue = false; + bool fixed = false; + numIterations = 0; + while(!fixed && ++numIterations < kMaxNumIterations) { + + VectorBase newB = (*this) * b; + + // !HACK! If the principal eigenvector of the matrix + // converges to zero, that could mean that there is no + // principal eigenvector. However, that may be due to + // poor initialization of the random vector, so rerandomize + // and try again. + const float newBlen = newB.Length(); + if(newBlen < 1e-10) { + if(badEigenValue) { + eigVec = b; + if(eigVal) *eigVal = 0.0; + return numIterations; + } + + VectorBase b; + for(int i = 0; i < N; i++) + b[i] = static_cast(rand()); + + b.Normalize(); + badEigenValue = true; + } + + // Normalize + newB.Normalize(); + + // If the new eigenvector is close enough to the old one, + // then we've converged. + if(fabs(1.0f - (b.Dot(newB))) < 1e-8) + fixed = true; + + // Save and continue. + b = newB; + } + + // Store the eigenvector in the proper variable. + eigVec = b; + + // Store eigenvalue if it was requested + if(eigVal) { + VectorBase result = (*this) * b; + *eigVal = result.Length() / b.Length(); + } + + return numIterations; + } + + private: + }; + REGISTER_ONE_TEMPLATE_MATRIX_SIZED_TYPE(MatrixSquare); + }; #endif // BASE_INCLUDE_MATRIXSQUARE_H_ diff --git a/Base/include/Pixel.h b/Base/include/Pixel.h index 54555c9..2f02b64 100644 --- a/Base/include/Pixel.h +++ b/Base/include/Pixel.h @@ -59,7 +59,7 @@ namespace FasTC { class Pixel : public Vector4 { - private: + protected: typedef uint16 ChannelType; typedef Vector4 VectorType; uint8 m_BitDepth[4]; @@ -143,45 +143,43 @@ class Pixel : public Vector4 { uint32 Pack() const; void Unpack(uint32 rgba); + // Shuffles the pixel values around so that they change their ordering based + // on the passed mask. The values are chosen such that each two bits from the + // least significant bit define a value from 0-3. From LSB to MSB, the values + // are labelled a, b, c, d. From these labels, we store: + // m_Pixels[0] = m_Pixels[a] + // m_Pixels[1] = m_Pixels[b] + // m_Pixels[2] = m_Pixels[c] + // m_Pixels[3] = m_Pixels[d] + // hence, 0xE4 (11 10 01 00) represents a no-op. + void Shuffle(uint8 shuffleMask = 0xE4); + // Tests for equality by comparing the values and the bit depths. bool operator==(const Pixel &) const; }; REGISTER_VECTOR_TYPE(Pixel); -// Overload operators so that we can preserve bit depths... -template -static inline Pixel ScalarMultiply(const Pixel &p, const ScalarType &s) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) - a(i) = p(i) * s; - return a; -} +class YCoCgPixel : public Pixel { + private: + void ToYCoCg(); -template -static inline Pixel ScalarDivide(const Pixel &p, const ScalarType &s) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) - a(i) = p(i) / s; - return a; -} + public: + YCoCgPixel() : Pixel() { } + explicit YCoCgPixel(uint32 rgba) : Pixel(rgba) { ToYCoCg(); } + explicit YCoCgPixel(const Pixel &p) : Pixel(p) { ToYCoCg(); } -template -static inline Pixel VectorAddition(const Pixel &p, const VectorType &v) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) { - a(i) += v(i); - } - return a; -} + Pixel ToRGBA() const; -template -static inline Pixel VectorSubtraction(const Pixel &p, const VectorType &v) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) { - a(i) -= v(i); - } - return a; -} + float ToIntensity() const { return ConvertChannelToFloat(R(), 8); } + uint32 Pack() const { return ToRGBA().Pack(); } + void Unpack(uint32 rgba) { Pixel::Unpack(rgba); ToYCoCg(); } + + const ChannelType &Co() const { return Z(); } + ChannelType &Co() { return Z(); } + const ChannelType &Cg() const { return W(); } + ChannelType &Cg() { return W(); } +}; +REGISTER_VECTOR_TYPE(YCoCgPixel); } // namespace FasTC diff --git a/Base/include/TexCompTypes.h b/Base/include/TexCompTypes.h index 5290b41..779c91b 100644 --- a/Base/include/TexCompTypes.h +++ b/Base/include/TexCompTypes.h @@ -1,30 +1,39 @@ /* FasTC - * Copyright (c) 2012 University of North Carolina at Chapel Hill. All rights reserved. + * Copyright (c) 2014 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 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 . + * 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. + * 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. + * 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, + * 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 . @@ -48,6 +57,28 @@ #ifndef _TEX_COMP_TYPES_H_ #define _TEX_COMP_TYPES_H_ +#include "FasTCBaseConfig.h" + +// Do we support C++11? +#ifdef FASTC_BASE_HAS_CPP11_TYPES +#include + +typedef int8_t int8; +typedef uint8_t uint8; + +typedef int16_t int16; +typedef uint16_t uint16; + +typedef int32_t int32; +typedef uint32_t uint32; + +typedef int64_t int64; +typedef uint64_t uint64; + +typedef char CHAR; + +#else + // Windows? #ifdef _MSC_VER @@ -83,4 +114,6 @@ typedef char CHAR; #endif // _MSC_VER +#endif // FASTC_BASE_HAS_CPP11_TYPES + #endif // _TEX_COMP_TYPES_H_ diff --git a/Base/include/Vector2.h b/Base/include/Vector2.h index 52bce4b..09f4be3 100644 --- a/Base/include/Vector2.h +++ b/Base/include/Vector2.h @@ -27,10 +27,8 @@ #include "VectorBase.h" -#ifdef _VEX_ENABLE_SWIZZLE_ # define _VEX_VEC2_SWIZZLE_DEF(X, Y) \ Vector2 X##Y() const { return Vector2( X(), Y() ); } -#endif // _VEX_ENABLE_SWIZZLE_ namespace FasTC { @@ -46,6 +44,11 @@ namespace FasTC { Y() = y; } + explicit Vector2(const T *_vec) { + for(int i = 0; i < 2; i++) + this->vec[i] = _vec[i]; + } + // Overloaded functions template Vector2(const Vector2<_T> &v) : VectorBase(v) { } @@ -56,6 +59,11 @@ namespace FasTC { return *this; } + Vector2 &operator=(const T *_vec) { + VectorBase::operator=(_vec); + return *this; + } + // Accessors T &X() { return (*this)[0]; } const T &X() const { return (*this)[0]; } @@ -64,12 +72,10 @@ namespace FasTC { const T &Y() const { return (*this)[1]; } // Swizzle - #ifdef _VEX_ENABLE_SWIZZLE_ _VEX_VEC2_SWIZZLE_DEF(X, X) _VEX_VEC2_SWIZZLE_DEF(X, Y) _VEX_VEC2_SWIZZLE_DEF(Y, X) _VEX_VEC2_SWIZZLE_DEF(Y, Y) - #endif //_VEX_ENABLE_SWIZZLE_ }; REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector2); diff --git a/Base/include/Vector3.h b/Base/include/Vector3.h index 02de606..2b6f950 100644 --- a/Base/include/Vector3.h +++ b/Base/include/Vector3.h @@ -27,10 +27,8 @@ #include "Vector2.h" -#ifdef _VEX_ENABLE_SWIZZLE_ # define _VEX_VEC3_SWIZZLE_DEF(X, Y, Z) \ Vector3 X##Y##Z() const { return Vector3( X(), Y(), Z() ); } -#endif // _VEX_ENABLE_SWIZZLE_ namespace FasTC { @@ -43,6 +41,12 @@ namespace FasTC { Y() = y; Z() = z; } + + explicit Vector3(const T *_vec) { + for(int i = 0; i < 3; i++) { + this->vec[i] = _vec[i]; + } + } // Overloaded functions template @@ -54,6 +58,12 @@ namespace FasTC { return *this; } + template + Vector3 &operator=(const _T *v) { + VectorBase::operator=(v); + return *this; + } + // Accessors T &X() { return (*this)[0]; } const T &X() const { return (*this)[0]; } @@ -75,7 +85,6 @@ namespace FasTC { } // Swizzle - #ifdef _VEX_ENABLE_SWIZZLE_ _VEX_VEC2_SWIZZLE_DEF(X, X) _VEX_VEC2_SWIZZLE_DEF(X, Y) _VEX_VEC2_SWIZZLE_DEF(X, Z) @@ -113,7 +122,6 @@ namespace FasTC { _VEX_VEC3_SWIZZLE_DEF(Z, Z, X) _VEX_VEC3_SWIZZLE_DEF(Z, Z, Y) _VEX_VEC3_SWIZZLE_DEF(Z, Z, Z) - #endif // _VEX_ENABLE_SWIZZLE_ }; REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector3); diff --git a/Base/include/Vector4.h b/Base/include/Vector4.h index bf5311d..5f0dbbc 100644 --- a/Base/include/Vector4.h +++ b/Base/include/Vector4.h @@ -28,10 +28,8 @@ #include "TexCompTypes.h" #include "Vector3.h" -#ifdef _VEX_ENABLE_SWIZZLE_ #define _VEX_VEC4_SWIZZLE_DEF(X, Y, Z, W) \ Vector4 X##Y##Z##W() const { return Vector4( X(), Y(), Z(), W() ); } -#endif // _VEX_ENABLE_SWIZZLE_ namespace FasTC { @@ -45,6 +43,12 @@ namespace FasTC { Z() = z; W() = w; } + + explicit Vector4(const T *_vec) { + for(int i = 0; i < 4; i++) { + this->vec[i] = _vec[i]; + } + } // Overloaded functions template @@ -56,6 +60,12 @@ namespace FasTC { return *this; } + template + Vector4 &operator=(const _T *v) { + VectorBase::operator=(v); + return *this; + } + // Accessors T &X() { return (*this)[0]; } const T &X() const { return (*this)[0]; } @@ -70,7 +80,6 @@ namespace FasTC { const T &W() const { return (*this)[3]; } // Swizzle - #ifdef _VEX_ENABLE_SWIZZLE_ _VEX_VEC2_SWIZZLE_DEF(X, X) _VEX_VEC2_SWIZZLE_DEF(X, Y) _VEX_VEC2_SWIZZLE_DEF(X, Z) @@ -409,7 +418,6 @@ namespace FasTC { _VEX_VEC4_SWIZZLE_DEF(W, W, W, Y) _VEX_VEC4_SWIZZLE_DEF(W, W, W, Z) _VEX_VEC4_SWIZZLE_DEF(W, W, W, W) - #endif // _VEX_ENABLE_SWIZZLE_ }; REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector4); diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index dc78d01..e313b90 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -31,6 +31,12 @@ namespace FasTC { + enum EVectorType { + eVectorType_Scalar, + eVectorType_Vector, + eVectorType_Matrix + }; + template class VectorBase { protected: @@ -46,7 +52,7 @@ namespace FasTC { for(int i = 0; i < N; i++) vec[i] = other[i]; } - explicit VectorBase(T *_vec) { + explicit VectorBase(const T *_vec) { for(int i = 0; i < N; i++) { vec[i] = _vec[i]; } @@ -61,7 +67,7 @@ namespace FasTC { const T &operator[](int idx) const { return vec[idx]; } // Allow casts to the respective array representation... - operator T *() const { return vec; } + operator const T *() const { return vec; } VectorBase &operator=(const T *v) { for(int i = 0; i < N; i++) vec[i] = v[i]; @@ -71,7 +77,11 @@ namespace FasTC { // Allows casting to other vector types if the underlying type system does as well... template operator VectorBase<_T, N>() const { - return VectorBase<_T, N>(vec); + VectorBase<_T, N> ret; + for(int i = 0; i < N; i++) { + ret[i] = static_cast<_T>(vec[i]); + } + return ret; } // Vector operations @@ -85,15 +95,22 @@ namespace FasTC { T LengthSq() const { return this->Dot(*this); } T Length() const { return sqrt(LengthSq()); } + + void Normalize() { + T len = Length(); + for(int i = 0; i < N; i++) { + vec[i] /= len; + } + } }; // Operators template static inline VectorTypeOne VectorAddition(const VectorTypeOne &v1, const VectorTypeTwo &v2) { - VectorTypeOne a; + VectorTypeOne a(v1); for(int i = 0; i < VectorTypeOne::Size; i++) { - a(i) = v1(i) + v2(i); + a(i) += v2[i]; } return a; } @@ -113,9 +130,9 @@ namespace FasTC { template static inline VectorTypeOne VectorSubtraction(const VectorTypeOne &v1, const VectorTypeTwo &v2) { - VectorTypeOne a; + VectorTypeOne a(v1); for(int i = 0; i < VectorTypeOne::Size; i++) { - a(i) = v1(i) - v2(i); + a(i) -= v2[i]; } return a; } @@ -135,99 +152,141 @@ namespace FasTC { template class VectorTraits { public: - static const bool IsVector = false; + static const EVectorType kVectorType = eVectorType_Scalar; }; template class VectorTraits > { public: - static const bool IsVector = true; + static const EVectorType kVectorType = eVectorType_Vector; }; - #define REGISTER_VECTOR_TYPE(TYPE) \ - template<> \ - class VectorTraits< TYPE > { \ - public: \ - static const bool IsVector = true; \ + #define REGISTER_VECTOR_TYPE(TYPE) \ + template<> \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Vector; \ } - #define REGISTER_ONE_TEMPLATE_VECTOR_TYPE(TYPE) \ - template \ - class VectorTraits< TYPE > { \ - public: \ - static const bool IsVector = true; \ + #define REGISTER_ONE_TEMPLATE_VECTOR_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Vector; \ } - template - class VectorSwitch { - private: - const TypeOne &m_A; - const TypeTwo &m_B; - public: - typedef TypeOne VectorType; - typedef TypeTwo ScalarType; - - VectorSwitch(const TypeOne &a, const TypeTwo &b) - : m_A(a), m_B(b) { } - - const TypeOne &GetVector() { return m_A; } - const TypeTwo &GetScalar() { return m_B; } - }; - - template - class VectorSwitch { - private: - const TypeOne &m_A; - const TypeTwo &m_B; - - public: - typedef TypeTwo VectorType; - typedef TypeOne ScalarType; - - VectorSwitch(const TypeOne &a, const TypeTwo &b) - : m_A(a), m_B(b) { } - - const TypeOne &GetVector() { return m_B; } - const TypeTwo &GetScalar() { return m_A; } - }; - template static inline VectorType ScalarMultiply(const VectorType &v, const ScalarType &s) { - VectorType a; + VectorType a(v); for(int i = 0; i < VectorType::Size; i++) - a(i) = static_cast(v(i) * s); + a(i) = static_cast(a(i) * s); return a; } + template< + EVectorType kVectorTypeOne, + EVectorType kVectorTypeTwo, + typename TypeOne, + typename TypeTwo> + class MultSwitch { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + public: + typedef TypeOne ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_A * m_B; } + }; + + template + class MultSwitch< + eVectorType_Scalar, + eVectorType_Vector, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef TypeTwo ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return ScalarMultiply(m_B, m_A); } + }; + + template + class MultSwitch< + eVectorType_Vector, + eVectorType_Scalar, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef TypeOne ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return ScalarMultiply(m_A, m_B); } + }; + + template + class MultSwitch< + eVectorType_Vector, + eVectorType_Vector, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef typename TypeOne::ScalarType ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_A.Dot(m_B); } + }; + template static inline - typename VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo >::VectorType + typename MultSwitch< + VectorTraits::kVectorType, + VectorTraits::kVectorType, + TypeOne, TypeTwo + >::ResultType operator*(const TypeOne &v1, const TypeTwo &v2) { - typedef VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo > VSwitch; - VSwitch s(v1, v2); - return ScalarMultiply(s.GetVector(), s.GetScalar()); - } - - template - static inline VectorType ScalarDivide(const VectorType &v, const ScalarType &s) { - VectorType a; - for(int i = 0; i < VectorType::Size; i++) - a(i) = static_cast(v(i) / s); - return a; - } - - template - static inline - typename VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo >::VectorType - operator/(const TypeOne &v1, const TypeTwo &v2) { - typedef VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo > VSwitch; - VSwitch s(v1, v2); - return ScalarDivide(s.GetVector(), s.GetScalar()); + typedef MultSwitch< + VectorTraits::kVectorType, + VectorTraits::kVectorType, + TypeOne, TypeTwo + > VSwitch; + return VSwitch(v1, v2).GetMultiplication(); } template static inline VectorType &operator*=(VectorType &v, const ScalarType &s) { - return v = ScalarMultiply(v, s); + return v = v * s; + } + + template + static inline VectorType ScalarDivide(const VectorType &v, const ScalarType &s) { + VectorType a(v); + for(int i = 0; i < VectorType::Size; i++) + a(i) = static_cast(a(i) / s); + return a; + } + + template + static inline TypeOne operator/(const TypeOne &v1, const TypeTwo &v2) { + return ScalarDivide(v1, v2); } template diff --git a/Base/src/Pixel.cpp b/Base/src/Pixel.cpp index 01582ef..7806292 100644 --- a/Base/src/Pixel.cpp +++ b/Base/src/Pixel.cpp @@ -56,6 +56,11 @@ #include #include +template +static inline T Clamp(const T &v, const T &_min, const T &_max) { + return std::max(_min, std::min(v, _max)); +} + namespace FasTC { void Pixel::FromBits(const uint8 *bits, @@ -222,6 +227,29 @@ namespace FasTC { B() = ChangeBitDepth((rgba >> 16) & 0xFF, 8, m_BitDepth[3]); } + void Pixel::Shuffle(uint8 shuffleMask) { + Pixel thisPixel(*this); + uint8 a = shuffleMask & 3; + uint8 b = (shuffleMask >> 2) & 3; + uint8 c = (shuffleMask >> 4) & 3; + uint8 d = (shuffleMask >> 6) & 3; + + Pixel tmp; + tmp[0] = thisPixel[a]; + tmp.m_BitDepth[0] = thisPixel.m_BitDepth[a]; + + tmp[1] = thisPixel[b]; + tmp.m_BitDepth[1] = thisPixel.m_BitDepth[b]; + + tmp[2] = thisPixel[c]; + tmp.m_BitDepth[2] = thisPixel.m_BitDepth[c]; + + tmp[3] = thisPixel[d]; + tmp.m_BitDepth[3] = thisPixel.m_BitDepth[d]; + + *this = tmp; + } + bool Pixel::operator==(const Pixel &other) const { uint8 depths[4]; other.GetBitDepth(depths); @@ -237,4 +265,30 @@ namespace FasTC { return ok; } + void YCoCgPixel::ToYCoCg() { + int16 Y = ((R() + (G() << 1) + B()) + 2) >> 2; + int16 Co = (R() - B() + 1) >> 1; + int16 Cg = ((-R() + (G() << 1) - B()) + 2) >> 2; + + this->Y() = Clamp(Y, 0, 255); + this->Co() = Clamp(Co + 128, 0, 255); + this->Cg() = Clamp(Cg + 128, 0, 255); + } + + Pixel YCoCgPixel::ToRGBA() const { + int16 Co = this->Co() - 128; + int16 Cg = this->Cg() - 128; + + int16 R = Y() + (Co - Cg); + int16 G = Y() + Cg; + int16 B = Y() - (Co + Cg); + + Pixel p; + p.R() = Clamp(R, 0, 255); + p.G() = Clamp(G, 0, 255); + p.B() = Clamp(B, 0, 255); + p.A() = A(); + return p; + } + } // namespace FasTC diff --git a/Base/test/CMakeLists.txt b/Base/test/CMakeLists.txt index ff349c8..25deb87 100644 --- a/Base/test/CMakeLists.txt +++ b/Base/test/CMakeLists.txt @@ -49,11 +49,13 @@ # # -INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include ) + INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS - Pixel Image Color + Vector Matrix Pixel Image Color ) FOREACH(TEST ${TESTS}) @@ -66,6 +68,20 @@ FOREACH(TEST ${TESTS}) ENDIF() ADD_EXECUTABLE(${TEST_NAME} ${TEST_MODULE}) + + # Vector tests need to use uninitialized variables + IF((${TEST_NAME} STREQUAL "Test_Base_Vector") + OR + (${TEST_NAME} STREQUAL "Test_Base_Matrix")) + IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) + SET_TARGET_PROPERTIES( + ${TEST_NAME} + PROPERTIES + COMPILE_FLAGS + "-Wno-uninitialized") + ENDIF() + ENDIF() + TARGET_LINK_LIBRARIES(${TEST_NAME} FasTCBase) TARGET_LINK_LIBRARIES(${TEST_NAME} gtest_main) ADD_TEST(${TEST_NAME} ${TEST_NAME}) diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp new file mode 100644 index 0000000..55a4aa9 --- /dev/null +++ b/Base/test/TestMatrix.cpp @@ -0,0 +1,340 @@ +/* FasTC + * Copyright (c) 2014 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 "MatrixBase.h" + +static const float kEpsilon = 1e-6; + +TEST(MatrixBase, Constructors) { + FasTC::MatrixBase m3f; + FasTC::MatrixBase m1d; + FasTC::MatrixBase m7i; + FasTC::MatrixBase m16u; + +#define TEST_VECTOR_COPY_CONS(mat, t, n, m) \ + do { \ + FasTC::MatrixBase d##mat (mat); \ + for(int i = 0; i < n*m; i++) { \ + EXPECT_EQ(d##mat [i], mat[i]); \ + } \ + } while(0) \ + + TEST_VECTOR_COPY_CONS(m3f, float, 3, 4); + TEST_VECTOR_COPY_CONS(m1d, double, 1, 1); + TEST_VECTOR_COPY_CONS(m7i, int, 7, 200); + TEST_VECTOR_COPY_CONS(m16u, unsigned, 16, 16); + +#undef TEST_VECTOR_COPY_CONS +} + +TEST(MatrixBase, Accessors) { + FasTC::MatrixBase v3f; + v3f[0] = 1.0f; + v3f[1] = -2.3f; + v3f[2] = 1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], v3f(i)); + } + + v3f(0) = -1.0f; + v3f(1) = 2.3f; + v3f(2) = -1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f(i), v3f[i]); + } +} + +TEST(MatrixBase, PointerConversion) { + FasTC::MatrixBase v3f; + v3f(0,0) = 1.0f; + v3f(0,1) = -2.3f; + v3f(0,2) = 1000.0f; + v3f(1,0) = 1.0f; + v3f(1,1) = -2.3f; + v3f(1,2) = 1000.0f; + + float cmp[6] = { 1.0f, -2.3f, 1000.0f, 1.0f, -2.3f, 1000.0f }; + const float *v3fp = v3f; + int result = memcmp(cmp, v3fp, 6 * sizeof(float)); + EXPECT_EQ(result, 0); + + cmp[0] = -1.0f; + cmp[1] = 2.3f; + cmp[2] = 1000.0f; + cmp[3] = -1.0f; + cmp[4] = 2.3f; + cmp[5] = 1000.0f; + v3f = cmp; + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], cmp[i]); + } +} + +TEST(MatrixBase, CastVector) { + srand(time(NULL)); + + FasTC::MatrixBase v3f; + for(int i = 0; i < 6; i++) { + v3f[i] = static_cast(rand()); + } + + FasTC::MatrixBase v3d = v3f; + FasTC::MatrixBase v3i = v3f; + for(int i = 0; i < 3*2; i++) { + EXPECT_EQ(v3d(i), static_cast(v3f(i))); + EXPECT_EQ(v3i(i), static_cast(v3f(i))); + } +} + +TEST(MatrixBase, MatrixMultiplication) { + FasTC::MatrixBase a; + a(0, 0) = 1; a(0, 1) = 2; a(0, 2) = 3; + a(1, 0) = 4; a(1, 1) = 5; a(1, 2) = 6; + + FasTC::MatrixBase b; + b(0, 0) = -1; b(0, 1) = 2; b(0, 2) = -4; b(0, 3) = 5; b(0, 4) = 0; + b(1, 0) = 1; b(1, 1) = 2; b(1, 2) = 4; b(1, 3) = 6; b(1, 4) = 3; + b(2, 0) = -1; b(2, 1) = -2; b(2, 2) = -3; b(2, 3) = -4; b(2, 4) = 5; + + FasTC::MatrixBase amb = a * b; + EXPECT_NEAR(amb(0, 0), -2, kEpsilon); + EXPECT_NEAR(amb(0, 1), 0, kEpsilon); + EXPECT_NEAR(amb(0, 2), -5, kEpsilon); + EXPECT_NEAR(amb(0, 3), 5, kEpsilon); + EXPECT_NEAR(amb(0, 4), 21, kEpsilon); + + EXPECT_NEAR(amb(1, 0), -5, kEpsilon); + EXPECT_NEAR(amb(1, 1), 6, kEpsilon); + EXPECT_NEAR(amb(1, 2), -14, kEpsilon); + EXPECT_NEAR(amb(1, 3), 26, kEpsilon); + EXPECT_NEAR(amb(1, 4), 45, kEpsilon); +} + +TEST(MatrixBase, Transposition) { + FasTC::MatrixBase a; + a(0, 0) = -1; a(0, 1) = 2; a(0, 2) = -4; a(0, 3) = 5; a(0, 4) = 0; + a(1, 0) = 1; a(1, 1) = 2; a(1, 2) = 4; a(1, 3) = 6; a(1, 4) = 3; + a(2, 0) = -1; a(2, 1) = -2; a(2, 2) = -3; a(2, 3) = -4; a(2, 4) = 5; + + FasTC::MatrixBase b = a.Transpose(); + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 5; j++) { + EXPECT_EQ(a(i, j), b(j, i)); + } + } +} + +TEST(MatrixBase, VectorMultiplication) { + + FasTC::MatrixBase a; + a(0, 0) = -1; a(0, 1) = 2; a(0, 2) = -4; a(0, 3) = 5; a(0, 4) = 0; + a(1, 0) = 1; a(1, 1) = 2; a(1, 2) = 4; a(1, 3) = 6; a(1, 4) = 3; + a(2, 0) = -1; a(2, 1) = -2; a(2, 2) = -3; a(2, 3) = -4; a(2, 4) = 5; + + FasTC::VectorBase v; + for(int i = 0; i < 5; i++) v[i] = i + 1; + + FasTC::VectorBase u = a * v; + EXPECT_EQ(u[0], -1 + (2 * 2) - (4 * 3) + (5 * 4)); + EXPECT_EQ(u[1], 1 + (2 * 2) + (4 * 3) + (6 * 4) + (3 * 5)); + EXPECT_EQ(u[2], -1 + (-2 * 2) - (3 * 3) - (4 * 4) + (5 * 5)); + + ///// + + for(int i = 0; i < 3; i++) u[i] = i + 1; + v = u * a; + + EXPECT_EQ(v[0], -1 + (1 * 2) - (1 * 3)); + EXPECT_EQ(v[1], 2 + (2 * 2) - (2 * 3)); + EXPECT_EQ(v[2], -4 + (4 * 2) - (3 * 3)); + EXPECT_EQ(v[3], 5 + (6 * 2) - (4 * 3)); + EXPECT_EQ(v[4], 0 + (3 * 2) + (5 * 3)); +} + +//////////////////////////////////////////////////////////////////////////////// + +#include "MatrixSquare.h" + +TEST(MatrixSquare, Constructors) { + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; m(0, 2) = 3; + m(1, 0) = 2; m(1, 1) = 3; m(1, 2) = 4; + m(2, 0) = 3; m(2, 1) = 4; m(2, 2) = 5; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::MatrixSquare fsqm(m); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::MatrixSquare fcsqm(sqm); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } +} + +TEST(MatrixSquare, PowerMethod) { + FasTC::MatrixSquare A; + A(0, 0) = 0.8f; A(0, 1) = 0.3f; + A(1, 0) = 0.2f; A(1, 1) = 0.7f; + + double e; + FasTC::VectorBase x; + A.PowerMethod(x, &e, 20, 200); + + EXPECT_NEAR(x[0], 0.83205f, 0.0001); + EXPECT_NEAR(x[1], 0.5547f, 0.0001); + + EXPECT_NEAR(e, 1.f, 0.0001); +} + +//////////////////////////////////////////////////////////////////////////////// + +#include "Matrix2x2.h" + +TEST(Matrix2x2, Constructors) { + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; + m(1, 0) = 2; m(1, 1) = 3; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 4; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::Matrix2x2 tbtm (m); + for(int i = 0; i < 4; i++) { + EXPECT_EQ(m[i], tbtm[i]); + } + + FasTC::Matrix2x2 fsqm(m); + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::Matrix2x2 fcsqm(sqm); + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#include "Matrix3x3.h" + +TEST(Matrix3x3, Constructors) { + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; m(0, 2) = 3; + m(1, 0) = 2; m(1, 1) = 3; m(1, 2) = 4; + m(2, 0) = 3; m(2, 1) = 4; m(2, 2) = 5; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::Matrix3x3 tbtm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], tbtm[i]); + } + + FasTC::Matrix3x3 fsqm(m); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::Matrix3x3 fcsqm(sqm); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#include "Matrix4x4.h" + +TEST(Matrix4x4, Constructors) { + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; m(0, 2) = 3; m(0, 3) = 4; + m(1, 0) = 2; m(1, 1) = 3; m(1, 2) = 4; m(1, 3) = 5; + m(2, 0) = 3; m(2, 1) = 4; m(2, 2) = 5; m(2, 3) = 6; + m(3, 0) = 4; m(3, 1) = 5; m(3, 2) = 6; m(3, 3) = 7; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::Matrix4x4 tbtm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], tbtm[i]); + } + + FasTC::Matrix4x4 fsqm(m); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::Matrix4x4 fcsqm(sqm); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } +} + diff --git a/Base/test/TestPixel.cpp b/Base/test/TestPixel.cpp index 0a630b8..fc97dca 100644 --- a/Base/test/TestPixel.cpp +++ b/Base/test/TestPixel.cpp @@ -248,3 +248,63 @@ TEST(Pixel, UnpackRGBA) { EXPECT_EQ(p.G(), 0x3); EXPECT_EQ(p.R(), 0x1f); } + +TEST(Pixel, ScaleColor) { + FasTC::Pixel p; + uint8 newBitDepth[4] = { 3, 5, 2, 1 }; // A R G B + p.ChangeBitDepth(newBitDepth); + + p.R() = 1; + p.G() = 2; + p.B() = 3; + p.A() = 4; + + FasTC::Pixel sp = p * 3; + FasTC::Pixel ps = 3 * p; + + EXPECT_EQ(sp.R(), 3); EXPECT_EQ(ps.R(), 3); + EXPECT_EQ(sp.G(), 6); EXPECT_EQ(ps.G(), 6); + EXPECT_EQ(sp.B(), 9); EXPECT_EQ(ps.B(), 9); + EXPECT_EQ(sp.A(), 12); EXPECT_EQ(ps.A(), 12); + + uint8 bd[4]; + sp.GetBitDepth(bd); + for(uint32 i = 0; i < 4; i++) { + EXPECT_EQ(bd[i], newBitDepth[i]); + } + + ps.GetBitDepth(bd); + for(uint32 i = 0; i < 4; i++) { + EXPECT_EQ(bd[i], newBitDepth[i]); + } +} + +TEST(YCoCgPixel, Conversion) { + + FasTC::Pixel p; + p.R() = 127; + p.G() = 127; + p.B() = 127; + p.A() = 255; + + FasTC::YCoCgPixel yp (p); + EXPECT_EQ(yp.Y(), 127); + EXPECT_EQ(yp.Co(), 128); + EXPECT_EQ(yp.Cg(), 128); +} + +TEST(YCoCgPixel, ConvertBack) { + FasTC::Pixel p; + + p.R() = 241; + p.G() = 22; + p.B() = 102; + p.A() = 124; + + FasTC::YCoCgPixel yp (p); + FasTC::Pixel bp = yp.ToRGBA(); + + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(p[i], bp[i], 1); + } +} diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp new file mode 100644 index 0000000..7735fdc --- /dev/null +++ b/Base/test/TestVector.cpp @@ -0,0 +1,435 @@ +/* FasTC + * Copyright (c) 2014 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 "VectorBase.h" + +static const float kEpsilon = 1e-6; + +TEST(VectorBase, Constructors) { + FasTC::VectorBase v3f; + FasTC::VectorBase v1d; + FasTC::VectorBase v7i; + FasTC::VectorBase v16u; + +#define TEST_VECTOR_COPY_CONS(v, t, n) \ + do { \ + FasTC::VectorBase d##v (v); \ + for(int i = 0; i < n; i++) { \ + EXPECT_EQ(d##v [i], v[i]); \ + } \ + } while(0) \ + + TEST_VECTOR_COPY_CONS(v3f, float, 3); + TEST_VECTOR_COPY_CONS(v1d, double, 1); + TEST_VECTOR_COPY_CONS(v7i, int, 7); + TEST_VECTOR_COPY_CONS(v16u, unsigned, 16); + +#undef TEST_VECTOR_COPY_CONS +} + +TEST(VectorBase, Accessors) { + FasTC::VectorBase v3f; + v3f[0] = 1.0f; + v3f[1] = -2.3f; + v3f[2] = 1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], v3f(i)); + } + + v3f(0) = -1.0f; + v3f(1) = 2.3f; + v3f(2) = -1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f(i), v3f[i]); + } +} + +TEST(VectorBase, PointerConversion) { + FasTC::VectorBase v3f; + v3f[0] = 1.0f; + v3f[1] = -2.3f; + v3f[2] = 1000; + + float cmp[3] = { 1.0f, -2.3f, 1000 }; + const float *v3fp = v3f; + int result = memcmp(cmp, v3fp, 3 * sizeof(float)); + EXPECT_EQ(result, 0); + + cmp[0] = -1.0f; + cmp[1] = 2.3f; + cmp[2] = 1000.0f; + v3f = cmp; + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], cmp[i]); + } +} + +TEST(VectorBase, CastVector) { + FasTC::VectorBase v3f; + FasTC::VectorBase v3d = v3f; + FasTC::VectorBase v3i = v3f; + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3d(i), static_cast(v3f(i))); + EXPECT_EQ(v3i(i), static_cast(v3f(i))); + } +} + +TEST(VectorBase, DotProduct) { + int iv[5] = { -2, -1, 0, 1, 2 }; + FasTC::VectorBase v5i(iv); + + unsigned uv[5] = { 1, 2, 3, 4, 5 }; + FasTC::VectorBase v5u(uv); + + EXPECT_EQ(v5i.Dot(v5u), 10); + EXPECT_EQ(v5u.Dot(v5i), 10); + + EXPECT_EQ(v5i * v5u, 10); + EXPECT_EQ(v5u * v5i, 10); +} + +TEST(VectorBase, Length) { + int iv[5] = { 1, 2, 3, 4, 5 }; + FasTC::VectorBase v5i (iv); + + EXPECT_EQ(v5i.LengthSq(), 55); + EXPECT_EQ(v5i.Length(), 7); + + float fv[6] = {1, 2, 3, 4, 5, 6}; + FasTC::VectorBase v6f (fv); + + EXPECT_EQ(v6f.LengthSq(), 91); + EXPECT_NEAR(v6f.Length(), sqrt(91.0f), kEpsilon); +} + +TEST(VectorBase, Normalization) { + float fv[2] = {1, 0}; + FasTC::VectorBase v2f (fv); + v2f.Normalize(); + EXPECT_EQ(v2f[0], 1); + EXPECT_EQ(v2f[1], 0); + + // Normalized vector should be sqrt(2) for each axis, although + // this can't be represented as integers... + unsigned uv[2] = {2, 2}; + FasTC::VectorBase v2u (uv); + v2u.Normalize(); + EXPECT_EQ(v2u[0], 1); + EXPECT_EQ(v2u[1], 1); + + const float sqrt2 = sqrt(2)/2.0f; + for(int i = 2; i < 10; i++) { + v2f[0] = static_cast(i); + v2f[1] = static_cast(i); + v2f.Normalize(); + EXPECT_NEAR(v2f[0], sqrt2, kEpsilon); + EXPECT_NEAR(v2f[1], sqrt2, kEpsilon); + } +} + +TEST(VectorBase, Scaling) { + float fv[2] = {1.0f, 3.0f}; + FasTC::VectorBase v2f (fv); + FasTC::VectorBase v2fd = v2f * 3.0f; + EXPECT_NEAR(v2fd[0], 3.0f, kEpsilon); + EXPECT_NEAR(v2fd[1], 9.0f, kEpsilon); + + v2fd = -1.0 * v2f; + EXPECT_NEAR(v2fd[0], -1.0f, kEpsilon); + EXPECT_NEAR(v2fd[1], -3.0f, kEpsilon); + + v2fd = v2f / 3; + EXPECT_NEAR(v2fd[0], 1.0f / 3.0f, kEpsilon); + EXPECT_NEAR(v2fd[1], 1.0f, kEpsilon); + + unsigned uv[2] = {1, 3}; + FasTC::VectorBase v2u (uv); + FasTC::VectorBase v2ud = v2u * 0.5; + EXPECT_EQ(v2ud[0], 0); + EXPECT_EQ(v2ud[1], 1); + + v2ud = v2u / 0.5f; + EXPECT_EQ(v2ud[0], 2); + EXPECT_EQ(v2ud[1], 6); +} + +TEST(VectorBase, Addition) { + float fv[2] = {1.1f, 3.2f}; + FasTC::VectorBase v2f (fv); + + int uv[2] = {5, 2}; + FasTC::VectorBase v2u (uv); + + FasTC::VectorBase au = v2u + v2f; + EXPECT_EQ(au[0], 6); + EXPECT_EQ(au[1], 5); + + au = v2u + fv + uv; + EXPECT_EQ(au[0], 11); + EXPECT_EQ(au[1], 7); + + FasTC::VectorBase af = v2f + v2u; + EXPECT_NEAR(af[0], 6.1f, kEpsilon); + EXPECT_NEAR(af[1], 5.2f, kEpsilon); + + au = v2u - v2f; + EXPECT_EQ(au[0], 3); + EXPECT_EQ(au[1], -1); + + af = v2f - v2u; + EXPECT_NEAR(af[0], -3.9f, kEpsilon); + EXPECT_NEAR(af[1], 1.2f, kEpsilon); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Vec2 +// +//////////////////////////////////////////////////////////////////////////////// + +#include "Vector2.h" + +TEST(Vector2, BaseFunctionality) { + FasTC::Vec2f v2f; + FasTC::Vec2d v2d; + + v2f = v2d; + EXPECT_NEAR(v2f[0], v2d[0], kEpsilon); + EXPECT_NEAR(v2f[1], v2d[1], kEpsilon); +} + +TEST(Vector2, Accessors) { + float fv[2] = { 1.0f, 2.0f }; + FasTC::Vec2f v2f (fv); + EXPECT_EQ(v2f.X(), 1.0f); + EXPECT_EQ(v2f.Y(), 2.0f); + + v2f.X() = 4.0f; + v2f.Y() = 5.0f; + + EXPECT_EQ(v2f.X(), 4.0f); + EXPECT_EQ(v2f.Y(), 5.0f); +} + +TEST(Vector2, Addition) { + float fv[2] = { 1.0f, 2.0f }; + FasTC::Vec2f v2f (fv); + + double dv[2] = { 4.3, -10.2 }; + FasTC::Vec2d v2d (dv); + + EXPECT_NEAR((v2f + v2d).X(), 5.3, kEpsilon); + EXPECT_NEAR((v2f + v2d).Y(), -8.2, kEpsilon); +} + +TEST(Vector2, Swizzle) { + float fv[2] = {1.0f, 2.0f}; + FasTC::Vec2f v; + v = fv; + + EXPECT_EQ(v.XX().X(), 1.0f); + EXPECT_EQ(v.XX().Y(), 1.0f); + EXPECT_EQ(v.YY().X(), 2.0f); + EXPECT_EQ(v.YY().Y(), 2.0f); + EXPECT_EQ(v.YX().X(), 2.0f); + EXPECT_EQ(v.YX().Y(), 1.0f); + EXPECT_EQ(v.XY().X(), 1.0f); + EXPECT_EQ(v.XY().Y(), 2.0f); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Vec3 +// +//////////////////////////////////////////////////////////////////////////////// + +#include "Vector3.h" + +TEST(Vector3, BaseFunctionality) { + FasTC::Vec3f vf; + FasTC::Vec3d vd; + + vf = vd; + for(int i = 0; i < 3; i++) { + EXPECT_NEAR(vf[i], vd[i], kEpsilon); + } +} + +TEST(Vector3, Accessors) { + float fv[3] = { 1.0f, 2.0f, 3.0f }; + FasTC::Vec3f v3f (fv); + EXPECT_EQ(v3f.X(), 1.0f); + EXPECT_EQ(v3f.Y(), 2.0f); + EXPECT_EQ(v3f.Z(), 3.0f); + + v3f.X() = 4.0f; + v3f.Y() = 5.0f; + v3f.Z() = 6.0f; + + EXPECT_EQ(v3f.X(), 4.0f); + EXPECT_EQ(v3f.Y(), 5.0f); + EXPECT_EQ(v3f.Z(), 6.0f); +} + +TEST(Vector3, Addition) { + float fv[3] = { 1.0f, 2.0f, 3.0f }; + FasTC::Vec3f v3f (fv); + + double dv[3] = { 4.3, -10.2, 0.0f }; + FasTC::Vec3d v3d (dv); + + EXPECT_NEAR((v3f + v3d).X(), 5.3, kEpsilon); + EXPECT_NEAR((v3f + v3d).Y(), -8.2, kEpsilon); + EXPECT_NEAR((v3f + v3d).Z(), 3.0, kEpsilon); +} + +TEST(Vector3, Swizzle) { + float fv[3] = {1.0f, 2.0f, 3.0f}; + FasTC::Vec3f v; + v = fv; + + EXPECT_EQ(v.XXX().Y(), 1.0f); + EXPECT_EQ(v.YZX().X(), 2.0f); + EXPECT_EQ(v.ZZY().Z(), 2.0f); + EXPECT_EQ(v.ZYZ().X(), 3.0f); +} + +TEST(Vector3, CrossProduct) { + float fv[3] = {1.0f, 2.0f, 3.0f}; + FasTC::Vec3f v1 (fv); + FasTC::Vec3f v2 = v1; + std::swap(v1.X(), v1.Z()); + + // Right handed coordinate system... + FasTC::Vec3f r = v1.Cross(v2); + EXPECT_NEAR(r.X(), 4.0f, kEpsilon); + EXPECT_NEAR(r.Y(), -8.0f, kEpsilon); + EXPECT_NEAR(r.Z(), 4.0f, kEpsilon); + + v1.X() = v1.Y() = v2.X() = v2.Z() = 0.0f; + v1.Z() = v2.Y() = 1.0f; + + r = v1.Cross(v2); + EXPECT_EQ(r.X(), -1.0f); + EXPECT_EQ(r.Y(), 0.0f); + EXPECT_EQ(r.Z(), 0.0f); + + r = v2.Cross(v1); + EXPECT_EQ(r.X(), 1.0f); + EXPECT_EQ(r.Y(), 0.0f); + EXPECT_EQ(r.Z(), 0.0f); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Vec4 +// +//////////////////////////////////////////////////////////////////////////////// + +#include "Vector4.h" + +TEST(Vector4, BaseFunctionality) { + FasTC::Vec4f vf; + FasTC::Vec4d vd; + + vf = vd; + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(vf[i], vd[i], kEpsilon); + } +} + +TEST(Vector4, Accessors) { + float fv[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; + FasTC::Vec4f v4f (fv); + EXPECT_EQ(v4f.X(), 1.0f); + EXPECT_EQ(v4f.Y(), 2.0f); + EXPECT_EQ(v4f.Z(), 3.0f); + EXPECT_EQ(v4f.W(), 4.0f); + + v4f.X() = 5.0f; + v4f.Y() = 6.0f; + v4f.Z() = 7.0f; + v4f.W() = 8.0f; + + EXPECT_EQ(v4f.X(), 5.0f); + EXPECT_EQ(v4f.Y(), 6.0f); + EXPECT_EQ(v4f.Z(), 7.0f); + EXPECT_EQ(v4f.W(), 8.0f); +} + +TEST(Vector4, Addition) { + float fv[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; + FasTC::Vec4f v4f (fv); + + double dv[4] = { 4.3, -10.2, 0.0f, -22.0f }; + FasTC::Vec4d v3d (dv); + + EXPECT_NEAR((v4f + v3d).X(), 5.3, kEpsilon); + EXPECT_NEAR((v4f + v3d).Y(), -8.2, kEpsilon); + EXPECT_NEAR((v4f + v3d).Z(), 3.0, kEpsilon); + EXPECT_NEAR((v4f + v3d).W(), -18.0, kEpsilon); +} + +TEST(Vector4, Swizzle) { + float fv[4] = {1.0f, 2.0f, 3.0f, 4.0f}; + FasTC::Vec4f v; + v = fv; + + EXPECT_EQ(v.XXXX().Y(), 1.0f); + EXPECT_EQ(v.YZXW().X(), 2.0f); + EXPECT_EQ(v.ZWY().Z(), 2.0f); + EXPECT_EQ(v.ZZ().X(), 3.0f); + EXPECT_EQ(v.WWXY().W(), 2.0f); +} diff --git a/CLTool/CMakeLists.txt b/CLTool/CMakeLists.txt index 2205688..73de05b 100644 --- a/CLTool/CMakeLists.txt +++ b/CLTool/CMakeLists.txt @@ -41,6 +41,8 @@ # INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/Base/include ) + INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Core/include ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/include ) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 78430b0..3af98a6 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -49,6 +49,9 @@ # # +INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/Base/include ) + SET( SOURCES "src/TexComp.cpp" "src/CompressedImage.cpp" @@ -74,7 +77,6 @@ ELSE() SET( LINK_FLAGS -lrt ${LINK_FLAGS} ) ENDIF() -INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR} ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/ETCEncoder/include ) diff --git a/DXTEncoder/CMakeLists.txt b/DXTEncoder/CMakeLists.txt index 9774136..015bd96 100755 --- a/DXTEncoder/CMakeLists.txt +++ b/DXTEncoder/CMakeLists.txt @@ -41,6 +41,7 @@ # INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/DXTEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/DXTEncoder/include) diff --git a/ETCEncoder/CMakeLists.txt b/ETCEncoder/CMakeLists.txt index a05bd4b..f23bc82 100644 --- a/ETCEncoder/CMakeLists.txt +++ b/ETCEncoder/CMakeLists.txt @@ -41,6 +41,7 @@ # INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/ETCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/ETCEncoder/include) diff --git a/ETCEncoder/src/Decompressor.cpp b/ETCEncoder/src/Decompressor.cpp index f99fede..92c8b93 100644 --- a/ETCEncoder/src/Decompressor.cpp +++ b/ETCEncoder/src/Decompressor.cpp @@ -60,8 +60,8 @@ namespace ETCC { uint32 blocksX = cj.Width() / 4; uint32 blocksY = cj.Height() / 4; - for(uint32 j = 0; j < blocksX; j++) { - for(uint32 i = 0; i < blocksY; i++) { + for(uint32 j = 0; j < blocksY; j++) { + for(uint32 i = 0; i < blocksX; i++) { uint32 pixels[16]; uint32 blockIdx = j*blocksX + i; rg_etc1::unpack_etc1_block(cj.InBuf() + blockIdx * 8, pixels); diff --git a/IO/CMakeLists.txt b/IO/CMakeLists.txt index dc90d3c..272e624 100644 --- a/IO/CMakeLists.txt +++ b/IO/CMakeLists.txt @@ -40,6 +40,12 @@ # # +INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/Base/include) + +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/IO/include ) +INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/include ) + SET( SOURCES "src/ImageWriter.cpp" "src/ImageLoader.cpp" @@ -108,9 +114,6 @@ CONFIGURE_FILE( "include/ImageWriter.h" ) -INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/IO/include ) -INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/include ) -INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Core/include ) ADD_LIBRARY(FasTCIO diff --git a/IO/src/ImageLoaderKTX.cpp b/IO/src/ImageLoaderKTX.cpp index 55de436..d1f1bd0 100644 --- a/IO/src/ImageLoaderKTX.cpp +++ b/IO/src/ImageLoaderKTX.cpp @@ -103,6 +103,7 @@ class IntLoader { class BigEndianIntLoader : public IntLoader { public: + BigEndianIntLoader() { } virtual uint32 ReadInt(const uint8 *data) const { uint32 ret = 0; ret |= data[0]; @@ -117,10 +118,11 @@ static const BigEndianIntLoader gBEldr; class LittleEndianIntLoader : public IntLoader { public: + LittleEndianIntLoader() { } virtual uint32 ReadInt(const uint8 *data) const { uint32 ret = 0; ret |= data[3]; - for(uint32 i = 3; i >= 0; i--) { + for(int32 i = 3; i >= 0; i--) { ret <<= 8; ret |= data[i]; } diff --git a/PVRTCEncoder/CMakeLists.txt b/PVRTCEncoder/CMakeLists.txt index 2f8845b..555c1dd 100644 --- a/PVRTCEncoder/CMakeLists.txt +++ b/PVRTCEncoder/CMakeLists.txt @@ -53,6 +53,7 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) SET( HEADERS include/PVRTCCompressor.h diff --git a/PVRTCEncoder/test/CMakeLists.txt b/PVRTCEncoder/test/CMakeLists.txt index 57de2e6..a399ee8 100644 --- a/PVRTCEncoder/test/CMakeLists.txt +++ b/PVRTCEncoder/test/CMakeLists.txt @@ -53,7 +53,9 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/PVRTCEncoder/src) -INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include ) + INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS diff --git a/QtGUI/CMakeLists.txt b/QtGUI/CMakeLists.txt deleted file mode 100644 index 9d13dc4..0000000 --- a/QtGUI/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -# FasTC -# Copyright (c) 2012 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 -# -# diff --git a/README.md b/README.md index bdecfb0..adf612b 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,9 @@ compression time and PSNR. * [DXT1](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2] * [DXT5](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2] * [PVRTC](http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf) +* `-d`: Specifies the decompressed output file. + * **Default**: ``-``.png +* `-nd`: Suppress decompressed output. * `-t`: Specifies the number of threads to use for compression. * **Default**: 1 * **Formats**: BPTC, ETC1, DXT1, DXT5