Skip to content

Commit

Permalink
Rename all template parameters that indicate the type used to hold th…
Browse files Browse the repository at this point in the history
…e sample to SampleType (#300)

Background: a pixel consist of 1 or more samples. (RGB has 3 samples for example).
CharLS uses as SampleType a byte (uint8_t) or a 16 bit byte (uint16_t)
  • Loading branch information
vbaderks authored Dec 29, 2023
1 parent c9c417c commit cb6a9d7
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 127 deletions.
74 changes: 37 additions & 37 deletions src/color_transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T>
template<typename SampleType>
struct transform_none_impl
{
static_assert(std::is_integral_v<T>, "Integral required.");
static_assert(std::is_integral_v<SampleType>, "Integral required.");

using size_type = T;
using sample_type = SampleType;

FORCE_INLINE triplet<T> operator()(const int v1, const int v2, const int v3) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int v1, const int v2, const int v3) const noexcept
{
return {v1, v2, v3};
}

FORCE_INLINE quad<T> operator()(const int v1, const int v2, const int v3, const int v4) const noexcept
FORCE_INLINE quad<SampleType> operator()(const int v1, const int v2, const int v3, const int v4) const noexcept
{
return {v1, v2, v3, v4};
}
};


template<typename T>
struct transform_none final : transform_none_impl<T>
template<typename SampleType>
struct transform_none final : transform_none_impl<SampleType>
{
static_assert(std::is_integral_v<T>, "Integral required.");
static_assert(std::is_integral_v<SampleType>, "Integral required.");

using inverse = transform_none_impl<T>;
using inverse = transform_none_impl<SampleType>;
};


template<typename T>
template<typename SampleType>
struct transform_hp1 final
{
static_assert(std::is_integral_v<T>, "Integral required.");
static_assert(std::is_integral_v<SampleType>, "Integral required.");

using size_type = T;
using sample_type = SampleType;

FORCE_INLINE triplet<T> operator()(const int red, const int green, const int blue) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int red, const int green, const int blue) const noexcept
{
return {static_cast<T>(red - green + range_ / 2), static_cast<T>(green), static_cast<T>(blue - green + range_ / 2)};
return {static_cast<SampleType>(red - green + range_ / 2), static_cast<SampleType>(green), static_cast<SampleType>(blue - green + range_ / 2)};
}

struct inverse final
{
FORCE_INLINE triplet<T> operator()(const int v1, const int v2, const int v3) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int v1, const int v2, const int v3) const noexcept
{
return {static_cast<T>(v1 + v2 - range_ / 2), v2, static_cast<T>(v3 + v2 - range_ / 2)};
return {static_cast<SampleType>(v1 + v2 - range_ / 2), v2, static_cast<SampleType>(v3 + v2 - range_ / 2)};
}
};

private:
static constexpr size_t range_{1 << (sizeof(T) * 8)};
static constexpr size_t range_{1 << (sizeof(SampleType) * 8)};
};


template<typename T>
template<typename SampleType>
struct transform_hp2 final
{
static_assert(std::is_integral_v<T>, "Integral required.");
static_assert(std::is_integral_v<SampleType>, "Integral required.");

using size_type = T;
using sample_type = SampleType;

FORCE_INLINE triplet<T> operator()(const int red, const int green, const int blue) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int red, const int green, const int blue) const noexcept
{
return {static_cast<T>(red - green + range_ / 2), green, static_cast<T>(blue - ((red + green) >> 1) - range_ / 2)};
return {static_cast<SampleType>(red - green + range_ / 2), green, static_cast<SampleType>(blue - ((red + green) >> 1) - range_ / 2)};
}

struct inverse final
{
FORCE_INLINE triplet<T> operator()(const int v1, const int v2, const int v3) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int v1, const int v2, const int v3) const noexcept
{
const auto r{static_cast<T>(v1 + v2 - range_ / 2)};
return {r, static_cast<T>(v2), static_cast<T>(v3 + ((r + static_cast<T>(v2)) >> 1) - range_ / 2)};
const auto r{static_cast<SampleType>(v1 + v2 - range_ / 2)};
return {r, static_cast<SampleType>(v2), static_cast<SampleType>(v3 + ((r + static_cast<SampleType>(v2)) >> 1) - range_ / 2)};
}
};

