diff --git a/src/rgbcx/BC3/BC3Decoder.h b/src/rgbcx/BC3/BC3Decoder.h index 0119b6e..83e4773 100644 --- a/src/rgbcx/BC3/BC3Decoder.h +++ b/src/rgbcx/BC3/BC3Decoder.h @@ -32,7 +32,6 @@ namespace rgbcx { class BC3Decoder : public BlockDecoderTemplate { public: - using InterpolatorPtr = std::shared_ptr; using BC1DecoderPtr = std::shared_ptr; using BC4DecoderPtr = std::shared_ptr; diff --git a/src/rgbcx/BC3/BC3Encoder.cpp b/src/rgbcx/BC3/BC3Encoder.cpp new file mode 100644 index 0000000..3dc098a --- /dev/null +++ b/src/rgbcx/BC3/BC3Encoder.cpp @@ -0,0 +1,30 @@ +/* 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 . + */ + +#include "BC3Encoder.h" + +#include "../BlockView.h" +#include "BC3Block.h" + +namespace rgbcx { +void BC3Encoder::EncodeBlock(Color4x4 pixels, BC3Block *dest) const { + _bc1_encoder->EncodeBlock(pixels, &(dest->color_block)); + _bc4_encoder->EncodeBlock(pixels, &(dest->alpha_block), 3); +} +} // namespace rgbcx \ No newline at end of file diff --git a/src/rgbcx/BC3/BC3Encoder.h b/src/rgbcx/BC3/BC3Encoder.h new file mode 100644 index 0000000..6a0ba19 --- /dev/null +++ b/src/rgbcx/BC3/BC3Encoder.h @@ -0,0 +1,50 @@ +/* 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 "../BC1/BC1Encoder.h" +#include "../BC4/BC4Encoder.h" +#include "../BlockEncoder.h" +#include "../BlockView.h" +#include "../Interpolator.h" +#include "BC3Block.h" + +namespace rgbcx { + +class BC3Encoder : public BlockEncoderTemplate { + public: + using BC1EncoderPtr = std::shared_ptr; + using BC4EncoderPtr = std::shared_ptr; + + BC3Encoder(Interpolator::Type type = Interpolator::Type::Ideal, unsigned level = 5, bool allow_3color = true, bool allow_3color_black = true) + : _bc1_encoder(std::make_shared(type, level, allow_3color, allow_3color_black)), _bc4_encoder(std::make_shared(3)) {} + + void EncodeBlock(Color4x4 pixels, BC3Block *dest) const override; + + BC1EncoderPtr GetBC1Encoder() const { return _bc1_encoder; } + BC4EncoderPtr GetBC4Encoder() const { return _bc4_encoder; } + + private: + const BC1EncoderPtr _bc1_encoder; + const BC4EncoderPtr _bc4_encoder; +}; +} // namespace rgbcx diff --git a/src/rgbcx/BC4/BC4Decoder.h b/src/rgbcx/BC4/BC4Decoder.h index c05d285..33ea776 100644 --- a/src/rgbcx/BC4/BC4Decoder.h +++ b/src/rgbcx/BC4/BC4Decoder.h @@ -31,7 +31,7 @@ namespace rgbcx { class BC4Decoder : public BlockDecoderTemplate { public: - BC4Decoder(uint8_t channel = 3) : _channel(channel) { assert(channel < 4U); } + BC4Decoder(uint8_t channel = 3) { SetChannel(channel); } void DecodeBlock(Color4x4 dest, BC4Block *const block) const noexcept(ndebug) override { DecodeBlock(dest.GetChannel(_channel), block); } void DecodeBlock(Color4x4 dest, BC4Block *const block, uint8_t channel) const noexcept(ndebug) { DecodeBlock(dest.GetChannel(channel), block); } @@ -39,7 +39,7 @@ class BC4Decoder : public BlockDecoderTemplate { uint8_t GetChannel() const { return _channel; } void SetChannel(uint8_t channel) { - if (channel >= 4) throw std::invalid_argument("Channel out of range"); + if (channel >= 4U) throw std::invalid_argument("Channel out of range"); _channel = channel; } diff --git a/src/rgbcx/BC4/BC4Encoder.h b/src/rgbcx/BC4/BC4Encoder.h index b32308a..eb5b73b 100644 --- a/src/rgbcx/BC4/BC4Encoder.h +++ b/src/rgbcx/BC4/BC4Encoder.h @@ -31,13 +31,19 @@ namespace rgbcx { class BC4Encoder : public BlockEncoderTemplate { public: - BC4Encoder(const uint8_t channel) : _channel(channel) { assert(channel < 4); } + BC4Encoder(const uint8_t channel) { SetChannel(channel); } - void EncodeBlock(Color4x4 pixels, BC4Block *dest) const override { EncodeBlock(pixels.GetChannel(_channel), dest); } + void EncodeBlock(Color4x4 pixels, BC4Block *const dest) const override { EncodeBlock(pixels.GetChannel(_channel), dest); } void EncodeBlock(Color4x4 pixels, BC4Block *const dest, uint8_t channel) const noexcept(ndebug) { EncodeBlock(pixels.GetChannel(channel), dest); } void EncodeBlock(Byte4x4 pixels, BC4Block *const dest) const noexcept(ndebug); + uint8_t GetChannel() const { return _channel; } + void SetChannel(uint8_t channel) { + if (channel >= 4) throw std::invalid_argument("Channel out of range"); + _channel = channel; + } + private: - const uint8_t _channel; + uint8_t _channel; }; } // namespace rgbcx diff --git a/src/rgbcx/BC5/BC5Encoder.cpp b/src/rgbcx/BC5/BC5Encoder.cpp new file mode 100644 index 0000000..b20521c --- /dev/null +++ b/src/rgbcx/BC5/BC5Encoder.cpp @@ -0,0 +1,27 @@ +/* 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 . + */ + +#include "BC5Encoder.h" + +namespace rgbcx { +void BC5Encoder::EncodeBlock(Color4x4 pixels, BC5Block *dest) const { + _chan0_encoder->EncodeBlock(pixels, &(dest->chan0_block)); + _chan1_encoder->EncodeBlock(pixels, &(dest->chan1_block)); +} +} // namespace rgbcx \ No newline at end of file diff --git a/src/rgbcx/BC5/BC5Encoder.h b/src/rgbcx/BC5/BC5Encoder.h new file mode 100644 index 0000000..fb2de76 --- /dev/null +++ b/src/rgbcx/BC5/BC5Encoder.h @@ -0,0 +1,57 @@ +/* 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 "../BC4/BC4Encoder.h" +#include "../BlockEncoder.h" +#include "../BlockView.h" +#include "../ndebug.h" +#include "BC5Block.h" + +namespace rgbcx { +class BC5Encoder : public BlockEncoderTemplate { + public: + using ChannelPair = std::tuple; + using BC4EncoderPtr = std::shared_ptr; + using BC4EncoderPair = std::tuple; + + BC5Encoder(uint8_t chan0 = 0, uint8_t chan1 = 1) : BC5Encoder(std::make_shared(chan0), std::make_shared(chan1)) {} + BC5Encoder(BC4EncoderPtr chan0_encoder, BC4EncoderPtr chan1_encoder) : _chan0_encoder(chan0_encoder), _chan1_encoder(chan1_encoder) {} + + void EncodeBlock(Color4x4 pixels, BC5Block *dest) const override; + + ChannelPair GetChannels() const { return ChannelPair(_chan0_encoder->GetChannel(), _chan1_encoder->GetChannel()); } + void SetChannels(ChannelPair channels) { + _chan0_encoder->SetChannel(std::get<0>(channels)); + _chan1_encoder->SetChannel(std::get<1>(channels)); + } + + BC4EncoderPair GetBC4Encoders() const { return BC4EncoderPair(_chan0_encoder, _chan1_encoder); } + + private: + const BC4EncoderPtr _chan0_encoder; + const BC4EncoderPtr _chan1_encoder; +}; +} // namespace rgbcx diff --git a/src/rgbcx/bindings/Encoders.cpp b/src/rgbcx/bindings/Encoders.cpp index 632504e..f9dc3bc 100644 --- a/src/rgbcx/bindings/Encoders.cpp +++ b/src/rgbcx/bindings/Encoders.cpp @@ -25,6 +25,8 @@ #include #include "../BC1/BC1Encoder.h" +#include "../BC3/BC3Encoder.h" +#include "../BC5/BC5Encoder.h" #include "../BlockEncoder.h" #include "../Color.h" #include "../Interpolator.h" @@ -108,6 +110,26 @@ void InitEncoders(py::module_ &m) { .value("Faster", BC1Encoder::ErrorMode::Faster) .value("Check2", BC1Encoder::ErrorMode::Check2) .value("Full", BC1Encoder::ErrorMode::Full); -} + // BC3Encoder + py::class_ bc3_encoder(m, "BC3Encoder", block_encoder); + + bc3_encoder.def(py::init(), py::arg("interpolator") = Interpolator::Type::Ideal, py::arg("level") = 5, + py::arg("use_3color") = true, py::arg("use_3color_black") = true); + bc3_encoder.def_property_readonly("bc1_encoder", &BC3Encoder::GetBC1Encoder); + bc3_encoder.def_property_readonly("bc4_encoder", &BC3Encoder::GetBC4Encoder); + + // BC4Encoder + py::class_ bc4_encoder(m, "BC4Encoder", block_encoder); + + bc4_encoder.def(py::init(), py::arg("channel") = 3); + bc4_encoder.def_property("channel", &BC4Encoder::GetChannel, &BC4Encoder::SetChannel); + + // BC5Encoder + py::class_ bc5_encoder(m, "BC5Encoder", block_encoder); + + bc5_encoder.def(py::init(), py::arg("chan0") = 0, py::arg("chan1") = 1); + bc5_encoder.def_property("channels", &BC5Encoder::GetChannels, &BC5Encoder::SetChannels); + bc5_encoder.def_property_readonly("bc4_decoders", &BC5Encoder::GetBC4Encoders); +} } // namespace rgbcx::bindings \ No newline at end of file