/* 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, uint8_t mask = 0) { for (unsigned i = 0; i < 4; i++) { selectors[i] = mask ^ 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