diff --git a/src/color_transform.h b/src/color_transform.h index 876e0303..3cd48ca6 100644 --- a/src/color_transform.h +++ b/src/color_transform.h @@ -16,112 +16,112 @@ inline bool color_transformation_possible(const frame_info& frame) noexcept // They are invoked in process_line.h to convert between decoded values and the internal line buffers. // Color transforms work best for computer generated images, but are outside the official JPEG-LS specifications. -template +template struct transform_none_impl { - static_assert(std::is_integral_v, "Integral required."); + static_assert(std::is_integral_v, "Integral required."); - using size_type = T; + using sample_type = SampleType; - FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept + FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept { return {v1, v2, v3}; } - FORCE_INLINE quad operator()(const int v1, const int v2, const int v3, const int v4) const noexcept + FORCE_INLINE quad operator()(const int v1, const int v2, const int v3, const int v4) const noexcept { return {v1, v2, v3, v4}; } }; -template -struct transform_none final : transform_none_impl +template +struct transform_none final : transform_none_impl { - static_assert(std::is_integral_v, "Integral required."); + static_assert(std::is_integral_v, "Integral required."); - using inverse = transform_none_impl; + using inverse = transform_none_impl; }; -template +template struct transform_hp1 final { - static_assert(std::is_integral_v, "Integral required."); + static_assert(std::is_integral_v, "Integral required."); - using size_type = T; + using sample_type = SampleType; - FORCE_INLINE triplet operator()(const int red, const int green, const int blue) const noexcept + FORCE_INLINE triplet operator()(const int red, const int green, const int blue) const noexcept { - return {static_cast(red - green + range_ / 2), static_cast(green), static_cast(blue - green + range_ / 2)}; + return {static_cast(red - green + range_ / 2), static_cast(green), static_cast(blue - green + range_ / 2)}; } struct inverse final { - FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept + FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept { - return {static_cast(v1 + v2 - range_ / 2), v2, static_cast(v3 + v2 - range_ / 2)}; + return {static_cast(v1 + v2 - range_ / 2), v2, static_cast(v3 + v2 - range_ / 2)}; } }; private: - static constexpr size_t range_{1 << (sizeof(T) * 8)}; + static constexpr size_t range_{1 << (sizeof(SampleType) * 8)}; }; -template +template struct transform_hp2 final { - static_assert(std::is_integral_v, "Integral required."); + static_assert(std::is_integral_v, "Integral required."); - using size_type = T; + using sample_type = SampleType; - FORCE_INLINE triplet operator()(const int red, const int green, const int blue) const noexcept + FORCE_INLINE triplet operator()(const int red, const int green, const int blue) const noexcept { - return {static_cast(red - green + range_ / 2), green, static_cast(blue - ((red + green) >> 1) - range_ / 2)}; + return {static_cast(red - green + range_ / 2), green, static_cast(blue - ((red + green) >> 1) - range_ / 2)}; } struct inverse final { - FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept + FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept { - const auto r{static_cast(v1 + v2 - range_ / 2)}; - return {r, static_cast(v2), static_cast(v3 + ((r + static_cast(v2)) >> 1) - range_ / 2)}; + const auto r{static_cast(v1 + v2 - range_ / 2)}; + return {r, static_cast(v2), static_cast(v3 + ((r + static_cast(v2)) >> 1) - range_ / 2)}; } }; private: - static constexpr size_t range_{1 << (sizeof(T) * 8)}; + static constexpr size_t range_{1 << (sizeof(SampleType) * 8)}; }; -template +template struct transform_hp3 final { - static_assert(std::is_integral_v, "Integral required."); + static_assert(std::is_integral_v, "Integral required."); - using size_type = T; + using sample_type = SampleType; - FORCE_INLINE triplet operator()(const int red, const int green, const int blue) const noexcept + FORCE_INLINE triplet operator()(const int red, const int green, const int blue) const noexcept { - const auto v2{static_cast(blue - green + range_ / 2)}; - const auto v3{static_cast(red - green + range_ / 2)}; + const auto v2{static_cast(blue - green + range_ / 2)}; + const auto v3{static_cast(red - green + range_ / 2)}; - return {static_cast(green + ((v2 + v3) >> 2) - range_ / 4), static_cast(blue - green + range_ / 2), - static_cast(red - green + range_ / 2)}; + return {static_cast(green + ((v2 + v3) >> 2) - range_ / 4), static_cast(blue - green + range_ / 2), + static_cast(red - green + range_ / 2)}; } struct inverse final { - FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept + FORCE_INLINE triplet operator()(const int v1, const int v2, const int v3) const noexcept { const auto g{static_cast(v1 - ((v3 + v2) >> 2) + range_ / 4)}; - return {static_cast(v3 + g - range_ / 2), static_cast(g), static_cast(v2 + g - range_ / 2)}; + return {static_cast(v3 + g - range_ / 2), static_cast(g), static_cast(v2 + g - range_ / 2)}; } }; private: - static constexpr size_t range_{1 << (sizeof(T) * 8)}; + static constexpr size_t range_{1 << (sizeof(SampleType) * 8)}; }; } // namespace charls diff --git a/src/lossless_traits.h b/src/lossless_traits.h index ae6cd110..41d0d7fb 100644 --- a/src/lossless_traits.h +++ b/src/lossless_traits.h @@ -69,10 +69,10 @@ struct lossless_traits_impl }; -template -struct lossless_traits final : lossless_traits_impl +template +struct lossless_traits final : lossless_traits_impl { - using pixel_type = PixelType; + using pixel_type = SampleType; }; @@ -122,48 +122,48 @@ struct lossless_traits final : lossless_traits_impl }; -template -struct lossless_traits, BitsPerPixel> final : lossless_traits_impl +template +struct lossless_traits, BitsPerPixel> final : lossless_traits_impl { - using pixel_type = triplet; + using pixel_type = triplet; FORCE_INLINE constexpr static bool is_near(const int32_t lhs, const int32_t rhs) noexcept { return lhs == rhs; } - FORCE_INLINE constexpr static bool is_near(pixel_type lhs, pixel_type rhs) noexcept + FORCE_INLINE constexpr static bool is_near(const pixel_type lhs, const pixel_type rhs) noexcept { return lhs == rhs; } - FORCE_INLINE static PixelType compute_reconstructed_sample(const int32_t predicted_value, + FORCE_INLINE static SampleType compute_reconstructed_sample(const int32_t predicted_value, const int32_t error_value) noexcept { - return static_cast(predicted_value + error_value); + return static_cast(predicted_value + error_value); } }; -template -struct lossless_traits, BitsPerPixel> final : lossless_traits_impl +template +struct lossless_traits, BitsPerPixel> final : lossless_traits_impl { - using pixel_type = quad; + using pixel_type = quad; FORCE_INLINE constexpr static bool is_near(const int32_t lhs, const int32_t rhs) noexcept { return lhs == rhs; } - FORCE_INLINE constexpr static bool is_near(pixel_type lhs, pixel_type rhs) noexcept + FORCE_INLINE constexpr static bool is_near(const pixel_type lhs, const pixel_type rhs) noexcept { return lhs == rhs; } - FORCE_INLINE static PixelType compute_reconstructed_sample(const int32_t predicted_value, + FORCE_INLINE static SampleType compute_reconstructed_sample(const int32_t predicted_value, const int32_t error_value) noexcept { - return static_cast(predicted_value + error_value); + return static_cast(predicted_value + error_value); } }; diff --git a/src/process_decoded_line.h b/src/process_decoded_line.h index 49809c4a..b1bbd097 100644 --- a/src/process_decoded_line.h +++ b/src/process_decoded_line.h @@ -3,14 +3,9 @@ #pragma once -#include "coding_parameters.h" -#include "span.h" +#include "util.h" -#include #include -#include -#include - // During decoding, CharLS process one line at a time. // Conversions include color transforms, line interleaved vs sample interleaved, masking out unused bits, @@ -36,28 +31,29 @@ struct process_decoded_line class process_decoded_single_component final : public process_decoded_line { public: - process_decoded_single_component(std::byte* destination, const size_t stride, const size_t bytes_per_pixel) noexcept : - destination_{destination}, bytes_per_pixel_{bytes_per_pixel}, stride_{stride} + process_decoded_single_component(std::byte* destination, const size_t destination_stride, + const size_t bytes_per_pixel) noexcept : + destination_{destination}, destination_stride_{destination_stride}, bytes_per_pixel_{bytes_per_pixel} { ASSERT(bytes_per_pixel == sizeof(std::byte) || bytes_per_pixel == sizeof(uint16_t)); } - void new_line_decoded(const void* source, const size_t pixel_count, size_t /* source_stride */) noexcept(false) override + void new_line_decoded(const void* source, const size_t pixel_count, size_t /* source_stride */) noexcept override { memcpy(destination_, source, pixel_count * bytes_per_pixel_); - destination_ += stride_; + destination_ += destination_stride_; } private: std::byte* destination_; + size_t destination_stride_; size_t bytes_per_pixel_; - size_t stride_; }; -template -void transform_line(triplet* destination, const triplet* source, const size_t pixel_count, - const Transform& transform) noexcept +template +void transform_line(triplet* destination, const triplet* source, const size_t pixel_count, + const TransformType& transform) noexcept { for (size_t i{}; i < pixel_count; ++i) { @@ -66,8 +62,8 @@ void transform_line(triplet* destination, const triplet* s } -template -void transform_line(quad* destination, const quad* source, const size_t pixel_count) noexcept +template +void transform_line(quad* destination, const quad* source, const size_t pixel_count) noexcept { for (size_t i{}; i < pixel_count; ++i) { @@ -76,8 +72,8 @@ void transform_line(quad* destination, const quad* source, } -template -void transform_line_to_quad(const PixelType* source, const size_t pixel_stride_in, quad* destination, +template +void transform_line_to_quad(const SampleType* source, const size_t pixel_stride_in, quad* destination, const size_t pixel_stride) noexcept { const auto pixel_count{std::min(pixel_stride, pixel_stride_in)}; @@ -90,9 +86,9 @@ void transform_line_to_quad(const PixelType* source, const size_t pixel_stride_i } -template -void transform_line_to_triplet(const PixelType* source, const size_t pixel_stride_in, triplet* destination, - const size_t pixel_stride, const Transform& transform) noexcept +template +void transform_line_to_triplet(const SampleType* source, const size_t pixel_stride_in, triplet* destination, + const size_t pixel_stride, const TransformType& transform) noexcept { const auto pixel_count{std::min(pixel_stride, pixel_stride_in)}; @@ -107,53 +103,57 @@ template class process_decoded_transformed final : public process_decoded_line { public: - process_decoded_transformed(std::byte* destination, const size_t stride, const int32_t component_count, + process_decoded_transformed(std::byte* destination, const size_t destination_stride, const int32_t component_count, const interleave_mode interleave_mode) noexcept : - destination_{destination}, stride_{stride}, component_count_{component_count}, interleave_mode_{interleave_mode} + destination_{destination}, + destination_stride_{destination_stride}, + component_count_{component_count}, + interleave_mode_{interleave_mode} { } - void new_line_decoded(const void* source, const size_t pixel_count, const size_t source_stride) noexcept(false) override + void new_line_decoded(const void* source, const size_t pixel_count, const size_t source_stride) noexcept override { decode_transform(source, destination_, pixel_count, source_stride); - destination_ += stride_; + destination_ += destination_stride_; } - void decode_transform(const void* source, void* destination, const size_t pixel_count, const size_t byte_stride) noexcept + void decode_transform(const void* source, void* destination, const size_t pixel_count, + const size_t source_stride) noexcept { if (component_count_ == 3) { if (interleave_mode_ == interleave_mode::sample) { - transform_line(static_cast*>(destination), static_cast*>(source), - pixel_count, inverse_transform_); + transform_line(static_cast*>(destination), + static_cast*>(source), pixel_count, inverse_transform_); } else { - transform_line_to_triplet(static_cast(source), byte_stride, - static_cast*>(destination), pixel_count, inverse_transform_); + transform_line_to_triplet(static_cast(source), source_stride, + static_cast*>(destination), pixel_count, inverse_transform_); } } else if (component_count_ == 4) { if (interleave_mode_ == interleave_mode::sample) { - transform_line(static_cast*>(destination), static_cast*>(source), + transform_line(static_cast*>(destination), static_cast*>(source), pixel_count); } else if (interleave_mode_ == interleave_mode::line) { - transform_line_to_quad(static_cast(source), byte_stride, - static_cast*>(destination), pixel_count); + transform_line_to_quad(static_cast(source), source_stride, + static_cast*>(destination), pixel_count); } } } private: - using size_type = typename TransformType::size_type; + using sample_type = typename TransformType::sample_type; std::byte* destination_; - size_t stride_; + size_t destination_stride_; int32_t component_count_; interleave_mode interleave_mode_; typename TransformType::inverse inverse_transform_{}; diff --git a/src/process_encoded_line.h b/src/process_encoded_line.h index 3f731e7b..f7b62e19 100644 --- a/src/process_encoded_line.h +++ b/src/process_encoded_line.h @@ -6,7 +6,6 @@ #include "util.h" #include -#include // During encoding, CharLS process one line at a time. The different implementations @@ -34,8 +33,9 @@ struct process_encoded_line class process_encoded_single_component final : public process_encoded_line { public: - process_encoded_single_component(const std::byte* source, const size_t stride, const size_t bytes_per_pixel) noexcept : - source_{source}, bytes_per_pixel_{bytes_per_pixel}, stride_{stride} + process_encoded_single_component(const std::byte* source, const size_t source_stride, + const size_t bytes_per_pixel) noexcept : + source_{source}, source_stride_{source_stride}, bytes_per_pixel_{bytes_per_pixel} { ASSERT(bytes_per_pixel == sizeof(std::byte) || bytes_per_pixel == sizeof(uint16_t)); } @@ -44,24 +44,24 @@ class process_encoded_single_component final : public process_encoded_line size_t /* destination_stride */) noexcept(false) override { memcpy(destination, source_, pixel_count * bytes_per_pixel_); - source_ += stride_; + source_ += source_stride_; } private: const std::byte* source_; + size_t source_stride_; size_t bytes_per_pixel_; - size_t stride_; }; class process_encoded_single_component_masked final : public process_encoded_line { public: - process_encoded_single_component_masked(const void* source, const size_t stride, const size_t bytes_per_pixel, + process_encoded_single_component_masked(const void* source, const size_t source_stride, const size_t bytes_per_pixel, const uint32_t bits_per_pixel) noexcept : source_{source}, + source_stride_{source_stride}, bytes_per_pixel_{bytes_per_pixel}, - stride_{stride}, mask_{(1U << bits_per_pixel) - 1U}, single_byte_pixel_{bytes_per_pixel_ == sizeof(std::byte)} { @@ -90,21 +90,21 @@ class process_encoded_single_component_masked final : public process_encoded_lin } } - source_ = static_cast(source_) + stride_; + source_ = static_cast(source_) + source_stride_; } private: const void* source_; + size_t source_stride_; size_t bytes_per_pixel_; - size_t stride_; uint32_t mask_; bool single_byte_pixel_; }; -template -void transform_line(triplet* destination, const triplet* source, const size_t pixel_count, - Transform& transform, const uint32_t mask) noexcept +template +void transform_line(triplet* destination, const triplet* source, const size_t pixel_count, + const TransformType& transform, const uint32_t mask) noexcept { for (size_t i{}; i < pixel_count; ++i) { @@ -113,29 +113,28 @@ void transform_line(triplet* destination, const triplet* s } -template -void transform_line(quad* destination, const quad* source, const size_t pixel_count, +template +void transform_line(quad* destination, const quad* source, const size_t pixel_count, const uint32_t mask) noexcept { for (size_t i{}; i < pixel_count; ++i) { - destination[i] = {static_cast(source[i].v1 & mask), static_cast(source[i].v2 & mask), - static_cast(source[i].v3 & mask), static_cast(source[i].v4 & mask)}; + destination[i] = {static_cast(source[i].v1 & mask), static_cast(source[i].v2 & mask), + static_cast(source[i].v3 & mask), static_cast(source[i].v4 & mask)}; } } -template -void transform_triplet_to_line(const triplet* source, const size_t pixel_stride_in, PixelType* destination, - const size_t pixel_stride, Transform& transform, const uint32_t mask) noexcept +template +void transform_triplet_to_line(const triplet* source, const size_t pixel_stride_in, SampleType* destination, + const size_t pixel_stride, const TransformType& transform, const uint32_t mask) noexcept { const auto pixel_count{std::min(pixel_stride, pixel_stride_in)}; - const triplet* type_buffer_in{source}; for (size_t i{}; i < pixel_count; ++i) { - const triplet color{type_buffer_in[i]}; - const triplet color_transformed{transform(color.v1 & mask, color.v2 & mask, color.v3 & mask)}; + const triplet color{source[i]}; + const triplet color_transformed{transform(color.v1 & mask, color.v2 & mask, color.v3 & mask)}; destination[i] = color_transformed.v1; destination[i + pixel_stride] = color_transformed.v2; @@ -144,20 +143,20 @@ void transform_triplet_to_line(const triplet* source, const size_t pi } -template -void transform_quad_to_line(const quad* source, const size_t pixel_stride_in, PixelType* destination, +template +void transform_quad_to_line(const quad* source, const size_t pixel_stride_in, SampleType* destination, const size_t pixel_stride, const uint32_t mask) noexcept { const auto pixel_count{std::min(pixel_stride, pixel_stride_in)}; for (size_t i{}; i < pixel_count; ++i) { - const quad& color{source[i]}; + const quad& color{source[i]}; - destination[i] = static_cast(color.v1 & mask); - destination[i + pixel_stride] = static_cast(color.v2 & mask); - destination[i + 2 * pixel_stride] = static_cast(color.v3 & mask); - destination[i + 3 * pixel_stride] = static_cast(color.v4 & mask); + destination[i] = static_cast(color.v1 & mask); + destination[i + pixel_stride] = static_cast(color.v2 & mask); + destination[i + 2 * pixel_stride] = static_cast(color.v3 & mask); + destination[i + 3 * pixel_stride] = static_cast(color.v4 & mask); } } @@ -166,12 +165,12 @@ template class process_encoded_transformed final : public process_encoded_line { public: - process_encoded_transformed(const std::byte* const source, const size_t stride, const frame_info& info, + process_encoded_transformed(const std::byte* const source, const size_t stride, const frame_info& frame, const interleave_mode interleave_mode) noexcept : source_{source}, stride_{stride}, - mask_{(1U << info.bits_per_sample) - 1U}, - component_count_{info.component_count}, + mask_{(1U << frame.bits_per_sample) - 1U}, + component_count_{frame.component_count}, interleave_mode_{interleave_mode} { } @@ -190,32 +189,32 @@ class process_encoded_transformed final : public process_encoded_line { if (interleave_mode_ == interleave_mode::sample) { - transform_line(static_cast*>(destination), static_cast*>(source), - pixel_count, transform_, mask_); + transform_line(static_cast*>(destination), + static_cast*>(source), pixel_count, transform_, mask_); } else { - transform_triplet_to_line(static_cast*>(source), pixel_count, - static_cast(destination), destination_stride, transform_, mask_); + transform_triplet_to_line(static_cast*>(source), pixel_count, + static_cast(destination), destination_stride, transform_, mask_); } } else if (component_count_ == 4) { if (interleave_mode_ == interleave_mode::sample) { - transform_line(static_cast*>(destination), static_cast*>(source), + transform_line(static_cast*>(destination), static_cast*>(source), pixel_count, mask_); } else if (interleave_mode_ == interleave_mode::line) { - transform_quad_to_line(static_cast*>(source), pixel_count, - static_cast(destination), destination_stride, mask_); + transform_quad_to_line(static_cast*>(source), pixel_count, + static_cast(destination), destination_stride, mask_); } } } private: - using size_type = typename TransformType::size_type; + using sample_type = typename TransformType::sample_type; const std::byte* source_; size_t stride_; diff --git a/src/scan_decoder.h b/src/scan_decoder.h index b66f9485..f2edd9ae 100644 --- a/src/scan_decoder.h +++ b/src/scan_decoder.h @@ -9,6 +9,7 @@ #include "process_decoded_line.h" #include "scan_codec.h" #include "util.h" +#include "span.h" #include #include diff --git a/test/main.cpp b/test/main.cpp index ce868a24..54356f91 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include