Rename all template parameters that indicate the type used to hold the 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)
This commit is contained in:
Victor Derks 2023-12-30 00:19:10 +01:00 committed by GitHub
parent c9c417c1a4
commit cb6a9d715f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 128 additions and 127 deletions

View File

@ -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

View File

@ -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;
};
@ -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);
}
};

View File

@ -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,
@ -36,28 +31,29 @@ protected:
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)
{
@ -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)
{
@ -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)};
@ -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)};
@ -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_{};

View File

@ -6,7 +6,6 @@
#include "util.h"
#include <cstring>
#include <vector>
// During encoding, CharLS process one line at a time. The different implementations
@ -34,8 +33,9 @@ protected:
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 @@ public:
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 @@ public:
}
}
source_ = static_cast<const std::byte*>(source_) + stride_;
source_ = static_cast<const std::byte*>(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<typename Transform, typename PixelType>
void transform_line(triplet<PixelType>* destination, const triplet<PixelType>* source, const size_t pixel_count,
Transform& transform, const uint32_t mask) noexcept
template<typename TransformType, typename SampleType>
void transform_line(triplet<SampleType>* destination, const triplet<SampleType>* 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<PixelType>* destination, const triplet<PixelType>* s
}
template<typename PixelType>
void transform_line(quad<PixelType>* destination, const quad<PixelType>* source, const size_t pixel_count,
template<typename SampleType>
void transform_line(quad<SampleType>* destination, const quad<SampleType>* source, const size_t pixel_count,
const uint32_t mask) noexcept
{
for (size_t i{}; i < pixel_count; ++i)
{
destination[i] = {static_cast<PixelType>(source[i].v1 & mask), static_cast<PixelType>(source[i].v2 & mask),
static_cast<PixelType>(source[i].v3 & mask), static_cast<PixelType>(source[i].v4 & mask)};
destination[i] = {static_cast<SampleType>(source[i].v1 & mask), static_cast<SampleType>(source[i].v2 & mask),
static_cast<SampleType>(source[i].v3 & mask), static_cast<SampleType>(source[i].v4 & mask)};
}
}
template<typename Transform, typename PixelType>
void transform_triplet_to_line(const triplet<PixelType>* source, const size_t pixel_stride_in, PixelType* destination,
const size_t pixel_stride, Transform& transform, const uint32_t mask) noexcept
template<typename TransformType, typename SampleType>
void transform_triplet_to_line(const triplet<SampleType>* 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<PixelType>* type_buffer_in{source};
for (size_t i{}; i < pixel_count; ++i)
{
const triplet<PixelType> color{type_buffer_in[i]};
const triplet<PixelType> color_transformed{transform(color.v1 & mask, color.v2 & mask, color.v3 & mask)};
const triplet<SampleType> color{source[i]};
const triplet<SampleType> 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<PixelType>* source, const size_t pi
}
template<typename PixelType>
void transform_quad_to_line(const quad<PixelType>* source, const size_t pixel_stride_in, PixelType* destination,
template<typename SampleType>
void transform_quad_to_line(const quad<SampleType>* 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<PixelType>& color{source[i]};
const quad<SampleType>& color{source[i]};
destination[i] = static_cast<PixelType>(color.v1 & mask);
destination[i + pixel_stride] = static_cast<PixelType>(color.v2 & mask);
destination[i + 2 * pixel_stride] = static_cast<PixelType>(color.v3 & mask);
destination[i + 3 * pixel_stride] = static_cast<PixelType>(color.v4 & mask);
destination[i] = static_cast<SampleType>(color.v1 & mask);
destination[i + pixel_stride] = static_cast<SampleType>(color.v2 & mask);
destination[i + 2 * pixel_stride] = static_cast<SampleType>(color.v3 & mask);
destination[i + 3 * pixel_stride] = static_cast<SampleType>(color.v4 & mask);
}
}
@ -166,12 +165,12 @@ template<typename TransformType>
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 @@ public:
{
if (interleave_mode_ == interleave_mode::sample)
{
transform_line(static_cast<triplet<size_type>*>(destination), static_cast<const triplet<size_type>*>(source),
pixel_count, transform_, mask_);
transform_line(static_cast<triplet<sample_type>*>(destination),
static_cast<const triplet<sample_type>*>(source), pixel_count, transform_, mask_);
}
else
{
transform_triplet_to_line(static_cast<const triplet<size_type>*>(source), pixel_count,
static_cast<size_type*>(destination), destination_stride, transform_, mask_);
transform_triplet_to_line(static_cast<const triplet<sample_type>*>(source), pixel_count,
static_cast<sample_type*>(destination), destination_stride, transform_, mask_);
}
}
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, mask_);
}
else if (interleave_mode_ == interleave_mode::line)
{
transform_quad_to_line(static_cast<const quad<size_type>*>(source), pixel_count,
static_cast<size_type*>(destination), destination_stride, mask_);
transform_quad_to_line(static_cast<const quad<sample_type>*>(source), pixel_count,
static_cast<sample_type*>(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_;

View File

@ -9,6 +9,7 @@
#include "process_decoded_line.h"
#include "scan_codec.h"
#include "util.h"
#include "span.h"
#include <cassert>
#include <memory>

View File

@ -17,6 +17,7 @@
#include <fstream>
#include <iostream>
#include <random>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>