namespace and binding changes

hotfix/mipmap-alpha-fix
Andrew Cassidy 3 years ago
parent f72b794d20
commit 8f1e76bb43

@ -30,10 +30,7 @@ file(GLOB HEADER_FILES
file(GLOB TEST_FILES "tests/*.cpp")
set(PYTHON_FILES
"quicktex/bindings/Module.cpp"
"quicktex/s3tc/bindings/Decoders.cpp"
"quicktex/s3tc/bindings/Encoders.cpp")
file(GLOB_RECURSE PYTHON_FILES "src/**/*.py")
# Organize source files together for some IDEs
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES} ${HEADER_FILES} ${PYTHON_FILES})
@ -41,8 +38,7 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES} ${HEADER_FIL
# Add python module
pybind11_add_module(_quicktex
${SOURCE_FILES}
${HEADER_FILES}
${PYTHON_FILES})
${HEADER_FILES})
add_executable(test_quicktex
${SOURCE_FILES}

@ -25,9 +25,9 @@
#include <span>
#include <vector>
#include "../BlockView.h"
#include "../ndebug.h"
#include "../util.h"
#include "BlockView.h"
#include "ndebug.h"
#include "util.h"
namespace quicktex {

@ -24,7 +24,7 @@
#include <memory>
#include <string>
#include "../BlockView.h"
#include "BlockView.h"
namespace quicktex {

@ -18,22 +18,35 @@
*/
#include <pybind11/pybind11.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include "../../BlockDecoder.h"
#include "../bc1/BC1Decoder.h"
#include "../bc3/BC3Decoder.h"
#include "../bc4/BC4Decoder.h"
#include "../bc5/BC5Decoder.h"
#include "BlockEncoder.h"
#include "BlockDecoder.h"
namespace py = pybind11;
namespace quicktex::bindings {
void InitS3TC(py::module_ &m);
py::bytes EncodeImage(const BlockEncoder &self, py::bytes decoded, unsigned image_width, unsigned image_height) {
if (image_width % self.BlockWidth() != 0) throw std::invalid_argument("Width is not an even multiple of block_width");
if (image_height % self.BlockHeight() != 0) throw std::invalid_argument("Height is not an even multiple of block_height");
if (image_width == 0 || image_height == 0) throw std::invalid_argument("Image has zero size");
size_t size = image_width * image_height;
size_t block_size = (size / (self.BlockHeight() * self.BlockWidth())) * self.BlockSize();
size_t color_size = size * sizeof(Color);
std::string encoded_str = std::string(block_size, 0);
std::string decoded_str = (std::string)decoded; // decoded data is copied here, unfortunately
if (decoded_str.size() != color_size) throw std::invalid_argument("Incompatible data: image width and height do not match the size of the decoded image");
self.EncodeImage(reinterpret_cast<uint8_t *>(encoded_str.data()), reinterpret_cast<Color *>(decoded_str.data()), image_width, image_height);
auto bytes = py::bytes(encoded_str); // encoded data is copied here, unfortunately
return bytes;
}
py::bytes DecodeImage(const BlockDecoder &self, py::bytes encoded, unsigned image_width, unsigned image_height) {
if (image_width % self.BlockWidth() != 0) throw std::invalid_argument("Width is not an even multiple of block_width");
if (image_height % self.BlockHeight() != 0) throw std::invalid_argument("Height is not an even multiple of block_height");
@ -55,7 +68,9 @@ py::bytes DecodeImage(const BlockDecoder &self, py::bytes encoded, unsigned imag
return bytes;
}
void InitDecoders(py::module_ &m) {
PYBIND11_MODULE(_quicktex, m) {
m.doc() = "More Stuff";
// BlockDecoder
py::class_<BlockDecoder> block_decoder(m, "BlockDecoder");
@ -64,32 +79,15 @@ void InitDecoders(py::module_ &m) {
block_decoder.def_property_readonly("block_width", &BlockDecoder::BlockWidth);
block_decoder.def_property_readonly("block_height", &BlockDecoder::BlockHeight);
// BC1Decoder
py::class_<BC1Decoder> bc1_decoder(m, "BC1Decoder", block_decoder);
bc1_decoder.def(py::init<Interpolator::Type, bool>(), py::arg("interpolator") = Interpolator::Type::Ideal, py::arg("write_alpha") = false);
bc1_decoder.def_property_readonly("interpolator_type", &BC1Decoder::GetInterpolatorType);
bc1_decoder.def_readwrite("write_alpha", &BC1Decoder::write_alpha);
// BC3Decoder
py::class_<BC3Decoder> bc3_decoder(m, "BC3Decoder", block_decoder);
bc3_decoder.def(py::init<Interpolator::Type>(), py::arg("type") = Interpolator::Type::Ideal);
bc3_decoder.def_property_readonly("bc1_decoder", &BC3Decoder::GetBC1Decoder);
bc3_decoder.def_property_readonly("bc4_decoder", &BC3Decoder::GetBC4Decoder);
// BC4Decoder
py::class_<BC4Decoder> bc4_decoder(m, "BC4Decoder", block_decoder);
bc4_decoder.def(py::init<uint8_t>(), py::arg("channel") = 3);
bc4_decoder.def_property("channel", &BC4Decoder::GetChannel, &BC4Decoder::SetChannel);
// BlockEncoder
py::class_<BlockEncoder> block_encoder(m, "BlockEncoder");
// BC5Decoder
py::class_<BC5Decoder> bc5_decoder(m, "BC5Decoder", block_decoder);
block_encoder.def("encode_image", &EncodeImage);
block_encoder.def_property_readonly("block_size", &BlockEncoder::BlockSize);
block_encoder.def_property_readonly("block_width", &BlockEncoder::BlockWidth);
block_encoder.def_property_readonly("block_height", &BlockEncoder::BlockHeight);
bc5_decoder.def(py::init<uint8_t, uint8_t>(), py::arg("chan0") = 0, py::arg("chan1") = 1);
bc5_decoder.def_property("channels", &BC5Decoder::GetChannels, &BC5Decoder::SetChannels);
bc5_decoder.def_property_readonly("bc4_decoders", &BC5Decoder::GetBC4Decoders);
InitS3TC(m);
}
} // namespace quicktex::bindings

@ -26,67 +26,7 @@
#include "../util.h"
namespace quicktex {
/*
Interpolator::Interpolator() {
PrepSingleColorTables(_single_match5, _single_match5_half, 5);
PrepSingleColorTables(_single_match5, _single_match5_half, 6);
}
void Interpolator::PrepSingleColorTables(const MatchListPtr &matchTable, const MatchListPtr &matchTableHalf, int len) {
int size = 1 << len;
assert((len == 5 && size == Size5) || (len == 6 && size == size6));
const uint8_t *expand = (len == 5) ? &Expand5[0] : &Expand6[0];
bool ideal = IsIdeal();
bool use_e = useExpandedInMatch();
for (int i = 0; i < match_count; i++) {
int lowest_error = 256;
int lowest_half_error = 256;
for (int low = 0; low < size; low++) {
const int low_e = expand[low];
const int low_val = use_e ? low_e : low;
for (int high = 0; high < size; high++) {
const int high_e = expand[high];
const int high_val = use_e ? high_e : high;
int v = (len == 5) ? Interpolate5(high_val, low_val) : Interpolate6(high_val, low_val);
int v_half = (len == 5) ? InterpolateHalf5(low_val, high_val) : InterpolateHalf6(low_val, high_val);
int error = PrepSingleColorTableEntry(matchTable, v, i, low, high, low_e, high_e, lowest_error, false, ideal);
int half_error = PrepSingleColorTableEntry(matchTableHalf, v, i, low, high, low_e, high_e, lowest_error, true, ideal);
if (error < lowest_error) lowest_error = error;
if (half_error < lowest_half_error) lowest_half_error = half_error;
}
}
}
}
int Interpolator::PrepSingleColorTableEntry(const MatchListPtr &matchTable, int v, int i, int low, int high, int low_e, int high_e, int lowest_error, bool half,
bool ideal) {
int e = iabs(v - i);
// We only need to factor in 3% error in BC1 ideal mode.
if (ideal) e += (iabs(high_e - low_e) * 3) / 100;
// Favor equal endpoints, for lower error on actual GPU's which approximate the interpolation.
if ((e < lowest_error) || (e == lowest_error && low == high)) {
assert(e <= UINT8_MAX);
auto &entry = (*matchTable)[i];
entry.low = low;
entry.high = high;
entry.error = e;
}
return e;
}*/
namespace quicktex::s3tc {
// region Interpolator implementation
std::unique_ptr<Interpolator> Interpolator::MakeInterpolator(Interpolator::Type type) {
@ -196,4 +136,4 @@ uint8_t InterpolatorAMD::Interpolate8(uint8_t v0, uint8_t v1) const { return (v0
uint8_t InterpolatorAMD::InterpolateHalf8(uint8_t v0, uint8_t v1) const { return (v0 + v1 + 1) >> 1; }
// endregion
} // namespace quicktex
} // namespace quicktex::s3tc

@ -24,7 +24,7 @@
#include "../Color.h" // for Color
namespace quicktex {
namespace quicktex::s3tc {
class Interpolator {
public:
@ -171,4 +171,4 @@ class InterpolatorAMD : public Interpolator {
Type GetType() const noexcept override { return Type::AMD; }
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -0,0 +1 @@
from _quicktex._s3tc import *

@ -19,26 +19,32 @@
#include <pybind11/pybind11.h>
#include "../s3tc/Interpolator.h"
#include "Interpolator.h"
namespace py = pybind11;
namespace quicktex::bindings {
void InitEncoders(py::module_ &m);
void InitDecoders(py::module_ &m);
using namespace quicktex;
using namespace quicktex::s3tc;
PYBIND11_MODULE(_quicktex, m) {
m.doc() = "More Stuff";
void InitBC1(py::module_ &s3tc);
void InitBC3(py::module_ &s3tc);
void InitBC4(py::module_ &s3tc);
void InitBC5(py::module_ &s3tc);
void InitS3TC(py::module_ &m) {
py::module_ s3tc = m.def_submodule("_s3tc", "s3tc compression library based on rgbcx.h written by Richard Goldreich");
using IType = Interpolator::Type;
py::enum_<IType>(m, "InterpolatorType")
py::enum_<IType>(s3tc, "InterpolatorType")
.value("Ideal", IType::Ideal)
.value("IdealRound", IType::IdealRound)
.value("Nvidia", IType::Nvidia)
.value("AMD", IType::AMD);
InitEncoders(m);
InitDecoders(m);
InitBC1(s3tc);
InitBC3(s3tc);
InitBC4(s3tc);
InitBC5(s3tc);
}
} // namespace quicktex::bindings
} // namespace quicktex::bindings

@ -27,7 +27,7 @@
#include "../../Color.h"
#include "../../util.h"
namespace quicktex {
namespace quicktex::s3tc {
#pragma pack(push, 1)
class BC1Block {
@ -82,4 +82,4 @@ class BC1Block {
std::array<uint8_t, 4> selectors;
};
#pragma pack(pop)
} // namespace quicktex
} // namespace quicktex::s3tc

@ -28,7 +28,7 @@
#include "../../ndebug.h"
#include "BC1Block.h"
namespace quicktex {
namespace quicktex::s3tc {
void BC1Decoder::DecodeBlock(Color4x4 dest, BC1Block *const block) const noexcept(ndebug) {
const auto l = block->GetLowColor();
const auto h = block->GetHighColor();
@ -49,4 +49,4 @@ void BC1Decoder::DecodeBlock(Color4x4 dest, BC1Block *const block) const noexcep
}
}
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -28,7 +28,7 @@
#include "../Interpolator.h"
#include "BC1Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC1Decoder final : public BlockDecoderTemplate<BC1Block, 4, 4> {
public:
using InterpolatorPtr = std::shared_ptr<Interpolator>;
@ -45,4 +45,4 @@ class BC1Decoder final : public BlockDecoderTemplate<BC1Block, 4, 4> {
private:
const InterpolatorPtr _interpolator;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -39,8 +39,7 @@
#include "OrderTable.h"
#include "SingleColorTable.h"
namespace quicktex {
using namespace BC1;
namespace quicktex::s3tc {
// constructors
@ -941,4 +940,4 @@ void BC1Encoder::EndpointSearch(Color4x4 &pixels, EncodeResults &block) const {
}
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -35,6 +35,9 @@
namespace quicktex {
class Vector4;
}
namespace quicktex::s3tc {
class BC1Encoder final : public BlockEncoderTemplate<BC1Block, 4, 4> {
public:
@ -165,10 +168,10 @@ class BC1Encoder final : public BlockEncoderTemplate<BC1Block, 4, 4> {
// Each entry includes a high and low pair that best reproduces the 8-bit index as well as possible,
// with an included error value
// these depend on the interpolator
const BC1::MatchListPtr _single_match5 = BC1::SingleColorTable<5, 4>(_interpolator);
const BC1::MatchListPtr _single_match6 = BC1::SingleColorTable<6, 4>(_interpolator);
const BC1::MatchListPtr _single_match5_half = BC1::SingleColorTable<5, 3>(_interpolator);
const BC1::MatchListPtr _single_match6_half = BC1::SingleColorTable<6, 3>(_interpolator);
const MatchListPtr _single_match5 = SingleColorTable<5, 4>(_interpolator);
const MatchListPtr _single_match6 = SingleColorTable<6, 4>(_interpolator);
const MatchListPtr _single_match5_half = SingleColorTable<5, 3>(_interpolator);
const MatchListPtr _single_match6_half = SingleColorTable<6, 3>(_interpolator);
Flags _flags;
ErrorMode _error_mode;
@ -196,4 +199,4 @@ class BC1Encoder final : public BlockEncoderTemplate<BC1Block, 4, 4> {
void EndpointSearch(Color4x4 &pixels, EncodeResults &block) const;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -30,7 +30,7 @@
#include "../../Vector4.h"
#include "../../util.h"
namespace quicktex::BC1 {
namespace quicktex::s3tc {
template <size_t N> class Histogram {
public:
using Hash = uint16_t;
@ -82,4 +82,4 @@ template <size_t N> class Histogram {
private:
std::array<uint8_t, N> _bins;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -23,7 +23,7 @@
#include "../../Vector4.h"
namespace quicktex::BC1 {
namespace quicktex::s3tc {
using Hash = uint16_t;
template <> std::atomic<bool> OrderTable<3>::generated = false;
@ -324,4 +324,4 @@ const OrderTable<3>::BestOrderArray OrderTable<3>::BestOrders = {
template class OrderTable<3>;
template class OrderTable<4>;
} // namespace quicktex
} // namespace quicktex::s3tc

@ -31,7 +31,7 @@
#include "../../Vector4.h"
#include "Histogram.h"
namespace quicktex::BC1 {
namespace quicktex::s3tc {
template <size_t N> class OrderTable {
public:
static constexpr unsigned HashCount = 1 << ((N - 1) * 4); // 16**(N-1)
@ -147,4 +147,4 @@ template <> const OrderTable<4>::BestOrderArray OrderTable<4>::BestOrders;
extern template class OrderTable<3>;
extern template class OrderTable<4>;
} // namespace quicktex::BC1
} // namespace quicktex::s3tc

@ -20,7 +20,7 @@
#include "OrderTable.h"
// clang-format off
namespace quicktex::BC1 {
namespace quicktex::s3tc {
template <>
const OrderTable<4>::BestOrderArray OrderTable<4>::BestOrders = {{
@ -1966,5 +1966,5 @@ const OrderTable<4>::BestOrderArray OrderTable<4>::BestOrders = {{
{ 15,341,13,33,23,77,141,4,0,351,1,260,102,51,82,9,40,349,854,11,115,217,269,137,180,202,922,5,901,22,10,117,21,365,318,197,120,352,64,12,7,153,177,59,291,32,128,2,165,196,372,36,403,317,457,28,18,8,16,304,30,14,450,31,898,37,3,752,48,134,139,494,421,6,453,401,719,90,86,569,523,110,24,55,475,210,49,44,386,17,730,95,247,244,961,143,125,308,342,817,629,98,498,93,96,76,39,275,509,326,99,285,373,57,237,35,402,160,111,253,105,391,221,116,899,72,127,661 }
#endif
}};
} // namespace quicktex::BC1
} // namespace quicktex::s3tc ::BC1
// clang-format on

@ -26,7 +26,7 @@
#include "../../util.h"
#include "../Interpolator.h"
namespace quicktex::BC1 {
namespace quicktex::s3tc {
struct BC1MatchEntry {
uint8_t high;
@ -90,4 +90,4 @@ template <size_t B, size_t N> MatchListPtr SingleColorTable(InterpolatorPtr inte
}
return matches;
}
} // namespace quicktex::BC1
} // namespace quicktex::s3tc

@ -0,0 +1 @@
from _quicktex._s3tc._bc1 import *

@ -19,57 +19,31 @@
#include <pybind11/pybind11.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include "../../BlockDecoder.h"
#include "../../BlockEncoder.h"
#include "../../Color.h"
#include "../Interpolator.h"
#include "../bc1/BC1Encoder.h"
#include "../bc3/BC3Encoder.h"
#include "../bc4/BC4Encoder.h"
#include "../bc5/BC5Encoder.h"
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
#include "BC1Decoder.h"
#include "BC1Encoder.h"
namespace py = pybind11;
namespace quicktex::bindings {
py::bytes EncodeImage(const BlockEncoder &self, py::bytes decoded, unsigned image_width, unsigned image_height) {
if (image_width % self.BlockWidth() != 0) throw std::invalid_argument("Width is not an even multiple of block_width");
if (image_height % self.BlockHeight() != 0) throw std::invalid_argument("Height is not an even multiple of block_height");
if (image_width == 0 || image_height == 0) throw std::invalid_argument("Image has zero size");
size_t size = image_width * image_height;
size_t block_size = (size / (self.BlockHeight() * self.BlockWidth())) * self.BlockSize();
size_t color_size = size * sizeof(Color);
std::string encoded_str = std::string(block_size, 0);
std::string decoded_str = (std::string)decoded; // decoded data is copied here, unfortunately
if (decoded_str.size() != color_size) throw std::invalid_argument("Incompatible data: image width and height do not match the size of the decoded image");
self.EncodeImage(reinterpret_cast<uint8_t *>(encoded_str.data()), reinterpret_cast<Color *>(decoded_str.data()), image_width, image_height);
auto bytes = py::bytes(encoded_str); // encoded data is copied here, unfortunately
return bytes;
}
void InitEncoders(py::module_ &m) {
// BlockEncoder
py::class_<BlockEncoder> block_encoder(m, "BlockEncoder");
using namespace quicktex::s3tc;
using namespace quicktex::s3tc ;
block_encoder.def("encode_image", &EncodeImage);
block_encoder.def_property_readonly("block_size", &BlockEncoder::BlockSize);
block_encoder.def_property_readonly("block_width", &BlockEncoder::BlockWidth);
block_encoder.def_property_readonly("block_height", &BlockEncoder::BlockHeight);
void InitBC1(py::module_ &s3tc) {
auto bc1 = s3tc.def_submodule("_bc1", "BC1 encoding/decoding module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
// BC1Encoder
py::class_<BC1Encoder> bc1_encoder(m, "BC1Encoder", block_encoder);
py::class_<BC1Encoder> bc1_encoder(bc1, "BC1Encoder", block_encoder);
bc1_encoder.def(py::init<Interpolator::Type, unsigned, bool, bool>(), py::arg("interpolator") = Interpolator::Type::Ideal, py::arg("level") = 5,
py::arg("use_3color") = true, py::arg("use_3color_black") = true);
@ -112,25 +86,11 @@ void InitEncoders(py::module_ &m) {
.value("Check2", BC1Encoder::ErrorMode::Check2)
.value("Full", BC1Encoder::ErrorMode::Full);
// BC3Encoder
py::class_<BC3Encoder> bc3_encoder(m, "BC3Encoder", block_encoder);
bc3_encoder.def(py::init<Interpolator::Type, unsigned, bool, bool>(), 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_<BC4Encoder> bc4_encoder(m, "BC4Encoder", block_encoder);
bc4_encoder.def(py::init<uint8_t>(), py::arg("channel") = 3);
bc4_encoder.def_property("channel", &BC4Encoder::GetChannel, &BC4Encoder::SetChannel);
// BC5Encoder
py::class_<BC5Encoder> bc5_encoder(m, "BC5Encoder", block_encoder);
// BC1Decoder
py::class_<BC1Decoder> bc1_decoder(bc1, "BC1Decoder", block_decoder);
bc5_encoder.def(py::init<uint8_t, uint8_t>(), 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);
bc1_decoder.def(py::init<Interpolator::Type, bool>(), py::arg("interpolator") = Interpolator::Type::Ideal, py::arg("write_alpha") = false);
bc1_decoder.def_property_readonly("interpolator_type", &BC1Decoder::GetInterpolatorType);
bc1_decoder.def_readwrite("write_alpha", &BC1Decoder::write_alpha);
}
} // namespace quicktex::bindings

@ -19,10 +19,10 @@
#pragma once
#include "../../s3tc/bc1/BC1Block.h"
#include "BC4Block.h"
#include "../bc1/BC1Block.h"
#include "../bc4/BC4Block.h"
namespace quicktex {
namespace quicktex::s3tc {
#pragma pack(push, 1)
class BC3Block {
@ -31,4 +31,4 @@ class BC3Block {
BC1Block color_block;
};
#pragma pack(pop)
} // namespace quicktex
} // namespace quicktex::s3tc

@ -25,10 +25,10 @@
#include "../../ndebug.h"
#include "BC3Block.h"
namespace quicktex {
namespace quicktex::s3tc {
void BC3Decoder::DecodeBlock(Color4x4 dest, BC3Block *const block) const noexcept(ndebug) {
_bc1_decoder->DecodeBlock(dest, &(block->color_block));
_bc4_decoder->DecodeBlock(dest, &(block->alpha_block), 3);
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -29,7 +29,8 @@
#include "../bc4/BC4Decoder.h"
#include "BC3Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC3Decoder : public BlockDecoderTemplate<BC3Block, 4, 4> {
public:
using BC1DecoderPtr = std::shared_ptr<BC1Decoder>;
@ -47,4 +48,4 @@ class BC3Decoder : public BlockDecoderTemplate<BC3Block, 4, 4> {
const BC1DecoderPtr _bc1_decoder;
const BC4DecoderPtr _bc4_decoder;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -22,9 +22,9 @@
#include "../../BlockView.h"
#include "BC3Block.h"
namespace quicktex {
namespace quicktex::s3tc {
void BC3Encoder::EncodeBlock(Color4x4 pixels, BC3Block *dest) const {
_bc1_encoder->EncodeBlock(pixels, &(dest->color_block));
_bc4_encoder->EncodeBlock(pixels, &(dest->alpha_block), 3);
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -28,7 +28,7 @@
#include "../bc4/BC4Encoder.h"
#include "BC3Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC3Encoder : public BlockEncoderTemplate<BC3Block, 4, 4> {
public:
@ -47,4 +47,4 @@ class BC3Encoder : public BlockEncoderTemplate<BC3Block, 4, 4> {
const BC1EncoderPtr _bc1_encoder;
const BC4EncoderPtr _bc4_encoder;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -0,0 +1 @@
from _quicktex._s3tc._bc3 import *

@ -0,0 +1,60 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
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 <http://www.gnu.org/licenses/>.
*/
#include <pybind11/pybind11.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include "../../BlockDecoder.h"
#include "../../BlockEncoder.h"
#include "../Interpolator.h"
#include "BC3Decoder.h"
#include "BC3Encoder.h"
namespace py = pybind11;
namespace quicktex::bindings {
using namespace quicktex::s3tc;
using namespace quicktex::s3tc ;
void InitBC3(py::module_ &s3tc) {
auto bc3 = s3tc.def_submodule("_bc3", "BC3 encoding/decoding module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
// BC3Encoder
py::class_<BC3Encoder> bc3_encoder(bc3, "BC3Encoder", block_encoder);
bc3_encoder.def(py::init<Interpolator::Type, unsigned, bool, bool>(), 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);
// BC3Decoder
py::class_<BC3Decoder> bc3_decoder(bc3, "BC3Decoder", block_decoder);
bc3_decoder.def(py::init<Interpolator::Type>(), py::arg("type") = Interpolator::Type::Ideal);
bc3_decoder.def_property_readonly("bc1_decoder", &BC3Decoder::GetBC1Decoder);
bc3_decoder.def_property_readonly("bc4_decoder", &BC3Decoder::GetBC4Decoder);
};
} // namespace quicktex::bindings

@ -28,7 +28,7 @@
#include "../../util.h"
#include "../bc1/BC1Block.h"
namespace quicktex {
namespace quicktex::s3tc {
#pragma pack(push, 1)
class BC4Block {
@ -119,4 +119,4 @@ class BC4Block {
std::array<uint8_t, SelectorSize> selectors;
};
#pragma pack(pop)
} // namespace quicktex
} // namespace quicktex::s3tc

@ -26,7 +26,8 @@
#include "../../ndebug.h" // for ndebug
#include "BC4Block.h"
void quicktex::BC4Decoder::DecodeBlock(Byte4x4 dest, BC4Block *const block) const noexcept(ndebug) {
namespace quicktex::s3tc {
void BC4Decoder::DecodeBlock(Byte4x4 dest, BC4Block *const block) const noexcept(ndebug) {
auto l = block->GetLowAlpha();
auto h = block->GetHighAlpha();
@ -41,3 +42,4 @@ void quicktex::BC4Decoder::DecodeBlock(Byte4x4 dest, BC4Block *const block) cons
}
}
}
} // namespace quicktex::s3tc

@ -28,7 +28,7 @@
#include "../../ndebug.h"
#include "BC4Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC4Decoder : public BlockDecoderTemplate<BC4Block, 4, 4> {
public:
BC4Decoder(uint8_t channel = 3) { SetChannel(channel); }
@ -46,4 +46,4 @@ class BC4Decoder : public BlockDecoderTemplate<BC4Block, 4, 4> {
private:
uint8_t _channel;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -28,7 +28,7 @@
#include "../../ndebug.h"
#include "BC4Block.h"
namespace quicktex {
namespace quicktex::s3tc {
void BC4Encoder::EncodeBlock(Byte4x4 pixels, BC4Block *const dest) const noexcept(ndebug) {
auto flattened = pixels.Flatten();
auto minmax = std::minmax_element(flattened.begin(), flattened.end());
@ -70,4 +70,4 @@ void BC4Encoder::EncodeBlock(Byte4x4 pixels, BC4Block *const dest) const noexcep
dest->PackSelectors(selectors);
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -28,7 +28,7 @@
#include "../../ndebug.h"
#include "BC4Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC4Encoder : public BlockEncoderTemplate<BC4Block, 4, 4> {
public:
@ -47,4 +47,4 @@ class BC4Encoder : public BlockEncoderTemplate<BC4Block, 4, 4> {
private:
uint8_t _channel;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -0,0 +1 @@
from _quicktex._s3tc._bc4 import *

@ -0,0 +1,57 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
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 <http://www.gnu.org/licenses/>.
*/
#include <pybind11/pybind11.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include "../../BlockDecoder.h"
#include "../../BlockEncoder.h"
#include "BC4Decoder.h"
#include "BC4Encoder.h"
namespace py = pybind11;
namespace quicktex::bindings {
using namespace quicktex::s3tc;
using namespace quicktex::s3tc ;
void InitBC4(py::module_ &s3tc) {
auto bc4 = s3tc.def_submodule("_bc4", "BC4 encoding/decoding module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
// BC4Encoder
py::class_<BC4Encoder> bc4_encoder(bc4, "BC4Encoder", block_encoder);
bc4_encoder.def(py::init<uint8_t>(), py::arg("channel") = 3);
bc4_encoder.def_property("channel", &BC4Encoder::GetChannel, &BC4Encoder::SetChannel);
// BC4Decoder
py::class_<BC4Decoder> bc4_decoder(bc4, "BC4Decoder", block_decoder);
bc4_decoder.def(py::init<uint8_t>(), py::arg("channel") = 3);
bc4_decoder.def_property("channel", &BC4Decoder::GetChannel, &BC4Decoder::SetChannel);
}
} // namespace quicktex::bindings

@ -21,7 +21,7 @@
#include "../bc4/BC4Block.h"
namespace quicktex {
namespace quicktex::s3tc {
#pragma pack(push, 1)
class BC5Block {
@ -30,4 +30,4 @@ class BC5Block {
BC4Block chan1_block;
};
#pragma pack(pop)
} // namespace quicktex
} // namespace quicktex::s3tc

@ -23,10 +23,10 @@
#include "../../ndebug.h"
#include "BC5Block.h"
namespace quicktex {
namespace quicktex::s3tc {
void BC5Decoder::DecodeBlock(Color4x4 dest, BC5Block *const block) const noexcept(ndebug) {
_chan0_decoder->DecodeBlock(dest, &block->chan0_block);
_chan1_decoder->DecodeBlock(dest, &block->chan1_block);
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -30,7 +30,8 @@
#include "../bc4/BC4Decoder.h"
#include "BC5Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC5Decoder : public BlockDecoderTemplate<BC5Block, 4, 4> {
public:
using ChannelPair = std::tuple<uint8_t, uint8_t>;
@ -54,4 +55,4 @@ class BC5Decoder : public BlockDecoderTemplate<BC5Block, 4, 4> {
const BC4DecoderPtr _chan0_decoder;
const BC4DecoderPtr _chan1_decoder;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -19,9 +19,9 @@
#include "BC5Encoder.h"
namespace quicktex {
namespace quicktex::s3tc {
void BC5Encoder::EncodeBlock(Color4x4 pixels, BC5Block *dest) const {
_chan0_encoder->EncodeBlock(pixels, &(dest->chan0_block));
_chan1_encoder->EncodeBlock(pixels, &(dest->chan1_block));
}
} // namespace quicktex
} // namespace quicktex::s3tc

@ -30,7 +30,8 @@
#include "../bc4/BC4Encoder.h"
#include "BC5Block.h"
namespace quicktex {
namespace quicktex::s3tc {
class BC5Encoder : public BlockEncoderTemplate<BC5Block, 4, 4> {
public:
using ChannelPair = std::tuple<uint8_t, uint8_t>;
@ -54,4 +55,4 @@ class BC5Encoder : public BlockEncoderTemplate<BC5Block, 4, 4> {
const BC4EncoderPtr _chan0_encoder;
const BC4EncoderPtr _chan1_encoder;
};
} // namespace quicktex
} // namespace quicktex::s3tc

@ -0,0 +1 @@
from _quicktex._s3tc._bc5 import *

@ -0,0 +1,58 @@
/* Python-rgbcx Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
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 <http://www.gnu.org/licenses/>.
*/
#include <pybind11/pybind11.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <string>
#include "../../BlockDecoder.h"
#include "../../BlockEncoder.h"
#include "BC5Decoder.h"
#include "BC5Encoder.h"
namespace py = pybind11;
namespace quicktex::bindings {
using namespace quicktex::s3tc;
using namespace quicktex::s3tc ;
void InitBC5(py::module_ &s3tc) {
auto bc5 = s3tc.def_submodule("_bc5", "BC5 encoding/decoding module");
auto block_encoder = py::type::of<BlockEncoder>();
auto block_decoder = py::type::of<BlockDecoder>();
// BC5Encoder
py::class_<BC5Encoder> bc5_encoder(bc5, "BC5Encoder", block_encoder);
bc5_encoder.def(py::init<uint8_t, uint8_t>(), 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);
// BC5Decoder
py::class_<BC5Decoder> bc5_decoder(bc5, "BC5Decoder", block_decoder);
bc5_decoder.def(py::init<uint8_t, uint8_t>(), py::arg("chan0") = 0, py::arg("chan1") = 1);
bc5_decoder.def_property("channels", &BC5Decoder::GetChannels, &BC5Decoder::SetChannels);
bc5_decoder.def_property_readonly("bc4_decoders", &BC5Decoder::GetBC4Decoders);
}
} // namespace quicktex::bindings
Loading…
Cancel
Save