Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove duplicate code from make_scan_codec + undef_macros.h #333

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ message(STATUS "CharLS version: ${version_major}.${version_minor}.${version_patc

project(charls VERSION ${version_major}.${version_minor}.${version_patch} LANGUAGES C CXX)

# Determine if project is built as a subproject (using add_subdirectory) or if it is the master project.
set(MASTER_PROJECT OFF)
# Determine if project is built as a subproject (using add_subdirectory) or if it is the main project.
set(MAIN_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(MASTER_PROJECT ON)
message(STATUS "Building as master project, CMake version: ${CMAKE_VERSION}")
set(MAIN_PROJECT ON)
message(STATUS "Building as main project, CMake version: ${CMAKE_VERSION}")
endif ()

# The basic options to control what is build extra.
option(CHARLS_BUILD_TESTS "Build test application" ${MASTER_PROJECT})
option(CHARLS_BUILD_AFL_FUZZ_TEST "Build AFL test fuzzer application" ${MASTER_PROJECT})
option(CHARLS_BUILD_LIBFUZZER_FUZZ_TEST "Build LibFuzzer test fuzzer application" ${MASTER_PROJECT})
option(CHARLS_BUILD_SAMPLES "Build sample applications" ${MASTER_PROJECT})
option(CHARLS_INSTALL "Generate the install target." ${MASTER_PROJECT})
option(CHARLS_BUILD_TESTS "Build test application" ${MAIN_PROJECT})
option(CHARLS_BUILD_AFL_FUZZ_TEST "Build AFL test fuzzer application" ${MAIN_PROJECT})
option(CHARLS_BUILD_LIBFUZZER_FUZZ_TEST "Build LibFuzzer test fuzzer application" ${MAIN_PROJECT})
option(CHARLS_BUILD_SAMPLES "Build sample applications" ${MAIN_PROJECT})
option(CHARLS_INSTALL "Generate the install target." ${MAIN_PROJECT})

# Provide BUILD_SHARED_LIBS as an option for GUI tools
option(BUILD_SHARED_LIBS "Will control if charls lib is build as shared lib/DLL or static library")
Expand Down
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ target_compile_definitions(charls PRIVATE CHARLS_LIBRARY_BUILD)
target_compile_features(charls PUBLIC cxx_std_17)

set(HEADERS
"include/charls/api_abi.h"
"include/charls/annotations.h"
"include/charls/api_abi.h"
"include/charls/charls.h"
"include/charls/charls.hpp"
"include/charls/charls_jpegls_decoder.h"
Expand All @@ -81,6 +81,7 @@ set(HEADERS
"include/charls/jpegls_error.h"
"include/charls/jpegls_error.hpp"
"include/charls/public_types.h"
"include/charls/undef_macros.h"
"include/charls/validate_spiff_header.h"
"include/charls/version.h"
)
Expand Down
99 changes: 26 additions & 73 deletions src/make_scan_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,31 @@ using std::unique_ptr;

namespace {

/// <summary>
/// scan_codec_factory receives the actual frame info.
/// scan_codec expects 1 when encoding/decoding a single scan in interleave mode none.
/// </summary>
[[nodiscard]]
frame_info update_component_count(const frame_info& frame, const coding_parameters& parameters) noexcept
{
return {frame.width, frame.height, frame.bits_per_sample,
parameters.interleave_mode == interleave_mode::none ? 1 : frame.component_count};
}


template<typename ScanProcess, typename Traits>
[[nodiscard]]
unique_ptr<ScanProcess> make_codec(const frame_info& frame, const jpegls_pc_parameters& pc_parameters,
const coding_parameters& parameters, const Traits& traits)
{
if constexpr (std::is_same_v<ScanProcess, scan_encoder>)
{
return make_unique<scan_encoder_impl<Traits>>(update_component_count(frame, parameters), pc_parameters, parameters,
traits);
return make_unique<scan_encoder_impl<Traits>>(frame, pc_parameters, parameters, traits);
}
else
{
return make_unique<scan_decoder_impl<Traits>>(update_component_count(frame, parameters), pc_parameters, parameters,
traits);
return make_unique<scan_decoder_impl<Traits>>(frame, pc_parameters, parameters, traits);
}
}

} // namespace


template<typename ScanProcess>
[[nodiscard]]
unique_ptr<ScanProcess> try_make_optimized_codec(const frame_info& frame, const jpegls_pc_parameters& pc_parameters,
const coding_parameters& parameters)
unique_ptr<ScanProcess> make_scan_codec(const frame_info& frame, const jpegls_pc_parameters& pc_parameters,
const coding_parameters& parameters)
{
#ifndef DISABLE_SPECIALIZATIONS

// optimized lossless versions common formats
// Optimized lossless versions common formats
if (parameters.near_lossless == 0)
{
if (parameters.interleave_mode == interleave_mode::sample)
Expand All @@ -79,7 +67,8 @@ unique_ptr<ScanProcess> try_make_optimized_codec(const frame_info& frame, const
case 2:
return make_codec<ScanProcess>(frame, pc_parameters, parameters, lossless_traits<pair<uint16_t>, 16>());
case 3:
return make_codec<ScanProcess>(frame, pc_parameters, parameters, lossless_traits<triplet<uint16_t>, 16>());
return make_codec<ScanProcess>(frame, pc_parameters, parameters,
lossless_traits<triplet<uint16_t>, 16>());
default:
ASSERT(frame.component_count == 4);
return make_codec<ScanProcess>(frame, pc_parameters, parameters, lossless_traits<quad<uint16_t>, 16>());
Expand Down Expand Up @@ -136,68 +125,32 @@ unique_ptr<ScanProcess> try_make_optimized_codec(const frame_info& frame, const
default_traits<uint8_t, uint8_t>(maximum_sample_value, parameters.near_lossless));
}

if (frame.bits_per_sample <= 16)
if (parameters.interleave_mode == interleave_mode::sample)
{
if (parameters.interleave_mode == interleave_mode::sample)
if (frame.component_count == 2)
{
if (frame.component_count == 2)
{
return make_codec<ScanProcess>(
frame, pc_parameters, parameters,
default_traits<uint16_t, pair<uint16_t>>(maximum_sample_value, parameters.near_lossless));
}

if (frame.component_count == 3)
{
return make_codec<ScanProcess>(
frame, pc_parameters, parameters,
default_traits<uint16_t, triplet<uint16_t>>(maximum_sample_value, parameters.near_lossless));
}

if (frame.component_count == 4)
{
return make_codec<ScanProcess>(
frame, pc_parameters, parameters,
default_traits<uint16_t, quad<uint16_t>>(maximum_sample_value, parameters.near_lossless));
}
return make_codec<ScanProcess>(
frame, pc_parameters, parameters,
default_traits<uint16_t, pair<uint16_t>>(maximum_sample_value, parameters.near_lossless));
}

return make_codec<ScanProcess>(frame, pc_parameters, parameters,
default_traits<uint16_t, uint16_t>(maximum_sample_value, parameters.near_lossless));
}

return nullptr;
}


} // namespace


template<typename ScanProcess>
unique_ptr<ScanProcess> make_scan_codec(const frame_info& frame, const jpegls_pc_parameters& pc_parameters,
const coding_parameters& c_parameters)
{
unique_ptr<ScanProcess> codec{try_make_optimized_codec<ScanProcess>(frame, pc_parameters, c_parameters)};

if (!codec)
{
if (frame.bits_per_sample <= 8)
if (frame.component_count == 3)
{
default_traits<uint8_t, uint8_t> traits(calculate_maximum_sample_value(frame.bits_per_sample),
c_parameters.near_lossless);
traits.maximum_sample_value = pc_parameters.maximum_sample_value;
codec = make_codec<ScanProcess, default_traits<uint8_t, uint8_t>>(frame, pc_parameters, c_parameters, traits);
return make_codec<ScanProcess>(
frame, pc_parameters, parameters,
default_traits<uint16_t, triplet<uint16_t>>(maximum_sample_value, parameters.near_lossless));
}
else

if (frame.component_count == 4)
{
default_traits<uint16_t, uint16_t> traits(calculate_maximum_sample_value(frame.bits_per_sample),
c_parameters.near_lossless);
traits.maximum_sample_value = pc_parameters.maximum_sample_value;
codec = make_codec<ScanProcess, default_traits<uint16_t, uint16_t>>(frame, pc_parameters, c_parameters, traits);
return make_codec<ScanProcess>(
frame, pc_parameters, parameters,
default_traits<uint16_t, quad<uint16_t>>(maximum_sample_value, parameters.near_lossless));
}
}

return codec;
return make_codec<ScanProcess>(frame, pc_parameters, parameters,
default_traits<uint16_t, uint16_t>(maximum_sample_value, parameters.near_lossless));
}


Expand Down
2 changes: 1 addition & 1 deletion src/make_scan_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace charls {
template<typename ScanProcess>
[[nodiscard]]
std::unique_ptr<ScanProcess> make_scan_codec(const frame_info& frame,
const jpegls_pc_parameters& pc_parameters, const coding_parameters& c_parameters);
const jpegls_pc_parameters& pc_parameters, const coding_parameters& parameters);


extern template std::unique_ptr<class scan_decoder>
Expand Down
5 changes: 3 additions & 2 deletions src/scan_decoder_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,17 @@ class scan_decoder_impl final : public scan_decoder
{
decode_sample_line();
}
if constexpr (std::is_same_v<pixel_type, pair<sample_type>>)
else if constexpr (std::is_same_v<pixel_type, pair<sample_type>>)
{
decode_pair_line();
}
else if constexpr (std::is_same_v<pixel_type, triplet<sample_type>>)
{
decode_triplet_line();
}
else if constexpr (std::is_same_v<pixel_type, quad<sample_type>>)
else
{
static_assert(std::is_same_v<pixel_type, quad<sample_type>>);
decode_quad_line();
}

Expand Down