private:
static constexpr size_t range_{1 << (sizeof(T) * 8)};
static constexpr size_t range_{1 << (sizeof(SampleType) * 8)};
};


template<typename T>
template<typename SampleType>
struct transform_hp3 final
{
static_assert(std::is_integral_v<T>, "Integral required.");
static_assert(std::is_integral_v<SampleType>, "Integral required.");

using size_type = T;
using sample_type = SampleType;

FORCE_INLINE triplet<T> operator()(const int red, const int green, const int blue) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int red, const int green, const int blue) const noexcept
{
const auto v2{static_cast<T>(blue - green + range_ / 2)};
const auto v3{static_cast<T>(red - green + range_ / 2)};
const auto v2{static_cast<SampleType>(blue - green + range_ / 2)};
const auto v3{static_cast<SampleType>(red - green + range_ / 2)};

return {static_cast<T>(green + ((v2 + v3) >> 2) - range_ / 4), static_cast<T>(blue - green + range_ / 2),
static_cast<T>(red - green + range_ / 2)};
return {static_cast<SampleType>(green + ((v2 + v3) >> 2) - range_ / 4), static_cast<SampleType>(blue - green + range_ / 2),
static_cast<SampleType>(red - green + range_ / 2)};
}

struct inverse final
{
FORCE_INLINE triplet<T> operator()(const int v1, const int v2, const int v3) const noexcept
FORCE_INLINE triplet<SampleType> operator()(const int v1, const int v2, const int v3) const noexcept
{
const auto g{static_cast<int>(v1 - ((v3 + v2) >> 2) + range_ / 4)};
return {static_cast<T>(v3 + g - range_ / 2), static_cast<T>(g), static_cast<T>(v2 + g - range_ / 2)};
return {static_cast<SampleType>(v3 + g - range_ / 2), static_cast<SampleType>(g), static_cast<SampleType>(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
30 changes: 15 additions & 15 deletions src/lossless_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ struct lossless_traits_impl
};


template<typename PixelType, int32_t BitsPerPixel>
struct lossless_traits final : lossless_traits_impl<PixelType, BitsPerPixel>
template<typename SampleType, int32_t BitsPerPixel>
struct lossless_traits final : lossless_traits_impl<SampleType, BitsPerPixel>
{
using pixel_type = PixelType;
using pixel_type = SampleType;
};


Expand Down Expand Up @@ -122,48 +122,48 @@ struct lossless_traits<uint16_t, 16> final : lossless_traits_impl<uint16_t, 16>
};


template<typename PixelType, int32_t BitsPerPixel>
struct lossless_traits<triplet<PixelType>, BitsPerPixel> final : lossless_traits_impl<PixelType, BitsPerPixel>
template<typename SampleType, int32_t BitsPerPixel>
struct lossless_traits<triplet<SampleType>, BitsPerPixel> final : lossless_traits_impl<SampleType, BitsPerPixel>
{
using pixel_type = triplet<PixelType>;
using pixel_type = triplet<SampleType>;

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<PixelType>(predicted_value + error_value);
return static_cast<SampleType>(predicted_value + error_value);
}
};


template<typename PixelType, int32_t BitsPerPixel>
struct lossless_traits<quad<PixelType>, BitsPerPixel> final : lossless_traits_impl<PixelType, BitsPerPixel>
template<typename SampleType, int32_t BitsPerPixel>
struct lossless_traits<quad<SampleType>, BitsPerPixel> final : lossless_traits_impl<SampleType, BitsPerPixel>
{
using pixel_type = quad<PixelType>;
using pixel_type = quad<SampleType>;

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<PixelType>(predicted_value + error_value);
return static_cast<SampleType>(predicted_value + error_value);
}
};

