diff --git a/CMakeLists.txt b/CMakeLists.txt index c862354..2a5395f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ set_project_warnings(test_rgbcx) if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -lc++abi") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fsanitize=undefined") set(PROJECT_WARNINGS ${CLANG_WARNINGS}) if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") set_property(TARGET python_rgbcx test_rgbcx PROPERTY OSX_ARCHITECTURES_RELEASE x86_64 arm64) #Mach-O fat binary for arm and x86 diff --git a/src/BC1/BC1Block.h b/src/BC1/BC1Block.h new file mode 100644 index 0000000..77b81c4 --- /dev/null +++ b/src/BC1/BC1Block.h @@ -0,0 +1,85 @@ +/* Python-rgbcx Texture Compression Library + Copyright (C) 2021 Andrew Cassidy + Partially derived from rgbcx.h written by Richard Geldreich + and licenced under the public domain + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +#include "../Color.h" +#include "../util.h" + +namespace rgbcx { + +#pragma pack(push, 1) +class BC1Block { + public: + using UnpackedSelectors = std::array, 4>; + + uint16_t GetLowColor() const { return static_cast(_low_color[0] | (_low_color[1] << 8U)); } + uint16_t GetHighColor() const { return static_cast(_high_color[0] | (_high_color[1] << 8U)); } + Color GetLowColor32() const { return Color::Unpack565(GetLowColor()); } + Color GetHighColor32() const { return Color::Unpack565(GetHighColor()); } + + bool Is3Color() const { return GetLowColor() <= GetHighColor(); } + void SetLowColor(uint16_t c) { + _low_color[0] = c & 0xFF; + _low_color[1] = (c >> 8) & 0xFF; + } + void SetHighColor(uint16_t c) { + _high_color[0] = c & 0xFF; + _high_color[1] = (c >> 8) & 0xFF; + } + uint32_t GetSelector(uint32_t x, uint32_t y) const { + assert((x < 4U) && (y < 4U)); + return (selectors[y] >> (x * SelectorBits)) & SelectorMask; + } + void SetSelector(uint32_t x, uint32_t y, uint32_t val) { + assert((x < 4U) && (y < 4U) && (val < 4U)); + selectors[y] &= (~(SelectorMask << (x * SelectorBits))); + selectors[y] |= (val << (x * SelectorBits)); + } + + UnpackedSelectors UnpackSelectors() const { + UnpackedSelectors unpacked; + for (unsigned i = 0; i < 4; i++) { unpacked[i] = Unpack(selectors[i]); } + return unpacked; + } + + void PackSelectors(const UnpackedSelectors& unpacked) { + for (unsigned i = 0; i < 4; i++) { selectors[i] = Pack(unpacked[i]); } + } + + constexpr static inline size_t EndpointSize = 2; + constexpr static inline size_t SelectorSize = 4; + constexpr static inline uint8_t SelectorBits = 2; + constexpr static inline uint8_t SelectorValues = 1 << SelectorBits; + constexpr static inline uint8_t SelectorMask = SelectorValues - 1; + + private: + std::array _low_color; + std::array _high_color; + + public: + std::array selectors; +}; +#pragma pack(pop) +} // namespace rgbcx \ No newline at end of file diff --git a/src/BC1/BC1Decoder.cpp b/src/BC1/BC1Decoder.cpp index 23e276a..4b395f6 100644 --- a/src/BC1/BC1Decoder.cpp +++ b/src/BC1/BC1Decoder.cpp @@ -21,12 +21,14 @@ #include #include + #include -#include "../ColorBlock.h" -#include "../blocks.h" + #include "../Color.h" +#include "../ColorBlock.h" #include "../interpolator.h" #include "../ndebug.h" +#include "BC1Block.h" namespace rgbcx { void BC1Decoder::DecodeBlock(Color4x4 dest, BC1Block *const block) const noexcept(ndebug) { diff --git a/src/BC1/BC1Decoder.h b/src/BC1/BC1Decoder.h index 8defd16..deca5bc 100644 --- a/src/BC1/BC1Decoder.h +++ b/src/BC1/BC1Decoder.h @@ -23,9 +23,9 @@ #include "../BlockDecoder.h" #include "../ColorBlock.h" -#include "../blocks.h" #include "../interpolator.h" #include "../ndebug.h" +#include "BC1Block.h" namespace rgbcx { class BC1Decoder final : public BlockDecoder { diff --git a/src/BC3/BC3Block.h b/src/BC3/BC3Block.h new file mode 100644 index 0000000..1032e26 --- /dev/null +++ b/src/BC3/BC3Block.h @@ -0,0 +1,34 @@ +/* Python-rgbcx Texture Compression Library + Copyright (C) 2021 Andrew Cassidy + Partially derived from rgbcx.h written by Richard Geldreich + and licenced under the public domain + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . + */ + +#pragma once + +#include "../BC1/BC1Block.h" +#include "../BC4/BC4Block.h" + +namespace rgbcx { + +#pragma pack(push, 1) +class BC3Block { + public: + BC4Block alpha_block; + BC1Block color_block; +}; +#pragma pack(pop) +} // namespace rgbcx \ No newline at end of file diff --git a/src/BC3/BC3Decoder.cpp b/src/BC3/BC3Decoder.cpp index 6c3d423..5ac24e1 100644 --- a/src/BC3/BC3Decoder.cpp +++ b/src/BC3/BC3Decoder.cpp @@ -22,7 +22,6 @@ #include "../BC1/BC1Decoder.h" #include "../BC4/BC4Decoder.h" #include "../ColorBlock.h" -#include "../blocks.h" #include "../ndebug.h" namespace rgbcx { diff --git a/src/BC3/BC3Decoder.h b/src/BC3/BC3Decoder.h index f913148..40c478e 100644 --- a/src/BC3/BC3Decoder.h +++ b/src/BC3/BC3Decoder.h @@ -25,9 +25,9 @@ #include "../BC4/BC4Decoder.h" #include "../BlockDecoder.h" #include "../ColorBlock.h" -#include "../blocks.h" #include "../interpolator.h" #include "../ndebug.h" +#include "BC3Block.h" namespace rgbcx { class BC3Decoder : public BlockDecoder { diff --git a/src/blocks.h b/src/BC4/BC4Block.h similarity index 63% rename from src/blocks.h rename to src/BC4/BC4Block.h index eca6a27..c32bba7 100644 --- a/src/blocks.h +++ b/src/BC4/BC4Block.h @@ -1,6 +1,6 @@ /* Python-rgbcx Texture Compression Library Copyright (C) 2021 Andrew Cassidy - Partially derived from rgbcx.h written by Richard Geldreich 2020 + Partially derived from rgbcx.h written by Richard Geldreich and licenced under the public domain This program is free software: you can redistribute it and/or modify @@ -24,62 +24,13 @@ #include #include -#include "Color.h" -#include "util.h" +#include "../BC1/BC1Block.h" +#include "../Color.h" +#include "../util.h" -#pragma pack(push, 1) -class BC1Block { - public: - using UnpackedSelectors = std::array, 4>; - - uint16_t GetLowColor() const { return static_cast(_low_color[0] | (_low_color[1] << 8U)); } - uint16_t GetHighColor() const { return static_cast(_high_color[0] | (_high_color[1] << 8U)); } - Color GetLowColor32() const { return Color::Unpack565(GetLowColor()); } - Color GetHighColor32() const { return Color::Unpack565(GetHighColor()); } - - bool Is3Color() const { return GetLowColor() <= GetHighColor(); } - void SetLowColor(uint16_t c) { - _low_color[0] = c & 0xFF; - _low_color[1] = (c >> 8) & 0xFF; - } - void SetHighColor(uint16_t c) { - _high_color[0] = c & 0xFF; - _high_color[1] = (c >> 8) & 0xFF; - } - uint32_t GetSelector(uint32_t x, uint32_t y) const { - assert((x < 4U) && (y < 4U)); - return (selectors[y] >> (x * SelectorBits)) & SelectorMask; - } - void SetSelector(uint32_t x, uint32_t y, uint32_t val) { - assert((x < 4U) && (y < 4U) && (val < 4U)); - selectors[y] &= (~(SelectorMask << (x * SelectorBits))); - selectors[y] |= (val << (x * SelectorBits)); - } - - UnpackedSelectors UnpackSelectors() const { - UnpackedSelectors unpacked; - for (unsigned i = 0; i < 4; i++) { unpacked[i] = Unpack(selectors[i]); } - return unpacked; - } - - void PackSelectors(const UnpackedSelectors& unpacked) { - for (unsigned i = 0; i < 4; i++) { selectors[i] = Pack(unpacked[i]); } - } - - constexpr static inline size_t EndpointSize = 2; - constexpr static inline size_t SelectorSize = 4; - constexpr static inline uint8_t SelectorBits = 2; - constexpr static inline uint8_t SelectorValues = 1 << SelectorBits; - constexpr static inline uint8_t SelectorMask = SelectorValues - 1; - - private: - std::array _low_color; - std::array _high_color; - - public: - std::array selectors; -}; +namespace rgbcx { +#pragma pack(push, 1) class BC4Block { public: using UnpackedSelectors = std::array, 4>; @@ -156,22 +107,11 @@ class BC4Block { constexpr static inline uint8_t SelectorBits = 3; constexpr static inline uint8_t SelectorValues = 1 << SelectorBits; constexpr static inline uint8_t SelectorMask = SelectorValues - 1; - constexpr static inline uint64_t SelectorBitsMax = (1UL << (8U * SelectorSize)) - 1U; + constexpr static inline uint64_t SelectorBitsMax = (1ULL << (8U * SelectorSize)) - 1U; uint8_t low_alpha; uint8_t high_alpha; std::array selectors; }; - -class BC3Block { - public: - BC4Block alpha_block; - BC1Block color_block; -}; - -class BC5Block { - public: - BC4Block chan0_block; - BC4Block chan1_block; -}; -#pragma pack(pop) \ No newline at end of file +#pragma pack(pop) +} // namespace rgbcx diff --git a/src/BC4/BC4Decoder.cpp b/src/BC4/BC4Decoder.cpp index 730ce79..ca54a31 100644 --- a/src/BC4/BC4Decoder.cpp +++ b/src/BC4/BC4Decoder.cpp @@ -25,8 +25,8 @@ #include "../Color.h" // for Color #include "../ColorBlock.h" // for ColorBlock -#include "../blocks.h" // for BC4Block #include "../ndebug.h" // for ndebug +#include "BC4Block.h" void rgbcx::BC4Decoder::DecodeBlock(Color4x4 dest, BC4Block *const block, size_t channel) const noexcept(ndebug) { auto l = block->GetLowAlpha(); diff --git a/src/BC4/BC4Decoder.h b/src/BC4/BC4Decoder.h index 7009aa9..5509de9 100644 --- a/src/BC4/BC4Decoder.h +++ b/src/BC4/BC4Decoder.h @@ -23,8 +23,8 @@ #include "../BlockDecoder.h" #include "../ColorBlock.h" -#include "../blocks.h" #include "../ndebug.h" +#include "BC4Block.h" namespace rgbcx { class BC4Decoder : public BlockDecoder { diff --git a/src/BC5/BC5Block.h b/src/BC5/BC5Block.h new file mode 100644 index 0000000..e9b886a --- /dev/null +++ b/src/BC5/BC5Block.h @@ -0,0 +1,33 @@ +/* Python-rgbcx Texture Compression Library + Copyright (C) 2021 Andrew Cassidy + Partially derived from rgbcx.h written by Richard Geldreich + and licenced under the public domain + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . + */ + +#pragma once + +#include "../BC4/BC4Block.h" + +namespace rgbcx { + +#pragma pack(push, 1) +class BC5Block { + public: + BC4Block chan0_block; + BC4Block chan1_block; +}; +#pragma pack(pop) +} // namespace rgbcx \ No newline at end of file diff --git a/src/BC5/BC5Decoder.cpp b/src/BC5/BC5Decoder.cpp index 22aa723..2f4a43d 100644 --- a/src/BC5/BC5Decoder.cpp +++ b/src/BC5/BC5Decoder.cpp @@ -21,7 +21,6 @@ #include "../BC4/BC4Decoder.h" #include "../ColorBlock.h" -#include "../blocks.h" #include "../ndebug.h" namespace rgbcx { diff --git a/src/BC5/BC5Decoder.h b/src/BC5/BC5Decoder.h index 675c515..bf70b52 100644 --- a/src/BC5/BC5Decoder.h +++ b/src/BC5/BC5Decoder.h @@ -25,8 +25,8 @@ #include "../BC4/BC4Decoder.h" #include "../BlockDecoder.h" #include "../ColorBlock.h" -#include "../blocks.h" #include "../ndebug.h" +#include "BC5Block.h" namespace rgbcx { class BC5Decoder : public BlockDecoder { diff --git a/src/ColorBlock.h b/src/ColorBlock.h index 1152708..dfb9a3b 100644 --- a/src/ColorBlock.h +++ b/src/ColorBlock.h @@ -25,7 +25,7 @@ #include #include -#include "blocks.h" +#include "Color.h" template class ColorRow { public: diff --git a/src/rgbcx.cpp b/src/rgbcx.cpp index 2298d29..cb6a6e4 100644 --- a/src/rgbcx.cpp +++ b/src/rgbcx.cpp @@ -12,8 +12,8 @@ #include #include +#include "BC1/BC1Block.h" #include "Color.h" -#include "blocks.h" #include "tables.h" #include "util.h" diff --git a/src/rgbcx.h b/src/rgbcx.h index 9386346..da92b70 100644 --- a/src/rgbcx.h +++ b/src/rgbcx.h @@ -55,7 +55,10 @@ #include -#include "blocks.h" +#include "BC1/BC1Block.h" +#include "BC3/BC3Block.h" +#include "BC4/BC4Block.h" +#include "BC5/BC5Block.h" #include "interpolator.h" // By default, the table used to accelerate cluster fit on 4 color blocks uses a 969x128 entry table. diff --git a/src/test/test.cpp b/src/test/test.cpp index dd560d4..c43824f 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -17,7 +17,6 @@ #include #include -#include "../blocks.h" #include "../rgbcx.h" #include "../rgbcxDecoders.h" #include "../util.h" @@ -26,6 +25,8 @@ #include "dds_defs.h" #include "lodepng.h" +using namespace rgbcx; + const int MAX_UBER_LEVEL = 5; static int print_usage() {