diff --git a/src/BC1/BC1Decoder.cpp b/src/BC1/BC1Decoder.cpp index 860c734..23e276a 100644 --- a/src/BC1/BC1Decoder.cpp +++ b/src/BC1/BC1Decoder.cpp @@ -33,7 +33,7 @@ void BC1Decoder::DecodeBlock(Color4x4 dest, BC1Block *const block) const noexcep const auto l = block->GetLowColor(); const auto h = block->GetHighColor(); const auto selectors = block->UnpackSelectors(); - const auto colors = _interpolator.InterpolateBC1(l, h); + const auto colors = _interpolator->InterpolateBC1(l, h); for (unsigned y = 0; y < 4; y++) { for (unsigned x = 0; x < 4; x++) { diff --git a/src/BC1/BC1Decoder.h b/src/BC1/BC1Decoder.h index 741cd26..8defd16 100644 --- a/src/BC1/BC1Decoder.h +++ b/src/BC1/BC1Decoder.h @@ -19,24 +19,28 @@ #pragma once +#include + #include "../BlockDecoder.h" +#include "../ColorBlock.h" #include "../blocks.h" #include "../interpolator.h" #include "../ndebug.h" -#include "../ColorBlock.h" namespace rgbcx { class BC1Decoder final : public BlockDecoder { public: - BC1Decoder(const Interpolator &interpolator = Interpolator(), bool write_alpha = false) : _interpolator(interpolator), _write_alpha(write_alpha) {} + using InterpolatorPtr = std::shared_ptr; + BC1Decoder(const InterpolatorPtr interpolator = std::make_shared(), bool write_alpha = false) + : _interpolator(interpolator), _write_alpha(write_alpha) {} void DecodeBlock(Color4x4 dest, BC1Block *const block) const noexcept(ndebug) override; - constexpr const Interpolator &GetInterpolator() const { return _interpolator; } + InterpolatorPtr GetInterpolator() const { return _interpolator; } constexpr bool WritesAlpha() const { return _write_alpha; } private: - const Interpolator &_interpolator; + const InterpolatorPtr _interpolator; const bool _write_alpha; }; } // namespace rgbcx diff --git a/src/BC3/BC3Decoder.cpp b/src/BC3/BC3Decoder.cpp index c343eb6..6c3d423 100644 --- a/src/BC3/BC3Decoder.cpp +++ b/src/BC3/BC3Decoder.cpp @@ -28,7 +28,7 @@ namespace rgbcx { 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); + _bc1_decoder->DecodeBlock(dest, &(block->color_block)); + _bc4_decoder->DecodeBlock(dest, &(block->alpha_block), 3); } } // namespace rgbcx \ No newline at end of file diff --git a/src/BC3/BC3Decoder.h b/src/BC3/BC3Decoder.h index 1520fc7..f913148 100644 --- a/src/BC3/BC3Decoder.h +++ b/src/BC3/BC3Decoder.h @@ -19,6 +19,8 @@ #pragma once +#include + #include "../BC1/BC1Decoder.h" #include "../BC4/BC4Decoder.h" #include "../BlockDecoder.h" @@ -30,13 +32,17 @@ namespace rgbcx { class BC3Decoder : public BlockDecoder { public: - BC3Decoder(const Interpolator &interpolator = Interpolator()) : BC3Decoder(BC1Decoder(interpolator, false)) {} - BC3Decoder(const BC1Decoder &bc1_decoder, const BC4Decoder &bc4_decoder = BC4Decoder()) : _bc1_decoder(bc1_decoder), _bc4_decoder(bc4_decoder) {} + using InterpolatorPtr = std::shared_ptr; + using BC1DecoderPtr = std::shared_ptr; + using BC4DecoderPtr = std::shared_ptr; + + BC3Decoder(InterpolatorPtr interpolator = std::make_shared()) : BC3Decoder(std::make_shared(interpolator)) {} + BC3Decoder(BC1DecoderPtr bc1_decoder, BC4DecoderPtr bc4_decoder = std::make_shared()) : _bc1_decoder(bc1_decoder), _bc4_decoder(bc4_decoder) {} void DecodeBlock(Color4x4 dest, BC3Block *const block) const noexcept(ndebug) override; private: - const BC1Decoder &_bc1_decoder; - const BC4Decoder &_bc4_decoder; + const BC1DecoderPtr _bc1_decoder; + const BC4DecoderPtr _bc4_decoder; }; } // namespace rgbcx diff --git a/src/BC5/BC5Decoder.cpp b/src/BC5/BC5Decoder.cpp index 75310d5..22aa723 100644 --- a/src/BC5/BC5Decoder.cpp +++ b/src/BC5/BC5Decoder.cpp @@ -27,7 +27,7 @@ namespace rgbcx { void BC5Decoder::DecodeBlock(Color4x4 dest, BC5Block *const block) const noexcept(ndebug) { - _bc4_decoder.DecodeBlock(dest, &block->chan0_block, _chan0); - _bc4_decoder.DecodeBlock(dest, &block->chan1_block, _chan1); + _bc4_decoder->DecodeBlock(dest, &block->chan0_block, _chan0); + _bc4_decoder->DecodeBlock(dest, &block->chan1_block, _chan1); } } // namespace rgbcx \ No newline at end of file diff --git a/src/BC5/BC5Decoder.h b/src/BC5/BC5Decoder.h index 7da6579..675c515 100644 --- a/src/BC5/BC5Decoder.h +++ b/src/BC5/BC5Decoder.h @@ -20,18 +20,21 @@ #pragma once #include +#include #include "../BC4/BC4Decoder.h" #include "../BlockDecoder.h" #include "../ColorBlock.h" -#include "../ndebug.h" #include "../blocks.h" +#include "../ndebug.h" namespace rgbcx { class BC5Decoder : public BlockDecoder { public: - BC5Decoder(size_t chan0 = 0, size_t chan1 = 1) : BC5Decoder(BC4Decoder(), chan0, chan1) {} - BC5Decoder(const BC4Decoder &bc4_decoder, size_t chan0 = 0, size_t chan1 = 1) : _bc4_decoder(bc4_decoder), _chan0(chan0), _chan1(chan1) {} + using BC4DecoderPtr = std::shared_ptr; + + BC5Decoder(size_t chan0 = 0, size_t chan1 = 1) : BC5Decoder(std::make_shared(), chan0, chan1) {} + BC5Decoder(BC4DecoderPtr bc4_decoder, size_t chan0 = 0, size_t chan1 = 1) : _bc4_decoder(bc4_decoder), _chan0(chan0), _chan1(chan1) {} void DecodeBlock(Color4x4 dest, BC5Block *const block) const noexcept(ndebug) override; @@ -39,7 +42,7 @@ class BC5Decoder : public BlockDecoder { constexpr size_t GetChannel1() const { return _chan1; } private: - const BC4Decoder &_bc4_decoder; + const BC4DecoderPtr _bc4_decoder; const size_t _chan0; const size_t _chan1; }; diff --git a/src/Color.h b/src/Color.h index 1ffa8a4..6544633 100644 --- a/src/Color.h +++ b/src/Color.h @@ -56,7 +56,7 @@ class Color { void SetRGBA(const Color &other) { SetRGBA(other.r, other.g, other.b, other.a); } void SetRGB(uint8_t vr, uint8_t vg, uint8_t vb); - void SetRGB(const Color &other) { SetRGB(other.r, other.g, other.a); } + void SetRGB(const Color &other) { SetRGB(other.r, other.g, other.b); } uint16_t pack565(); uint16_t pack565Unscaled(); @@ -67,6 +67,6 @@ class Color { static Color min(const Color &A, const Color &B); static Color max(const Color &A, const Color &B); - unsigned get_luma() const { return (13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U; } // REC709 weightings + int get_luma() const { return (13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U; } // REC709 weightings }; #pragma pack(pop) \ No newline at end of file diff --git a/src/test/test.cpp b/src/test/test.cpp index 3c5a749..dd560d4 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -264,9 +264,11 @@ class image_metrics { const color_quad_u8 &ca = a(x, y); const color_quad_u8 &cb = b(x, y); - if (!num_channels) - hist[iabs(ca.get_luma() - cb.get_luma())]++; - else { + if (!num_channels) { +// int luma_diff = ; + unsigned index = iabs(ca.get_luma() - cb.get_luma()); + hist[index]++; + } else { for (uint32_t c = 0; c < num_channels; c++) hist[iabs(ca[first_channel + c] - cb[first_channel + c])]++; } } diff --git a/src/util.h b/src/util.h index 438bec2..3c6d495 100644 --- a/src/util.h +++ b/src/util.h @@ -38,6 +38,7 @@ template constexpr void Assert6Bit(S x) { } template constexpr auto iabs(S i) { + static_assert(!std::is_unsigned::value); using O = typename std::make_unsigned::type; return (i < 0) ? static_cast(-i) : static_cast(i); }