Expand Down
70 changes: 35 additions & 35 deletions src/process_decoded_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@

#pragma once

#include "coding_parameters.h"
#include "span.h"
#include "util.h"

#include <algorithm>
#include <cstring>
#include <sstream>
#include <vector>


// During decoding, CharLS process one line at a time.
// Conversions include color transforms, line interleaved vs sample interleaved, masking out unused bits,
Expand All @@ -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<typename Transform, typename PixelType>
void transform_line(triplet<PixelType>* destination, const triplet<PixelType>* source, const size_t pixel_count,
const Transform& transform) noexcept
template<typename TransformType, typename SampleType>
void transform_line(triplet<SampleType>* destination, const triplet<SampleType>* source, const size_t pixel_count,
const TransformType& transform) noexcept
{
for (size_t i{}; i < pixel_count; ++i)
{
Expand All @@ -66,8 +62,8 @@ void transform_line(triplet<PixelType>* destination, const triplet<PixelType>* s
}


template<typename PixelType>
void transform_line(quad<PixelType>* destination, const quad<PixelType>* source, const size_t pixel_count) noexcept
template<typename SampleType>
void transform_line(quad<SampleType>* destination, const quad<SampleType>* source, const size_t pixel_count) noexcept
{
for (size_t i{}; i < pixel_count; ++i)
{
Expand All @@ -76,8 +72,8 @@ void transform_line(quad<PixelType>* destination, const quad<PixelType>* source,
}


template<typename PixelType>
void transform_line_to_quad(const PixelType* source, const size_t pixel_stride_in, quad<PixelType>* destination,
template<typename SampleType>
void transform_line_to_quad(const SampleType* source, const size_t pixel_stride_in, quad<SampleType>* destination,
const size_t pixel_stride) noexcept
{
const auto pixel_count{std::min(pixel_stride, pixel_stride_in)};
Expand All @@ -90,9 +86,9 @@ void transform_line_to_quad(const PixelType* source, const size_t pixel_stride_i
}


template<typename Transform, typename PixelType>
void transform_line_to_triplet(const PixelType* source, const size_t pixel_stride_in, triplet<PixelType>* destination,
const size_t pixel_stride, const Transform& transform) noexcept
template<typename TransformType, typename SampleType>
void transform_line_to_triplet(const SampleType* source, const size_t pixel_stride_in, triplet<SampleType>* destination,
const size_t pixel_stride, const TransformType& transform) noexcept
{
const auto pixel_count{std::min(pixel_stride, pixel_stride_in)};

Expand All @@ -107,53 +103,57 @@ template<typename TransformType>
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<triplet<size_type>*>(destination), static_cast<const triplet<size_type>*>(source),
pixel_count, inverse_transform_);
transform_line(static_cast<triplet<sample_type>*>(destination),
static_cast<const triplet<sample_type>*>(source), pixel_count, inverse_transform_);
}
else
{
transform_line_to_triplet(static_cast<const size_type*>(source), byte_stride,
static_cast<triplet<size_type>*>(destination), pixel_count, inverse_transform_);
transform_line_to_triplet(static_cast<const sample_type*>(source), source_stride,
static_cast<triplet<sample_type>*>(destination), pixel_count, inverse_transform_);
}
}
else if (component_count_ == 4)
{
if (interleave_mode_ == interleave_mode::sample)
{
transform_line(static_cast<quad<size_type>*>(destination), static_cast<const quad<size_type>*>(source),
transform_line(static_cast<quad<sample_type>*>(destination), static_cast<const quad<sample_type>*>(source),
pixel_count);
}
else if (interleave_mode_ == interleave_mode::line)
{
transform_line_to_quad(static_cast<const size_type*>(source), byte_stride,
static_cast<quad<size_type>*>(destination), pixel_count);
transform_line_to_quad(static_cast<const sample_type*>(source), source_stride,
static_cast<quad<sample_type>*>(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_{};
Expand Down
Loading

0 comments on commit cb6a9d7

Please sign in to comment.