diff --git a/doc/style_and_design.md b/doc/style_and_design.md index e7960347..1c4cc691 100644 --- a/doc/style_and_design.md +++ b/doc/style_and_design.md @@ -110,7 +110,7 @@ sense to define a good naming convention. Not all JPEG-LS names are good C++ var | JPEG-LS Symbol | C++ name | Description | | -------------- | ------------------------ |------------ | | a, b, c, d | a, b, c, d | positions of samples in the causal template | -| bpp | bits_per_pixel | number of bits needed to represent MAXVAL (not less than 2) | +| bpp | bits_per_sample | number of bits needed to represent MAXVAL (not less than 2) | | D1, D2, D3, Di | d1, d2, d3, di | local gradients | | EMErrval | e_mapped_error_value | Errval mapped to non-negative integers in run interruption mode | | Errval | error_value | prediction error (quantized or unquantized, before and after modulo reduction) | diff --git a/fuzzing/libfuzzer/main.cpp b/fuzzing/libfuzzer/main.cpp index ff4e19fe..91833f90 100644 --- a/fuzzing/libfuzzer/main.cpp +++ b/fuzzing/libfuzzer/main.cpp @@ -15,7 +15,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, const size_t size) if (const auto& frame_info{decoder.frame_info()}; frame_info.height < 500 && frame_info.width < 500 && frame_info.component_count < 4) { - std::vector destination(decoder.destination_size()); + std::vector destination(decoder.get_destination_size()); decoder.decode(destination); } } diff --git a/include/charls/charls_jpegls_decoder.h b/include/charls/charls_jpegls_decoder.h index 054f9339..09f085d6 100644 --- a/include/charls/charls_jpegls_decoder.h +++ b/include/charls/charls_jpegls_decoder.h @@ -241,11 +241,11 @@ charls_decoder_get_mapping_table_id(CHARLS_IN const charls_jpegls_decoder* decod /// Function should be called after processing the complete JPEG-LS stream. /// /// Reference to the decoder instance. -/// Mapping table ID to lookup. +/// Mapping table ID to lookup. /// Output argument, will hold the mapping table index or -1 when the function returns. /// The result of the operation: success or a failure code. CHARLS_CHECK_RETURN CHARLS_API_IMPORT_EXPORT charls_jpegls_errc CHARLS_API_CALLING_CONVENTION -charls_decoder_get_mapping_table_index(CHARLS_IN const charls_jpegls_decoder* decoder, int32_t table_id, +charls_decoder_find_mapping_table_index(CHARLS_IN const charls_jpegls_decoder* decoder, int32_t mapping_table_id, CHARLS_OUT int32_t* index) CHARLS_NOEXCEPT CHARLS_ATTRIBUTE((nonnull)); /// @@ -268,13 +268,13 @@ charls_decoder_get_mapping_table_count(CHARLS_IN const charls_jpegls_decoder* de /// Function should be called after processing the complete JPEG-LS stream. /// /// Reference to the decoder instance. -/// Index of the requested mapping table. +/// Index of the requested mapping table. /// /// Output argument, will hold the mapping table information when the function returns. /// /// The result of the operation: success or a failure code. CHARLS_CHECK_RETURN CHARLS_API_IMPORT_EXPORT charls_jpegls_errc CHARLS_API_CALLING_CONVENTION -charls_decoder_get_mapping_table_info(CHARLS_IN const charls_jpegls_decoder* decoder, int32_t index, +charls_decoder_get_mapping_table_info(CHARLS_IN const charls_jpegls_decoder* decoder, int32_t mapping_table_index, CHARLS_OUT charls_mapping_table_info* mapping_table_info) CHARLS_NOEXCEPT CHARLS_ATTRIBUTE((nonnull)); @@ -285,15 +285,15 @@ charls_decoder_get_mapping_table_info(CHARLS_IN const charls_jpegls_decoder* dec /// Function should be called after processing the complete JPEG-LS stream. /// /// Reference to the decoder instance. -/// Index of the requested mapping table. -/// Output argument, will hold the data of the mapping table when the function returns. -/// Length of the mapping table buffer in bytes. +/// Index of the requested mapping table. +/// Output argument, will hold the data of the mapping table when the function returns. +/// Length of the mapping table buffer in bytes. /// The result of the operation: success or a failure code. CHARLS_ATTRIBUTE_ACCESS((access(write_only, 3, 4))) CHARLS_CHECK_RETURN CHARLS_API_IMPORT_EXPORT charls_jpegls_errc CHARLS_API_CALLING_CONVENTION -charls_decoder_get_mapping_table_data(CHARLS_IN const charls_jpegls_decoder* decoder, int32_t index, - CHARLS_OUT_WRITES_BYTES(table_size_bytes) void* table_data, - size_t table_size_bytes) CHARLS_NOEXCEPT CHARLS_ATTRIBUTE((nonnull)); +charls_decoder_get_mapping_table_data(CHARLS_IN const charls_jpegls_decoder* decoder, int32_t mapping_table_index, + CHARLS_OUT_WRITES_BYTES(mapping_table_size_bytes) void* mapping_table_data, + size_t mapping_table_size_bytes) CHARLS_NOEXCEPT CHARLS_ATTRIBUTE((nonnull)); #ifdef __cplusplus @@ -328,7 +328,7 @@ class jpegls_decoder final { jpegls_decoder decoder{source, true}; - const size_t destination_size{decoder.destination_size()}; + const size_t destination_size{decoder.get_destination_size()}; if (destination_size > maximum_size_in_bytes) impl::throw_jpegls_error(jpegls_errc::not_enough_memory); @@ -531,14 +531,14 @@ class jpegls_decoder final /// /// Returns the NEAR parameter that was used to encode the scan. A value of 0 means lossless. /// - /// The component index for which the NEAR parameter should be retrieved. + /// The component index for which the NEAR parameter should be retrieved. /// An error occurred during the operation. /// The value of the NEAR parameter. [[nodiscard]] - int32_t near_lossless(const int32_t component = 0) const + int32_t get_near_lossless(const int32_t component_index = 0) const { int32_t near_lossless; - check_jpegls_errc(charls_jpegls_decoder_get_near_lossless(decoder(), component, &near_lossless)); + check_jpegls_errc(charls_jpegls_decoder_get_near_lossless(decoder(), component_index, &near_lossless)); return near_lossless; } @@ -589,7 +589,7 @@ class jpegls_decoder final /// An error occurred during the operation. /// The required size in bytes of the destination buffer. [[nodiscard]] - size_t destination_size(const uint32_t stride = 0) const + size_t get_destination_size(const uint32_t stride = 0) const { size_t size_in_bytes; check_jpegls_errc(charls_jpegls_decoder_get_destination_size(decoder(), stride, &size_in_bytes)); @@ -635,7 +635,7 @@ class jpegls_decoder final [[nodiscard]] Container decode(const uint32_t stride = 0) { - Container destination(destination_size() / sizeof(ContainerValueType)); + Container destination(get_destination_size() / sizeof(ContainerValueType)); decode(destination.data(), destination.size() * sizeof(ContainerValueType), stride); return destination; @@ -701,16 +701,16 @@ class jpegls_decoder final /// /// Function should be called after processing the complete JPEG-LS stream. /// - /// Mapping table ID to lookup. + /// Mapping table ID to lookup. /// /// The index of the mapping table or -1 (mapping_table_missing) when the table is not present in the JPEG-LS stream. /// /// An error occurred during the operation. [[nodiscard]] - int32_t get_mapping_table_index(const int32_t table_id) const + int32_t find_mapping_table_index(const int32_t mapping_table_id) const { int32_t index; - check_jpegls_errc(charls_decoder_get_mapping_table_index(decoder(), table_id, &index)); + check_jpegls_errc(charls_decoder_find_mapping_table_index(decoder(), mapping_table_id, &index)); return index; } diff --git a/include/charls/public_types.h b/include/charls/public_types.h index 769e0cc9..06805730 100644 --- a/include/charls/public_types.h +++ b/include/charls/public_types.h @@ -56,7 +56,7 @@ enum charls_jpegls_errc CHARLS_JPEGLS_ERRC_RESTART_MARKER_NOT_FOUND = 23, CHARLS_JPEGLS_ERRC_END_OF_IMAGE_MARKER_NOT_FOUND = 24, CHARLS_JPEGLS_ERRC_UNKNOWN_COMPONENT_ID = 25, - CHARLS_JPEGLS_ERRC_ABBREVIATED_FORMAT_AND_SPIFF_HEADER = 26, + CHARLS_JPEGLS_ERRC_ABBREVIATED_FORMAT_AND_SPIFF_HEADER_MISMATCH = 26, CHARLS_JPEGLS_ERRC_INVALID_PARAMETER_WIDTH = 27, CHARLS_JPEGLS_ERRC_INVALID_PARAMETER_HEIGHT = 28, CHARLS_JPEGLS_ERRC_INVALID_PARAMETER_BITS_PER_SAMPLE = 29, @@ -325,7 +325,7 @@ enum class [[nodiscard]] jpegls_errc /// /// This error is returned for stream with only mapping tables and a spiff header. /// - abbreviated_format_and_spiff_header = impl::CHARLS_JPEGLS_ERRC_ABBREVIATED_FORMAT_AND_SPIFF_HEADER, + abbreviated_format_and_spiff_header_mismatch = impl::CHARLS_JPEGLS_ERRC_ABBREVIATED_FORMAT_AND_SPIFF_HEADER_MISMATCH, /// /// This error is returned when the stream contains a width parameter defined more than once or in an incompatible way. diff --git a/spelling.dic b/spelling.dic index 5c31af70..cc30f382 100644 --- a/spelling.dic +++ b/spelling.dic @@ -18,3 +18,4 @@ cppcoreguidelines uint json intrinsics +palletised diff --git a/src/charls_jpegls_decoder.cpp b/src/charls_jpegls_decoder.cpp index 669a6362..880d0078 100644 --- a/src/charls_jpegls_decoder.cpp +++ b/src/charls_jpegls_decoder.cpp @@ -91,7 +91,7 @@ struct charls_jpegls_decoder final } [[nodiscard]] - size_t destination_size(const size_t stride) const + size_t get_destination_size(const size_t stride) const { const auto [width, height, bits_per_sample, component_count]{frame_info_checked()}; @@ -138,11 +138,11 @@ struct charls_jpegls_decoder final } [[nodiscard]] - int32_t get_mapping_table_index(const int32_t table_id) const + int32_t find_mapping_table_index(const int32_t mapping_table_id) const { check_state_completed(); - check_argument_range(minimum_table_id, maximum_table_id, table_id); - return reader_.get_mapping_table_index(static_cast(table_id)); + check_argument_range(minimum_mapping_table_id, maximum_mapping_table_id, mapping_table_id); + return reader_.find_mapping_table_index(static_cast(mapping_table_id)); } [[nodiscard]] @@ -153,18 +153,18 @@ struct charls_jpegls_decoder final } [[nodiscard]] - mapping_table_info get_mapping_table_info(const int32_t index) const + mapping_table_info get_mapping_table_info(const int32_t mapping_table_index) const { - check_table_index(index); - return reader_.get_mapping_table_info(index); + check_mapping_table_index(mapping_table_index); + return reader_.get_mapping_table_info(mapping_table_index); } - void get_mapping_table_data(const int32_t index, const span table) const + void get_mapping_table_data(const int32_t mapping_table_index, const span table_data) const { - check_table_index(index); - check_argument(table.data() || table.empty()); + check_mapping_table_index(mapping_table_index); + check_argument(table_data.data() || table_data.empty()); - reader_.get_mapping_table_data(index, table); + reader_.get_mapping_table_data(mapping_table_index, table_data); } void decode(span destination, size_t stride) @@ -239,9 +239,9 @@ struct charls_jpegls_decoder final check_operation(state_ == state::completed); } - void check_table_index(const int32_t index) const + void check_mapping_table_index(const int32_t mapping_table_index) const { - check_argument_range(0, mapping_table_count() - 1, index); + check_argument_range(0, mapping_table_count() - 1, mapping_table_index); } void check_parameter_coherent() const @@ -400,7 +400,7 @@ USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION charls_jpegls_dec const charls_jpegls_decoder* decoder, const uint32_t stride, size_t* destination_size_bytes) noexcept try { - *check_pointer(destination_size_bytes) = check_pointer(decoder)->destination_size(stride); + *check_pointer(destination_size_bytes) = check_pointer(decoder)->get_destination_size(stride); return jpegls_errc::success; } catch (...) @@ -462,11 +462,11 @@ catch (...) } -USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION -charls_decoder_get_mapping_table_index(const charls_jpegls_decoder* decoder, const int32_t table_id, int32_t* index) noexcept +USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION charls_decoder_find_mapping_table_index( + const charls_jpegls_decoder* decoder, const int32_t mapping_table_id, int32_t* index) noexcept try { - *check_pointer(index) = check_pointer(decoder)->get_mapping_table_index(table_id); + *check_pointer(index) = check_pointer(decoder)->find_mapping_table_index(mapping_table_id); return jpegls_errc::success; } catch (...) @@ -488,11 +488,12 @@ catch (...) } -USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION charls_decoder_get_mapping_table_info( - const charls_jpegls_decoder* decoder, const int32_t index, mapping_table_info* mapping_table_info) noexcept +USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION +charls_decoder_get_mapping_table_info(const charls_jpegls_decoder* decoder, const int32_t mapping_table_index, + charls_mapping_table_info* mapping_table_info) noexcept try { - *check_pointer(mapping_table_info) = check_pointer(decoder)->get_mapping_table_info(index); + *check_pointer(mapping_table_info) = check_pointer(decoder)->get_mapping_table_info(mapping_table_index); return jpegls_errc::success; } catch (...) @@ -501,11 +502,13 @@ catch (...) } -USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION charls_decoder_get_mapping_table_data( - const charls_jpegls_decoder* decoder, const int32_t index, void* table_data, const size_t table_size_bytes) noexcept +USE_DECL_ANNOTATIONS jpegls_errc CHARLS_API_CALLING_CONVENTION +charls_decoder_get_mapping_table_data(const charls_jpegls_decoder* decoder, const int32_t mapping_table_index, + void* mapping_table_data, const size_t mapping_table_size_bytes) noexcept try { - check_pointer(decoder)->get_mapping_table_data(index, {static_cast(table_data), table_size_bytes}); + check_pointer(decoder)->get_mapping_table_data(mapping_table_index, + {static_cast(mapping_table_data), mapping_table_size_bytes}); return jpegls_errc::success; } catch (...) diff --git a/src/charls_jpegls_encoder.cpp b/src/charls_jpegls_encoder.cpp index 344dc1fe..3d5198c1 100644 --- a/src/charls_jpegls_encoder.cpp +++ b/src/charls_jpegls_encoder.cpp @@ -93,7 +93,7 @@ struct charls_jpegls_encoder final void set_mapping_table_id(const int32_t component_index, const int32_t table_id) { check_argument_range(minimum_component_index, maximum_component_index, component_index); - check_argument_range(0, maximum_table_id, table_id); + check_argument_range(0, maximum_mapping_table_id, table_id); writer_.set_mapping_table_id(static_cast(component_index), table_id); } @@ -163,8 +163,8 @@ struct charls_jpegls_encoder final void write_mapping_table(const int32_t table_id, const int32_t entry_size, const span table_data) { - check_argument_range(minimum_table_id, maximum_table_id, table_id); - check_argument_range(minimum_entry_size, maximum_entry_size, entry_size); + check_argument_range(minimum_mapping_table_id, maximum_mapping_table_id, table_id); + check_argument_range(minimum_mapping_entry_size, maximum_mapping_entry_size, entry_size); check_argument(table_data.data() || table_data.empty()); check_argument(table_data.size() >= static_cast(entry_size), jpegls_errc::invalid_argument_size); check_operation(state_ >= state::destination_set && state_ < state::completed); @@ -178,21 +178,13 @@ struct charls_jpegls_encoder final check_argument(source.data() || source.empty()); check_operation(is_frame_info_configured() && state_ != state::initial); check_interleave_mode_against_component_count(); + stride = check_stride_and_source(source.size(), stride); const int32_t maximum_sample_value{calculate_maximum_sample_value(frame_info_.bits_per_sample)}; if (UNLIKELY( !is_valid(user_preset_coding_parameters_, maximum_sample_value, near_lossless_, &preset_coding_parameters_))) throw_jpegls_error(jpegls_errc::invalid_argument_jpegls_pc_parameters); - if (stride == auto_calculate_stride) - { - stride = calculate_stride(); - } - else - { - check_stride(stride, source.size()); - } - transition_to_tables_and_miscellaneous_state(); write_color_transform_segment(); write_start_of_frame_segment(); @@ -283,36 +275,39 @@ struct charls_jpegls_encoder final } [[nodiscard]] - size_t calculate_stride() const noexcept - { - const auto stride{static_cast(frame_info_.width) * bit_to_byte_count(frame_info_.bits_per_sample)}; - if (interleave_mode_ == interleave_mode::none) - return stride; - - return stride * frame_info_.component_count; - } - - void check_stride(const size_t stride, const size_t source_size) const + size_t check_stride_and_source(const size_t source_size, size_t stride) const { - const size_t minimum_stride{calculate_stride()}; - if (UNLIKELY(stride < minimum_stride)) - throw_jpegls_error(jpegls_errc::invalid_argument_stride); - - // Simple check to verify user input, and prevent out-of-bound read access. - // Stride parameter defines the number of bytes on a scan line. - if (interleave_mode_ == interleave_mode::none) + const size_t minimum_stride{calculate_minimum_stride()}; + if (stride == auto_calculate_stride) { - if (const size_t minimum_source_size{stride * frame_info_.component_count * frame_info_.height - - (stride - minimum_stride)}; - UNLIKELY(source_size < minimum_source_size)) - throw_jpegls_error(jpegls_errc::invalid_argument_stride); + stride = minimum_stride; } else { - if (const size_t minimum_source_size{stride * frame_info_.height - (stride - minimum_stride)}; - UNLIKELY(source_size < minimum_source_size)) + if (UNLIKELY(stride < minimum_stride)) throw_jpegls_error(jpegls_errc::invalid_argument_stride); } + + const size_t not_used_bytes_at_end{stride - minimum_stride}; + const size_t minimum_source_size{interleave_mode_ == interleave_mode::none + ? (stride * frame_info_.component_count * frame_info_.height) - + not_used_bytes_at_end + : (stride * frame_info_.height) - not_used_bytes_at_end}; + + if (UNLIKELY(source_size < minimum_source_size)) + throw_jpegls_error(jpegls_errc::invalid_argument_size); + + return stride; + } + + [[nodiscard]] + size_t calculate_minimum_stride() const noexcept + { + const auto stride{static_cast(frame_info_.width) * bit_to_byte_count(frame_info_.bits_per_sample)}; + if (interleave_mode_ == interleave_mode::none) + return stride; + + return stride * frame_info_.component_count; } void check_interleave_mode_against_component_count() const diff --git a/src/constants.h b/src/constants.h index 90b07e1a..20ae2a06 100644 --- a/src/constants.h +++ b/src/constants.h @@ -23,10 +23,10 @@ constexpr int32_t minimum_application_data_id{}; constexpr int32_t maximum_application_data_id{15}; // The following limits for mapping tables are defined in ISO/IEC 14495-1, C.2.4.1.2, table C.4. -constexpr int32_t minimum_table_id{1}; -constexpr int32_t maximum_table_id{255}; -constexpr int32_t minimum_entry_size{1}; -constexpr int32_t maximum_entry_size{255}; +constexpr int32_t minimum_mapping_table_id{1}; +constexpr int32_t maximum_mapping_table_id{255}; +constexpr int32_t minimum_mapping_entry_size{1}; +constexpr int32_t maximum_mapping_entry_size{255}; constexpr int32_t max_k_value{16}; // This is an implementation limit (theoretical limit is 32) diff --git a/src/jpeg_stream_reader.cpp b/src/jpeg_stream_reader.cpp index 1c2b4c79..1410684d 100644 --- a/src/jpeg_stream_reader.cpp +++ b/src/jpeg_stream_reader.cpp @@ -132,7 +132,6 @@ void jpeg_stream_reader::read_header(spiff_header* header, bool* spiff_header_fo if (state_ == state::bit_stream_section) { - check_frame_info(); check_coding_parameters(); return; } @@ -147,9 +146,7 @@ void jpeg_stream_reader::read_end_of_image() if (const jpeg_marker_code marker_code{read_next_marker_code()}; UNLIKELY(marker_code != jpeg_marker_code::end_of_image)) throw_jpegls_error(jpegls_errc::end_of_image_marker_not_found); -#ifndef NDEBUG state_ = state::after_end_of_image; -#endif } @@ -265,10 +262,10 @@ int32_t jpeg_stream_reader::get_mapping_table_id(const size_t component_index) c } -int32_t jpeg_stream_reader::get_mapping_table_index(const uint8_t table_id) const noexcept +int32_t jpeg_stream_reader::find_mapping_table_index(const uint8_t mapping_table_id) const noexcept { - const auto it{find_mapping_table_entry(table_id)}; - return it != mapping_tables_.cend() ? static_cast(it - mapping_tables_.cbegin()) : mapping_table_missing; + const auto it{find_mapping_table_entry(mapping_table_id)}; + return it == mapping_tables_.cend() ? mapping_table_missing : static_cast(it - mapping_tables_.cbegin()); } @@ -299,6 +296,7 @@ void jpeg_stream_reader::read_marker_segment(const jpeg_marker_code marker_code, break; case jpeg_marker_code::start_of_scan: + check_height_and_width(); read_start_of_scan_segment(); break; @@ -421,10 +419,6 @@ void jpeg_stream_reader::read_preset_parameters_segment() read_preset_coding_parameters(); return; - case jpegls_preset_parameters_type::oversize_image_dimension: - read_oversize_image_dimension(); - return; - case jpegls_preset_parameters_type::mapping_table_specification: read_mapping_table_specification(); return; @@ -432,6 +426,10 @@ void jpeg_stream_reader::read_preset_parameters_segment() case jpegls_preset_parameters_type::mapping_table_continuation: read_mapping_table_continuation(); return; + + case jpegls_preset_parameters_type::oversize_image_dimension: + read_oversize_image_dimension(); + return; } constexpr byte jpegls_extended_preset_parameter_last{0xD}; // defined in JPEG-LS Extended (ISO/IEC 14495-2) (first = 0x5) @@ -559,8 +557,8 @@ void jpeg_stream_reader::read_start_of_scan_segment() for (size_t i{}; i != component_count_in_scan; ++i) { const uint8_t component_id{read_uint8()}; - const uint8_t table_id{read_uint8()}; - store_table_id(component_id, table_id); + const uint8_t mapping_table_id{read_uint8()}; + store_mapping_table_id(component_id, mapping_table_id); } parameters_.near_lossless = read_uint8(); // Read NEAR parameter @@ -795,7 +793,7 @@ void jpeg_stream_reader::skip_remaining_segment_data() noexcept } -void jpeg_stream_reader::check_frame_info() const +void jpeg_stream_reader::check_height_and_width() const { if (UNLIKELY(frame_info_.height < 1)) throw_jpegls_error(jpegls_errc::parameter_value_not_supported); @@ -867,7 +865,7 @@ void jpeg_stream_reader::extend_mapping_table(const uint8_t table_id, const uint } -void jpeg_stream_reader::store_table_id(const uint8_t component_id, const uint8_t table_id) +void jpeg_stream_reader::store_mapping_table_id(const uint8_t component_id, const uint8_t table_id) { if (table_id == 0) return; // default is already 0, no need to search and update. diff --git a/src/jpeg_stream_reader.h b/src/jpeg_stream_reader.h index da977018..4757e524 100644 --- a/src/jpeg_stream_reader.h +++ b/src/jpeg_stream_reader.h @@ -101,7 +101,7 @@ class jpeg_stream_reader final } [[nodiscard]] - int32_t get_mapping_table_index(uint8_t table_id) const noexcept; + int32_t find_mapping_table_index(uint8_t mapping_table_id) const noexcept; [[nodiscard]] mapping_table_info get_mapping_table_info(size_t index) const; @@ -168,31 +168,29 @@ class jpeg_stream_reader final uint32_t maximum_sample_value() const noexcept; void skip_remaining_segment_data() noexcept; - void check_frame_info() const; + void check_height_and_width() const; void check_coding_parameters() const; void frame_info_height(uint32_t height); void frame_info_width(uint32_t width); void call_application_data_callback(jpeg_marker_code marker_code) const; void add_mapping_table(uint8_t table_id, uint8_t entry_size, span table_data); void extend_mapping_table(uint8_t table_id, uint8_t entry_size, span table_data); - void store_table_id(uint8_t component_id, uint8_t table_id); + void store_mapping_table_id(uint8_t component_id, uint8_t table_id); + /// + /// ISO/IEC 14495-1, Annex C defines 3 data formats. + /// Annex C.4 defines the format that only contains mapping tables. + /// [[nodiscard]] bool is_abbreviated_format_for_table_specification_data() const { - if (mapping_table_count() > 0) - { - if (state_ == state::frame_section) - { - impl::throw_jpegls_error(jpegls_errc::abbreviated_format_and_spiff_header); - } + if (mapping_table_count() == 0) + return false; - // ISO/IEC 14495-1, Annex C defines 3 data formats. - // Annex C.4 defines the format that only contains mapping tables. - return state_ == state::header_section; - } + if (UNLIKELY(state_ == state::frame_section)) + impl::throw_jpegls_error(jpegls_errc::abbreviated_format_and_spiff_header_mismatch); - return false; + return state_ == state::header_section; } enum class state diff --git a/src/jpeg_stream_writer.h b/src/jpeg_stream_writer.h index a86d90a6..d3d7b89b 100644 --- a/src/jpeg_stream_writer.h +++ b/src/jpeg_stream_writer.h @@ -131,18 +131,18 @@ class jpeg_stream_writer final component_index_ = 0; } - void set_mapping_table_id(const size_t component_index, const int32_t table_id) + void set_mapping_table_id(const size_t component_index, const int32_t mapping_table_id) { ASSERT(component_index < maximum_component_count); - ASSERT(0 <= table_id && table_id <= maximum_table_id); + ASSERT(0 <= mapping_table_id && mapping_table_id <= maximum_mapping_table_id); // Usage of mapping tables is rare: use lazy initialization. - if (table_ids_.empty()) + if (mapping_table_ids_.empty()) { - table_ids_.resize(maximum_component_count); + mapping_table_ids_.resize(maximum_component_count); } - table_ids_[component_index] = static_cast(table_id); + mapping_table_ids_[component_index] = static_cast(mapping_table_id); } private: @@ -241,13 +241,13 @@ class jpeg_stream_writer final [[nodiscard]] uint8_t mapping_table_selector() const noexcept { - return table_ids_.empty() ? 0 : table_ids_[component_index_]; + return mapping_table_ids_.empty() ? 0 : mapping_table_ids_[component_index_]; } span destination_{}; size_t byte_offset_{}; uint8_t component_index_{}; - std::vector table_ids_; + std::vector mapping_table_ids_; }; } // namespace charls diff --git a/src/jpegls_algorithm.h b/src/jpegls_algorithm.h index 78652ba8..3282043f 100644 --- a/src/jpegls_algorithm.h +++ b/src/jpegls_algorithm.h @@ -119,9 +119,9 @@ constexpr int32_t compute_range_parameter(const int32_t maximum_sample_value, co /// Computes the parameter LIMIT. (see ISO/IEC 14495-1, A.2.1) /// [[nodiscard]] -constexpr int32_t compute_limit_parameter(const int32_t bits_per_pixel) +constexpr int32_t compute_limit_parameter(const int32_t bits_per_sample) { - return 2 * (bits_per_pixel + std::max(8, bits_per_pixel)); + return 2 * (bits_per_sample + std::max(8, bits_per_sample)); } diff --git a/src/jpegls_error.cpp b/src/jpegls_error.cpp index 249e3b98..961ff3c9 100644 --- a/src/jpegls_error.cpp +++ b/src/jpegls_error.cpp @@ -63,10 +63,10 @@ const char* CHARLS_API_CALLING_CONVENTION charls_get_error_message(const charls_ return "Invalid JPEG-LS stream: the JPEG stream is not encoded with the JPEG-LS algorithm"; case jpegls_errc::parameter_value_not_supported: - return "The JPEG-LS stream is encoded with a parameter value that is not supported by the CharLS decoder"; + return "The JPEG-LS stream is encoded with a parameter value that is not supported by the this decoder"; case jpegls_errc::color_transform_not_supported: - return "The color transform is not supported"; + return "The HP color transform is not supported"; case jpegls_errc::jpegls_preset_extended_parameter_type_not_supported: return "Unsupported JPEG-LS stream: JPEG-LS preset parameters segment contains a JPEG-LS Extended (ISO/IEC " @@ -120,7 +120,7 @@ const char* CHARLS_API_CALLING_CONVENTION charls_get_error_message(const charls_ case jpegls_errc::unknown_component_id: return "Invalid JPEG-LS stream: unknown component ID in scan segment"; - case jpegls_errc::abbreviated_format_and_spiff_header: + case jpegls_errc::abbreviated_format_and_spiff_header_mismatch: return "Invalid JPEG-LS stream: mapping tables without SOF but with spiff header"; case jpegls_errc::invalid_parameter_width: @@ -145,8 +145,7 @@ const char* CHARLS_API_CALLING_CONVENTION charls_get_error_message(const charls_ return "Invalid JPEG-LS stream: JPEG-LS preset parameters segment contains invalid values"; case jpegls_errc::invalid_parameter_color_transformation: - return "Invalid JPEG-LS stream: Color transformation segment contains invalid values or doesn't match with frame " - "info"; + return "Invalid JPEG-LS stream: Color transformation segment contains invalid values or frame info mismatch"; case jpegls_errc::invalid_parameter_mapping_table_id: return "Invalid JPEG-LS stream: mapping table ID outside valid range or duplicate"; @@ -175,7 +174,7 @@ const char* CHARLS_API_CALLING_CONVENTION charls_get_error_message(const charls_ return "The component count argument is outside the range [1, 255]"; case jpegls_errc::invalid_argument_interleave_mode: - return "The interleave mode is not None, Sample, Line) or invalid in combination with component count"; + return "The interleave mode is not None, Sample, Line or invalid in combination with component count"; case jpegls_errc::invalid_argument_near_lossless: return "The near lossless argument is outside the range [0, min(255, MAXVAL/2)]"; diff --git a/src/lossless_traits.h b/src/lossless_traits.h index a415ff2a..ec115163 100644 --- a/src/lossless_traits.h +++ b/src/lossless_traits.h @@ -97,7 +97,7 @@ struct lossless_traits final : lossless_traits_impl { using pixel_type = sample_type; - FORCE_INLINE constexpr static int8_t mod_range(const int32_t error_value) noexcept + FORCE_INLINE constexpr static int8_t modulo_range(const int32_t error_value) noexcept { return static_cast(error_value); } @@ -120,7 +120,7 @@ struct lossless_traits final : lossless_traits_impl { using pixel_type = sample_type; - FORCE_INLINE constexpr static int16_t mod_range(const int32_t error_value) noexcept + FORCE_INLINE constexpr static int16_t modulo_range(const int32_t error_value) noexcept { return static_cast(error_value); } diff --git a/src/process_encoded_line.h b/src/process_encoded_line.h index f7b62e19..39ad75d4 100644 --- a/src/process_encoded_line.h +++ b/src/process_encoded_line.h @@ -58,11 +58,11 @@ class process_encoded_single_component_masked final : public process_encoded_lin { public: 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 : + const uint32_t bits_per_sample) noexcept : source_{source}, source_stride_{source_stride}, bytes_per_pixel_{bytes_per_pixel}, - mask_{(1U << bits_per_pixel) - 1U}, + mask_{(1U << bits_per_sample) - 1U}, single_byte_pixel_{bytes_per_pixel_ == sizeof(std::byte)} { ASSERT(bytes_per_pixel == sizeof(std::byte) || bytes_per_pixel == sizeof(uint16_t)); diff --git a/src/run_mode_context.h b/src/run_mode_context.h index de92a1e3..6424babd 100644 --- a/src/run_mode_context.h +++ b/src/run_mode_context.h @@ -99,12 +99,6 @@ class run_mode_context final return false; } - [[nodiscard]] - FORCE_INLINE bool compute_map_negative_e(const int32_t k) const noexcept - { - return k != 0 || 2 * nn_ >= n_; - } - private: // Initialize with the default values as defined in ISO 14495-1, A.8, step 1.d and 1.f. int32_t run_interruption_type_{}; diff --git a/src/scan_codec.h b/src/scan_codec.h index 4bdfa17f..4b6e33a5 100644 --- a/src/scan_codec.h +++ b/src/scan_codec.h @@ -136,15 +136,6 @@ class scan_codec return frame_info_; } - [[nodiscard]] - bool is_interleaved() const noexcept - { - ASSERT((parameters().interleave_mode == interleave_mode::none && frame_info().component_count == 1) || - parameters().interleave_mode != interleave_mode::none); - - return parameters().interleave_mode != interleave_mode::none; - } - void reset_parameters(const int32_t range) noexcept { const regular_mode_context context_initial_value(range); diff --git a/src/scan_decoder.h b/src/scan_decoder.h index 670c5d2e..312173a0 100644 --- a/src/scan_decoder.h +++ b/src/scan_decoder.h @@ -88,7 +88,7 @@ class scan_decoder : protected scan_codec } [[nodiscard]] - const std::byte* get_cur_byte_pos() const noexcept + const std::byte* get_actual_position() const noexcept { int32_t valid_bits{valid_bits_}; const std::byte* compressed_bytes{position_}; diff --git a/src/scan_decoder_impl.h b/src/scan_decoder_impl.h index 3280fc5e..b6215a70 100644 --- a/src/scan_decoder_impl.h +++ b/src/scan_decoder_impl.h @@ -43,7 +43,7 @@ class scan_decoder_impl final : public scan_decoder decode_lines(); end_scan(); - return get_cur_byte_pos() - scan_begin; + return get_actual_position() - scan_begin; } private: @@ -265,7 +265,7 @@ class scan_decoder_impl final : public scan_decoder if (end_index - 1 == width_) return end_index - start_index; - // run interruption + // Run interruption const pixel_type rb{previous_line_[end_index]}; current_line_[end_index] = decode_run_interruption_pixel(ra, rb); decrement_run_index(); @@ -375,7 +375,7 @@ class scan_decoder_impl final : public scan_decoder if (index != pixel_count) { - // incomplete run. + // Incomplete run. index += (J[run_index_] > 0) ? read_value(J[run_index_]) : 0; } diff --git a/test/compliance.cpp b/test/compliance.cpp index 4368f809..a666b8fa 100644 --- a/test/compliance.cpp +++ b/test/compliance.cpp @@ -62,7 +62,7 @@ bool verify_encoded_bytes(const void* uncompressed_data, const size_t uncompress encoder.destination(our_encoded_bytes); encoder.frame_info(decoder.frame_info()); encoder.interleave_mode(decoder.interleave_mode()); - encoder.near_lossless(decoder.near_lossless()); + encoder.near_lossless(decoder.get_near_lossless()); encoder.preset_coding_parameters(decoder.preset_coding_parameters()); std::ignore = encoder.encode(uncompressed_data, uncompressed_length); @@ -99,7 +99,7 @@ void test_compliance(const byte* compressed_bytes, const size_t compressed_lengt const auto destination{decoder.decode>()}; - if (decoder.near_lossless() == 0) + if (decoder.get_near_lossless() == 0) { for (size_t i{}; i != uncompressed_length; ++i) { @@ -208,7 +208,7 @@ void test_sample_annex_h4_5() jpegls_decoder decoder; decoder.source(palettised_data); decoder.read_header(); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); constexpr array expected{byte{0}, byte{0}, byte{1}, byte{1}, byte{1}, byte{2}, @@ -218,7 +218,7 @@ void test_sample_annex_h4_5() const int32_t mapping_table_id{decoder.get_mapping_table_id(0)}; assert::is_true(mapping_table_id == 5); - const auto table_index{decoder.get_mapping_table_index(mapping_table_id)}; + const auto table_index{decoder.find_mapping_table_index(mapping_table_id)}; const mapping_table_info table_info{decoder.get_mapping_table_info(table_index)}; vector mapping_table(table_info.data_size); diff --git a/test/main.cpp b/test/main.cpp index 9d898b09..3075650a 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -39,6 +39,7 @@ using std::string; using std::stringstream; using std::uniform_int_distribution; using std::vector; +using std::ignore; using namespace charls; namespace { @@ -249,7 +250,7 @@ void test_fail_on_too_small_output_buffer() jpegls_encoder encoder; encoder.destination(output_buffer); encoder.frame_info({8, 8, 8, 1}); - std::ignore = encoder.encode(input_buffer); + ignore = encoder.encode(input_buffer); assert::is_true(false); } catch (const jpegls_error& e) @@ -264,7 +265,7 @@ void test_fail_on_too_small_output_buffer() jpegls_encoder encoder; encoder.destination(output_buffer); encoder.frame_info({8, 8, 8, 1}); - std::ignore = encoder.encode(input_buffer); + ignore = encoder.encode(input_buffer); assert::is_true(false); } catch (const jpegls_error& e) diff --git a/test/performance.cpp b/test/performance.cpp index 0449d985..920a33ad 100644 --- a/test/performance.cpp +++ b/test/performance.cpp @@ -99,7 +99,7 @@ void decode_performance_tests(const int loop_count) // Pre-allocate the destination outside the measurement loop. // std::vector initializes its elements and this step needs to be excluded from the measurement. - vector destination(jpegls_decoder{encoded_source, true}.destination_size()); + vector destination(jpegls_decoder{encoded_source, true}.get_destination_size()); const auto start{steady_clock::now()}; for (int i{}; i != loop_count; ++i) diff --git a/unittest/charls_jpegls_encoder_test.cpp b/unittest/charls_jpegls_encoder_test.cpp index 4ca238ce..79e00bab 100644 --- a/unittest/charls_jpegls_encoder_test.cpp +++ b/unittest/charls_jpegls_encoder_test.cpp @@ -228,7 +228,7 @@ TEST_CLASS(charls_jpegls_encoder_test) Assert::AreEqual(jpegls_errc::success, error); error = charls_jpegls_encoder_encode_from_buffer(encoder, nullptr, 0, 0); - Assert::AreEqual(jpegls_errc::destination_too_small, error); + Assert::AreEqual(jpegls_errc::invalid_argument_size, error); charls_jpegls_encoder_destroy(encoder); } diff --git a/unittest/color_transform_test.cpp b/unittest/color_transform_test.cpp index 295b1271..53f9db74 100644 --- a/unittest/color_transform_test.cpp +++ b/unittest/color_transform_test.cpp @@ -15,6 +15,7 @@ using Microsoft::VisualStudio::CppUnitTestFramework::Assert; using std::byte; using std::vector; +using std::ignore; namespace charls::test { @@ -120,7 +121,7 @@ TEST_CLASS(color_transform_test) encoder.destination(destination).frame_info(frame_info).color_transformation(color_transformation::hp3); const vector source(20); assert_expect_exception(jpegls_errc::invalid_argument_color_transformation, - [&encoder, &source] { std::ignore = encoder.encode(source); }); + [&encoder, &source] { ignore = encoder.encode(source); }); } TEST_METHOD(encode_non_3_components_that_is_not_supported_throws) // NOLINT @@ -132,7 +133,7 @@ TEST_CLASS(color_transform_test) encoder.destination(destination).frame_info(frame_info).color_transformation(color_transformation::hp3); const vector source(20); assert_expect_exception(jpegls_errc::invalid_argument_color_transformation, - [&encoder, &source] { std::ignore = encoder.encode(source); }); + [&encoder, &source] { ignore = encoder.encode(source); }); } }; diff --git a/unittest/compliance_test.cpp b/unittest/compliance_test.cpp index ecf8dd78..9c9cdef8 100644 --- a/unittest/compliance_test.cpp +++ b/unittest/compliance_test.cpp @@ -38,110 +38,110 @@ namespace charls::test { TEST_CLASS(compliance_test) { public: - TEST_METHOD(decompress_color_8_bit_interleave_none_lossless) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_none_lossless) // NOLINT { // ISO 14495-1: official test image 1 (T87_test-1-2-3-4-5-6.zip) - decompress_file("DataFiles/t8c0e0.jls", "DataFiles/test8.ppm"); + decode_encode_file("DataFiles/t8c0e0.jls", "DataFiles/test8.ppm"); } - TEST_METHOD(decompress_color_8_bit_interleave_line_lossless) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_line_lossless) // NOLINT { // ISO 14495-1: official test image 2 (T87_test-1-2-3-4-5-6.zip) - decompress_file("DataFiles/t8c1e0.jls", "DataFiles/test8.ppm"); + decode_encode_file("DataFiles/t8c1e0.jls", "DataFiles/test8.ppm"); } - TEST_METHOD(decompress_color_8_bit_interleave_sample_lossless) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_sample_lossless) // NOLINT { // ISO 14495-1: official test image 3 (T87_test-1-2-3-4-5-6.zip) - decompress_file("DataFiles/t8c2e0.jls", "DataFiles/test8.ppm"); + decode_encode_file("DataFiles/t8c2e0.jls", "DataFiles/test8.ppm"); } - TEST_METHOD(decompress_color_8_bit_interleave_none_near_lossless_3) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_none_near_lossless_3) // NOLINT { // ISO 14495-1: official test image 4 (T87_test-1-2-3-4-5-6.zip) - decompress_file("DataFiles/t8c0e3.jls", "DataFiles/test8.ppm"); + decode_encode_file("DataFiles/t8c0e3.jls", "DataFiles/test8.ppm"); } - TEST_METHOD(decompress_color_8_bit_interleave_line_near_lossless_3) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_line_near_lossless_3) // NOLINT { // ISO 14495-1: official test image 5 (T87_test-1-2-3-4-5-6.zip) - decompress_file("DataFiles/t8c1e3.jls", "DataFiles/test8.ppm"); + decode_encode_file("DataFiles/t8c1e3.jls", "DataFiles/test8.ppm"); } - TEST_METHOD(decompress_color_8_bit_interleave_sample_near_lossless_3) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_sample_near_lossless_3) // NOLINT { // ISO 14495-1: official test image 6 (T87_test-1-2-3-4-5-6.zip) - decompress_file("DataFiles/t8c2e3.jls", "DataFiles/test8.ppm"); + decode_encode_file("DataFiles/t8c2e3.jls", "DataFiles/test8.ppm"); } - TEST_METHOD(decompress_color_8_bit_interleave_line_lossless_non_default) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_line_lossless_non_default) // NOLINT { // ISO 14495-1: official test image 9 (T87_test-1-2-3-4-5-6.zip) // NON-DEFAULT parameters T1=T2=T3=9,RESET=31. - decompress_file("DataFiles/t8nde0.jls", "DataFiles/test8bs2.pgm"); + decode_encode_file("DataFiles/t8nde0.jls", "DataFiles/test8bs2.pgm"); } - TEST_METHOD(decompress_color_8_bit_interleave_line_near_lossless_3_non_default) // NOLINT + TEST_METHOD(decode_encode_color_8_bit_interleave_line_near_lossless_3_non_default) // NOLINT { // ISO 14495-1: official test image 10 (T87_test-1-2-3-4-5-6.zip) // NON-DEFAULT parameters T1=T2=T3=9,RESET=31. - decompress_file("DataFiles/t8nde3.jls", "DataFiles/test8bs2.pgm"); + decode_encode_file("DataFiles/t8nde3.jls", "DataFiles/test8bs2.pgm"); } - TEST_METHOD(decompress_monochrome_16_bit_lossless) // NOLINT + TEST_METHOD(decode_encode_monochrome_16_bit_lossless) // NOLINT { // ISO 14495-1: official test image 11 (T87_test-11-12.zip) // Note: test image is actually 12 bit. - decompress_file("DataFiles/t16e0.jls", "DataFiles/test16.pgm"); + decode_encode_file("DataFiles/t16e0.jls", "DataFiles/test16.pgm"); } - TEST_METHOD(decompress_monochrome_16_bit_near_lossless_3) // NOLINT + TEST_METHOD(decode_monochrome_16_bit_near_lossless_3) // NOLINT { // ISO 14495-1: official test image 12 (T87_test-11-12.zip) // Note: test image is actually 12 bit. - decompress_file("DataFiles/t16e3.jls", "DataFiles/TEST16.pgm", false); + decode_encode_file("DataFiles/t16e3.jls", "DataFiles/TEST16.pgm", false); } - TEST_METHOD(tulips_monochrome_8_bit_lossless_hp) // NOLINT + TEST_METHOD(decode_encode_tulips_monochrome_8_bit_lossless_hp) // NOLINT { // Additional, Tulips encoded with HP 1.0BETA encoder. - decompress_file("DataFiles/tulips-gray-8bit-512-512-hp-encoder.jls", "DataFiles/tulips-gray-8bit-512-512.pgm"); + decode_encode_file("DataFiles/tulips-gray-8bit-512-512-hp-encoder.jls", "DataFiles/tulips-gray-8bit-512-512.pgm"); } - TEST_METHOD(decompress_color_8_bit_interleave_none_lossless_restart_7) // NOLINT + TEST_METHOD(decode_color_8_bit_interleave_none_lossless_restart_7) // NOLINT { // ISO 14495-1: official test image 1 but with restart markers. - decompress_file("DataFiles/test8_ilv_none_rm_7.jls", "DataFiles/test8.ppm", false); + decode_encode_file("DataFiles/test8_ilv_none_rm_7.jls", "DataFiles/test8.ppm", false); } - TEST_METHOD(decompress_color_8_bit_interleave_line_lossless_restart_7) // NOLINT + TEST_METHOD(decode_color_8_bit_interleave_line_lossless_restart_7) // NOLINT { // ISO 14495-1: official test image 2 but with restart markers. - decompress_file("DataFiles/test8_ilv_line_rm_7.jls", "DataFiles/test8.ppm", false); + decode_encode_file("DataFiles/test8_ilv_line_rm_7.jls", "DataFiles/test8.ppm", false); } - TEST_METHOD(decompress_color_8_bit_interleave_sample_lossless_restart_7) // NOLINT + TEST_METHOD(decode_color_8_bit_interleave_sample_lossless_restart_7) // NOLINT { // ISO 14495-1: official test image 3 but with restart markers. - decompress_file("DataFiles/test8_ilv_sample_rm_7.jls", "DataFiles/test8.ppm", false); + decode_encode_file("DataFiles/test8_ilv_sample_rm_7.jls", "DataFiles/test8.ppm", false); } - TEST_METHOD(decompress_color_8_bit_interleave_sample_lossless_restart_300) // NOLINT + TEST_METHOD(decode_color_8_bit_interleave_sample_lossless_restart_300) // NOLINT { // ISO 14495-1: official test image 3 but with restart markers and restart interval 300 - decompress_file("DataFiles/test8_ilv_sample_rm_300.jls", "DataFiles/test8.ppm", false); + decode_encode_file("DataFiles/test8_ilv_sample_rm_300.jls", "DataFiles/test8.ppm", false); } - TEST_METHOD(decompress_monochrome_16_bit_restart_5) // NOLINT + TEST_METHOD(decode_monochrome_16_bit_restart_5) // NOLINT { // ISO 14495-1: official test image 12 but with restart markers and restart interval 5 - decompress_file("DataFiles/test16_rm_5.jls", "DataFiles/test16.pgm", false); + decode_encode_file("DataFiles/test16_rm_5.jls", "DataFiles/test16.pgm", false); } - TEST_METHOD(decompress_mapping_table_sample_annex_h4_5) // NOLINT + TEST_METHOD(decode_mapping_table_sample_annex_h4_5) // NOLINT { // ISO 14495-1: Sample image from appendix H.4.5 "Example of a palletised image" / Figure H.10 - constexpr array palettised_data{ + constexpr array palletised_data{ byte{0xFF}, byte{0xD8}, // Start of image (SOI) marker byte{0xFF}, byte{0xF7}, // Start of JPEG-LS frame (SOF 55) marker - marker segment follows byte{0x00}, byte{0x0B}, // Length of marker segment = 11 bytes including the length field @@ -176,9 +176,9 @@ TEST_CLASS(compliance_test) }; jpegls_decoder decoder; - decoder.source(palettised_data); + decoder.source(palletised_data); decoder.read_header(); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); constexpr array expected{byte{0}, byte{0}, byte{1}, byte{1}, byte{1}, byte{2}, @@ -188,7 +188,7 @@ TEST_CLASS(compliance_test) const int32_t mapping_table_id{decoder.get_mapping_table_id(0)}; Assert::AreEqual(5, mapping_table_id); - const auto table_index{decoder.get_mapping_table_index(mapping_table_id)}; + const auto table_index{decoder.find_mapping_table_index(mapping_table_id)}; const mapping_table_info table_info{decoder.get_mapping_table_info(table_index)}; vector mapping_table(table_info.data_size); @@ -202,7 +202,7 @@ TEST_CLASS(compliance_test) } private: - static void decompress_file(const char* encoded_filename, const char* raw_filename, const bool check_encode = true) + static void decode_encode_file(const char* encoded_filename, const char* raw_filename, const bool check_encode = true) { const auto encoded_source{read_file(encoded_filename)}; const jpegls_decoder decoder{encoded_source, true}; diff --git a/unittest/documentation_test.cpp b/unittest/documentation_test.cpp index a0ad27c2..fbd07a0a 100644 --- a/unittest/documentation_test.cpp +++ b/unittest/documentation_test.cpp @@ -42,7 +42,7 @@ std::vector decode_advanced(const std::vector& source) throw std::runtime_error("Not a grayscale image"); // After read_header() other properties can also be retrieved. - if (decoder.near_lossless() != 0) + if (decoder.get_near_lossless() != 0) { // Handle lossy images. } @@ -149,7 +149,7 @@ TEST_CLASS(documentation_test) Assert::AreEqual(reference_file.bits_per_sample(), frame_info.bits_per_sample); Assert::AreEqual(interleave_mode, decoder.interleave_mode()); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); const vector& uncompressed_source{reference_file.image_data()}; diff --git a/unittest/encode_test.cpp b/unittest/encode_test.cpp index 697b153a..3e8deb4a 100644 --- a/unittest/encode_test.cpp +++ b/unittest/encode_test.cpp @@ -87,6 +87,12 @@ TEST_CLASS(encode_test) encode("DataFiles/test8.ppm", 91862, interleave_mode::sample, color_transformation::hp3); } + TEST_METHOD(encode_monchrome_16_bit_interleave_none) // NOLINT + { + constexpr array data{byte{}, byte{10}, byte{}, byte{20}, byte{}, byte{30}, byte{}, byte{40}}; + encode({2, 2, 16, 1}, {data.cbegin(), data.cend()}, 36, interleave_mode::none); + } + TEST_METHOD(encode_color_16_bit_interleave_none) // NOLINT { constexpr array data{byte{10}, byte{20}, byte{30}, byte{40}, byte{50}, byte{60}}; @@ -101,8 +107,11 @@ TEST_CLASS(encode_test) TEST_METHOD(encode_color_16_bit_interleave_sample) // NOLINT { - constexpr array data{byte{10}, byte{20}, byte{30}, byte{40}, byte{50}, byte{60}}; - encode({1, 1, 16, 3}, {data.cbegin(), data.cend()}, 45, interleave_mode::sample); + constexpr array data{byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, // row 0, pixel 0 + byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, // row 0, pixel 1 + byte{1}, byte{10}, byte{1}, byte{20}, byte{1}, byte{30}, // row 1, pixel 0 + byte{1}, byte{40}, byte{1}, byte{50}, byte{1}, byte{60}}; // row 1, pixel 1 + encode({2, 2, 16, 3}, {data.cbegin(), data.cend()}, 51, interleave_mode::sample); } TEST_METHOD(encode_color_16_bit_interleave_line_hp1) // NOLINT @@ -173,8 +182,14 @@ TEST_CLASS(encode_test) TEST_METHOD(encode_4_components_16_bit_interleave_sample) // NOLINT { - constexpr array data{byte{10}, byte{20}, byte{30}, byte{40}, byte{50}, byte{60}, byte{70}, byte{80}}; - encode({1, 1, 16, 4}, {data.cbegin(), data.cend()}, 52, interleave_mode::sample); + constexpr array data{byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, // row 0, pixel 0 + byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, byte{}, // row 0, pixel 1 + byte{1}, byte{10}, byte{1}, byte{20}, byte{1}, byte{30}, byte{1}, byte{40}, // row 1, pixel 0 + byte{1}, byte{50}, byte{1}, byte{60}, byte{1}, byte{70}, byte{1}, byte{80}}; // row 1, pixel 1 + + + // constexpr array data{byte{10}, byte{20}, byte{30}, byte{40}, byte{50}, byte{60}, byte{70}, byte{80}}; + encode({2, 2, 16, 4}, {data.cbegin(), data.cend()}, 61, interleave_mode::sample); } private: @@ -222,12 +237,12 @@ TEST_CLASS(encode_test) Assert::IsTrue(interleave_mode == decoder.interleave_mode()); Assert::IsTrue(color_transformation == decoder.color_transformation()); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); Assert::AreEqual(destination.size(), reference_source.size()); - if (decoder.near_lossless() == 0) + if (decoder.get_near_lossless() == 0) { for (size_t i{}; i != reference_source.size(); ++i) { diff --git a/unittest/jpeg_stream_reader_test.cpp b/unittest/jpeg_stream_reader_test.cpp index 16cc7b76..3ccc30d2 100644 --- a/unittest/jpeg_stream_reader_test.cpp +++ b/unittest/jpeg_stream_reader_test.cpp @@ -170,9 +170,9 @@ TEST_CLASS(jpeg_stream_reader_test) TEST_METHOD(read_header_with_too_small_start_of_frame_throws) // NOLINT { - constexpr array buffer{byte{0xFF}, byte{0xD8}, - byte{0xFF}, byte{0xF7}, // SOF_55: Marks the start of JPEG-LS extended scan. - byte{0x00}, byte{0x07}}; + constexpr array buffer{ + byte{0xFF}, byte{0xD8}, byte{0xFF}, byte{0xF7}, // SOF_55: Marks the start of JPEG-LS extended scan. + byte{0x00}, byte{0x06}, byte{2}, byte{2}, byte{2}, byte{2}, byte{2}, byte{2}, byte{1}}; jpeg_stream_reader reader; reader.source(buffer); @@ -182,9 +182,9 @@ TEST_CLASS(jpeg_stream_reader_test) TEST_METHOD(read_header_with_too_small_start_of_frame_in_component_info_throws) // NOLINT { - constexpr array buffer{byte{0xFF}, byte{0xD8}, - byte{0xFF}, byte{0xF7}, // SOF_55: Marks the start of JPEG-LS extended scan. - byte{0x00}, byte{0x07}}; + constexpr array buffer{ + byte{0xFF}, byte{0xD8}, byte{0xFF}, byte{0xF7}, // SOF_55: Marks the start of JPEG-LS extended scan. + byte{0x00}, byte{0x08}, byte{2}, byte{2}, byte{2}, byte{2}, byte{2}, byte{2}, byte{1}}; jpeg_stream_reader reader; reader.source(buffer); @@ -705,7 +705,7 @@ TEST_CLASS(jpeg_stream_reader_test) reader.read_header(); Assert::AreEqual(size_t{1}, reader.mapping_table_count()); - Assert::AreEqual(0, reader.get_mapping_table_index(1)); + Assert::AreEqual(0, reader.find_mapping_table_index(1)); const auto info{reader.get_mapping_table_info(0)}; Assert::AreEqual(int32_t{1}, info.table_id); @@ -824,7 +824,7 @@ TEST_CLASS(jpeg_stream_reader_test) reader.read_header(); Assert::AreEqual(size_t{1}, reader.mapping_table_count()); - Assert::AreEqual(0, reader.get_mapping_table_index(1)); + Assert::AreEqual(0, reader.find_mapping_table_index(1)); const auto info{reader.get_mapping_table_info(0)}; Assert::AreEqual(int32_t{1}, info.table_id); diff --git a/unittest/jpeg_test_stream_writer.h b/unittest/jpeg_test_stream_writer.h index 13b0104c..c436b3da 100644 --- a/unittest/jpeg_test_stream_writer.h +++ b/unittest/jpeg_test_stream_writer.h @@ -135,7 +135,7 @@ class jpeg_test_stream_writer final write_segment(jpeg_marker_code::jpegls_preset_parameters, segment.data(), segment.size()); } - void write_oversize_image_dimension(const uint32_t number_of_bytes, const uint32_t height, const uint32_t width, + void write_oversize_image_dimension(const uint32_t number_of_bytes, const uint32_t width, const uint32_t height, const bool extra_byte = false) { // Format is defined in ISO/IEC 14495-1, C.2.4.1.4 @@ -171,7 +171,6 @@ class jpeg_test_stream_writer final write_segment(jpeg_marker_code::jpegls_preset_parameters, segment.data(), segment.size()); } - void write_start_of_scan_segment(int component_id, const int component_count, const int near_lossless, const interleave_mode interleave_mode) { diff --git a/unittest/jpegls_decoder_test.cpp b/unittest/jpegls_decoder_test.cpp index e89bae13..04bd1279 100644 --- a/unittest/jpegls_decoder_test.cpp +++ b/unittest/jpegls_decoder_test.cpp @@ -82,7 +82,7 @@ TEST_CLASS(jpegls_decoder_test) { const jpegls_decoder decoder; - assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.destination_size(); }); + assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.get_destination_size(); }); } TEST_METHOD(read_header_without_source_throws) // NOLINT @@ -137,7 +137,7 @@ TEST_CLASS(jpegls_decoder_test) const vector source(2000); const jpegls_decoder decoder{source, false}; - assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.near_lossless(); }); + assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.get_near_lossless(); }); } TEST_METHOD(preset_coding_parameters_without_read_header_throws) // NOLINT @@ -150,17 +150,17 @@ TEST_CLASS(jpegls_decoder_test) assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.preset_coding_parameters(); }); } - TEST_METHOD(destination_size) // NOLINT + TEST_METHOD(get_destination_size) // NOLINT { const auto source{read_file("DataFiles/t8c0e0.jls")}; const jpegls_decoder decoder{source, true}; constexpr size_t expected_destination_size{size_t{256} * 256 * 3}; - Assert::AreEqual(expected_destination_size, decoder.destination_size()); + Assert::AreEqual(expected_destination_size, decoder.get_destination_size()); } - TEST_METHOD(destination_size_stride_interleave_none) // NOLINT + TEST_METHOD(get_destination_size_stride_interleave_none) // NOLINT { const auto source{read_file("DataFiles/t8c0e0.jls")}; const jpegls_decoder decoder{source, true}; @@ -168,10 +168,10 @@ TEST_CLASS(jpegls_decoder_test) constexpr size_t stride{512}; constexpr size_t minimum_stride{256}; constexpr size_t expected_destination_size{stride * 256 * 3 - (stride - minimum_stride)}; - Assert::AreEqual(expected_destination_size, decoder.destination_size(stride)); + Assert::AreEqual(expected_destination_size, decoder.get_destination_size(stride)); } - TEST_METHOD(destination_size_stride_interleave_none_16_bit) // NOLINT + TEST_METHOD(get_destination_size_stride_interleave_none_16_bit) // NOLINT { const auto source{read_file("DataFiles/t16e0.jls")}; const jpegls_decoder decoder{source, true}; @@ -179,10 +179,10 @@ TEST_CLASS(jpegls_decoder_test) constexpr size_t stride{513}; constexpr size_t minimum_stride{512}; constexpr size_t expected_destination_size{stride * 256 - (stride - minimum_stride)}; - Assert::AreEqual(expected_destination_size, decoder.destination_size(stride)); + Assert::AreEqual(expected_destination_size, decoder.get_destination_size(stride)); } - TEST_METHOD(destination_size_stride_interleave_line) // NOLINT + TEST_METHOD(get_destination_size_stride_interleave_line) // NOLINT { const auto source{read_file("DataFiles/t8c1e0.jls")}; const jpegls_decoder decoder{source, true}; @@ -190,10 +190,10 @@ TEST_CLASS(jpegls_decoder_test) constexpr size_t stride{1024}; constexpr size_t minimum_stride{size_t{3} * 256}; constexpr size_t expected_destination_size{stride * 256 - (stride - minimum_stride)}; - Assert::AreEqual(expected_destination_size, decoder.destination_size(stride)); + Assert::AreEqual(expected_destination_size, decoder.get_destination_size(stride)); } - TEST_METHOD(destination_size_stride_interleave_sample) // NOLINT + TEST_METHOD(get_destination_size_stride_interleave_sample) // NOLINT { const auto source{read_file("DataFiles/t8c2e0.jls")}; const jpegls_decoder decoder{source, true}; @@ -201,46 +201,46 @@ TEST_CLASS(jpegls_decoder_test) constexpr size_t stride{1024}; constexpr size_t minimum_stride{size_t{3} * 256}; constexpr size_t expected_destination_size{stride * 256 - (stride - minimum_stride)}; - Assert::AreEqual(expected_destination_size, decoder.destination_size(stride)); + Assert::AreEqual(expected_destination_size, decoder.get_destination_size(stride)); } - TEST_METHOD(destination_size_for_interleave_none_with_bad_stride_throws) // NOLINT + TEST_METHOD(get_destination_size_for_interleave_none_with_bad_stride_throws) // NOLINT { const auto source{read_file("DataFiles/t8c0e0.jls")}; const jpegls_decoder decoder{source, true}; constexpr uint32_t correct_stride{256}; assert_expect_exception(jpegls_errc::invalid_argument_stride, - [&decoder, &correct_stride] { std::ignore = decoder.destination_size(correct_stride - 1); }); + [&decoder, &correct_stride] { ignore = decoder.get_destination_size(correct_stride - 1); }); } - TEST_METHOD(destination_size_for_interleave_none_16_bit_with_bad_stride_throws) // NOLINT + TEST_METHOD(get_destination_size_for_interleave_none_16_bit_with_bad_stride_throws) // NOLINT { const auto source{read_file("DataFiles/t16e0.jls")}; const jpegls_decoder decoder{source, true}; constexpr uint32_t correct_stride{256 * 2}; assert_expect_exception(jpegls_errc::invalid_argument_stride, - [&decoder, &correct_stride] { std::ignore = decoder.destination_size(correct_stride - 1); }); + [&decoder, &correct_stride] { ignore = decoder.get_destination_size(correct_stride - 1); }); } - TEST_METHOD(destination_size_for_sample_interleave_with_bad_stride_throws) // NOLINT + TEST_METHOD(get_destination_size_for_sample_interleave_with_bad_stride_throws) // NOLINT { const auto source{read_file("DataFiles/t8c2e0.jls")}; const jpegls_decoder decoder{source, true}; constexpr uint32_t correct_stride{3 * 256}; assert_expect_exception(jpegls_errc::invalid_argument_stride, - [&decoder, &correct_stride] { std::ignore = decoder.destination_size(correct_stride - 1); }); + [&decoder, &correct_stride] { ignore = decoder.get_destination_size(correct_stride - 1); }); } - TEST_METHOD(destination_size_for_small_image_with_custom_stride) // NOLINT + TEST_METHOD(get_destination_size_for_small_image_with_custom_stride) // NOLINT { const auto source{read_file("8bit-monochrome-2x2.jls")}; jpegls_decoder decoder{source, true}; constexpr uint32_t stride{4}; - const size_t destination_size{decoder.destination_size(stride)}; + const size_t destination_size{decoder.get_destination_size(stride)}; Assert::AreEqual(size_t{6}, destination_size); vector destination(destination_size); @@ -252,7 +252,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); portable_anymap_file reference_file{ @@ -272,7 +272,7 @@ TEST_CLASS(jpegls_decoder_test) jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); portable_anymap_file reference_file{ @@ -295,7 +295,7 @@ TEST_CLASS(jpegls_decoder_test) writer.write_start_of_scan_segment(1, 2, 0, interleave_mode::sample); jpegls_decoder decoder(writer.buffer, true); - std::vector destination(decoder.destination_size()); + std::vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::parameter_value_not_supported, [&decoder, &destination] { decoder.decode(destination); }); @@ -367,7 +367,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); constexpr uint32_t correct_stride{256}; assert_expect_exception(jpegls_errc::invalid_argument_stride, [&decoder, &destination, &correct_stride] { @@ -380,7 +380,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c2e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); constexpr uint32_t correct_stride{256 * 3}; assert_expect_exception(jpegls_errc::invalid_argument_stride, [&decoder, &destination, correct_stride] { @@ -393,7 +393,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); const uint32_t standard_stride{decoder.frame_info().width}; decoder.decode(destination, standard_stride); @@ -406,7 +406,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c2e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); const uint32_t standard_stride{decoder.frame_info().width * 3}; decoder.decode(destination, standard_stride); @@ -420,7 +420,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size(custom_stride)); + vector destination(decoder.get_destination_size(custom_stride)); decoder.decode(destination, custom_stride); verify_decoded_bytes(decoder.interleave_mode(), decoder.frame_info(), destination, custom_stride, @@ -433,7 +433,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file("DataFiles/t8c2e0.jls")}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size(custom_stride)); + vector destination(decoder.get_destination_size(custom_stride)); decoder.decode(destination, custom_stride); verify_decoded_bytes(decoder.interleave_mode(), decoder.frame_info(), destination, custom_stride, @@ -544,7 +544,7 @@ TEST_CLASS(jpegls_decoder_test) const auto encoded{jpegls_encoder::encode(source_to_encode, frame_info)}; jpegls_decoder decoder{encoded, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); assert_expect_exception(jpegls_errc::invalid_operation, [&decoder, &destination] { decoder.decode(destination); }); @@ -596,7 +596,7 @@ TEST_CLASS(jpegls_decoder_test) Assert::AreEqual(1216U, frame_info.height); Assert::AreEqual(968U, frame_info.width); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::invalid_data, [&decoder, &destination] { decoder.decode(destination); }); @@ -615,7 +615,7 @@ TEST_CLASS(jpegls_decoder_test) const vector source(encoded.cbegin(), encoded.cend() - 1); jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::need_more_data, [&decoder, &destination] { decoder.decode(destination); }); } @@ -623,7 +623,7 @@ TEST_CLASS(jpegls_decoder_test) { const vector source(encoded.cbegin(), encoded.cend() - 2); jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::need_more_data, [&decoder, &destination] { decoder.decode(destination); }); @@ -633,7 +633,7 @@ TEST_CLASS(jpegls_decoder_test) auto source(encoded); source[source.size() - 1] = byte{0x33}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::end_of_image_marker_not_found, [&decoder, &destination] { decoder.decode(destination); }); @@ -652,7 +652,7 @@ TEST_CLASS(jpegls_decoder_test) Assert::AreEqual(65516U, frame_info.height); Assert::AreEqual(1U, frame_info.width); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::invalid_data, [&decoder, &destination] { decoder.decode(destination); }); @@ -670,7 +670,7 @@ TEST_CLASS(jpegls_decoder_test) Assert::AreEqual(1U, frame_info.height); Assert::AreEqual(1U, frame_info.width); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::need_more_data, [&decoder, &destination] { decoder.decode(destination); }); @@ -687,7 +687,7 @@ TEST_CLASS(jpegls_decoder_test) source.insert(it, stream_writer.buffer.cbegin(), stream_writer.buffer.cend()); jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::restart_marker_not_found, [&decoder, &destination] { decoder.decode(destination); }); @@ -704,7 +704,7 @@ TEST_CLASS(jpegls_decoder_test) *it = byte{0xD1}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::restart_marker_not_found, [&decoder, &destination] { decoder.decode(destination); }); @@ -740,7 +740,7 @@ TEST_CLASS(jpegls_decoder_test) const vector too_small_source(source.begin(), it); jpegls_decoder decoder{too_small_source, true}; - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); assert_expect_exception(jpegls_errc::need_more_data, [&decoder, &destination] { decoder.decode(destination); }); @@ -790,7 +790,7 @@ TEST_CLASS(jpegls_decoder_test) Assert::IsFalse(callback_called); } - TEST_METHOD(at_comment_that_throws_returns_callback_error) // NOLINT + TEST_METHOD(at_comment_that_throws_returns_callback_failed_error) // NOLINT { jpeg_test_stream_writer writer; writer.write_start_of_image(); @@ -876,9 +876,9 @@ TEST_CLASS(jpegls_decoder_test) { jpeg_test_stream_writer writer; writer.write_start_of_image(); - constexpr uint32_t height{numeric_limits::max() + 1U}; constexpr uint32_t width{99}; - writer.write_oversize_image_dimension(3, height, width); + constexpr uint32_t height{numeric_limits::max() + 1U}; + writer.write_oversize_image_dimension(3, width, height); writer.write_start_of_frame_segment(0, 0, 8, 3); writer.write_start_of_scan_segment(0, 1, 0, interleave_mode::none); @@ -894,8 +894,8 @@ TEST_CLASS(jpegls_decoder_test) { jpeg_test_stream_writer writer; writer.write_start_of_image(); - constexpr uint32_t height{numeric_limits::max()}; constexpr uint32_t width{99}; + constexpr uint32_t height{numeric_limits::max()}; writer.write_oversize_image_dimension(2, 0, 0); writer.write_start_of_frame_segment(width, height, 8, 3); writer.write_start_of_scan_segment(0, 1, 0, interleave_mode::none); @@ -908,7 +908,6 @@ TEST_CLASS(jpegls_decoder_test) Assert::AreEqual(width, decoder.frame_info().width); } - TEST_METHOD(oversize_image_dimension_with_invalid_number_of_bytes_throws) // NOLINT { jpeg_test_stream_writer writer; @@ -929,10 +928,10 @@ TEST_CLASS(jpegls_decoder_test) { jpeg_test_stream_writer writer; writer.write_start_of_image(); - constexpr uint32_t height{numeric_limits::max()}; constexpr uint32_t width{99}; + constexpr uint32_t height{numeric_limits::max()}; writer.write_start_of_frame_segment(width, height, 8, 3); - writer.write_oversize_image_dimension(2, 0, 10); + writer.write_oversize_image_dimension(2, 10, 0); writer.write_start_of_scan_segment(0, 1, 0, interleave_mode::none); jpegls_decoder decoder; @@ -945,9 +944,9 @@ TEST_CLASS(jpegls_decoder_test) { jpeg_test_stream_writer writer; writer.write_start_of_image(); + constexpr uint32_t width{}; constexpr uint32_t height{numeric_limits::max()}; - constexpr uint32_t width{0}; - writer.write_oversize_image_dimension(2, 10, width); + writer.write_oversize_image_dimension(2, width, 10); writer.write_start_of_frame_segment(width, height, 8, 3); writer.write_start_of_scan_segment(0, 1, 0, interleave_mode::none); @@ -968,9 +967,9 @@ TEST_CLASS(jpegls_decoder_test) { jpeg_test_stream_writer writer; writer.write_start_of_image(); - constexpr uint32_t height{numeric_limits::max()}; constexpr uint32_t width{numeric_limits::max()}; - writer.write_oversize_image_dimension(4, height, width); + constexpr uint32_t height{numeric_limits::max()}; + writer.write_oversize_image_dimension(4, width, height); constexpr size_t component_count{2}; writer.write_start_of_frame_segment(0, 0, 8, component_count); writer.write_start_of_scan_segment(0, 1, 0, interleave_mode::none); @@ -981,10 +980,10 @@ TEST_CLASS(jpegls_decoder_test) #if INTPTR_MAX == INT64_MAX Assert::AreEqual(component_count * numeric_limits::max() * numeric_limits::max(), - decoder.destination_size()); + decoder.get_destination_size()); #elif INTPTR_MAX == INT32_MAX assert_expect_exception(jpegls_errc::parameter_value_not_supported, - [&decoder] { ignore = decoder.destination_size(); }); + [&decoder] { ignore = decoder.get_destination_size(); }); #else #error Unknown pointer size or missing size macros! #endif @@ -1003,7 +1002,7 @@ TEST_CLASS(jpegls_decoder_test) decoder.source(encoded_source); decoder.read_header(); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); void* data{destination.data()}; const uint16_t size{static_cast(destination.size())}; @@ -1050,7 +1049,7 @@ TEST_CLASS(jpegls_decoder_test) decoder.source(writer.buffer); decoder.read_spiff_header(); - assert_expect_exception(jpegls_errc::abbreviated_format_and_spiff_header, + assert_expect_exception(jpegls_errc::abbreviated_format_and_spiff_header_mismatch, [&decoder] { ignore = decoder.read_header(); }); } @@ -1118,7 +1117,7 @@ TEST_CLASS(jpegls_decoder_test) decoder.source(data_h10); decoder.read_header(); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); const int32_t count{decoder.mapping_table_count()}; @@ -1160,7 +1159,7 @@ TEST_CLASS(jpegls_decoder_test) const auto encoded_source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder(encoded_source, true); - vector decoded_destination(decoder.destination_size()); + vector decoded_destination(decoder.get_destination_size()); decoder.decode(decoded_destination); @@ -1174,7 +1173,7 @@ TEST_CLASS(jpegls_decoder_test) const auto encoded_source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder(encoded_source, true); - vector decoded_destination(decoder.destination_size()); + vector decoded_destination(decoder.get_destination_size()); decoder.decode(decoded_destination); @@ -1196,7 +1195,7 @@ TEST_CLASS(jpegls_decoder_test) const jpegls_decoder decoder(encoded_source, true); - assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.get_mapping_table_index(3); }); + assert_expect_exception(jpegls_errc::invalid_operation, [&decoder] { ignore = decoder.find_mapping_table_index(3); }); } TEST_METHOD(mapping_table_index_invalid_index_throws) // NOLINT @@ -1204,11 +1203,11 @@ TEST_CLASS(jpegls_decoder_test) const auto encoded_source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder(encoded_source, true); - vector decoded_destination(decoder.destination_size()); + vector decoded_destination(decoder.get_destination_size()); decoder.decode(decoded_destination); - assert_expect_exception(jpegls_errc::invalid_argument, [&decoder] { ignore = decoder.get_mapping_table_index(0); }); - assert_expect_exception(jpegls_errc::invalid_argument, [&decoder] { ignore = decoder.get_mapping_table_index(256); }); + assert_expect_exception(jpegls_errc::invalid_argument, [&decoder] { ignore = decoder.find_mapping_table_index(0); }); + assert_expect_exception(jpegls_errc::invalid_argument, [&decoder] { ignore = decoder.find_mapping_table_index(256); }); } TEST_METHOD(mapping_table_count_before_decode_throws) // NOLINT @@ -1245,7 +1244,7 @@ TEST_CLASS(jpegls_decoder_test) const auto encoded_source{read_file("DataFiles/t8c0e0.jls")}; jpegls_decoder decoder(encoded_source, true); - vector decoded_destination(decoder.destination_size()); + vector decoded_destination(decoder.get_destination_size()); decoder.decode(decoded_destination); vector table(1000); @@ -1325,7 +1324,7 @@ TEST_CLASS(jpegls_decoder_test) writer.write_start_of_image(); constexpr uint32_t height{numeric_limits::max()}; constexpr uint32_t width{0}; - writer.write_oversize_image_dimension(number_of_bytes, 10, width, true); + writer.write_oversize_image_dimension(number_of_bytes, width, 10, true); writer.write_start_of_frame_segment(width, height, 8, 3); writer.write_start_of_scan_segment(0, 1, 0, interleave_mode::none); @@ -1340,7 +1339,7 @@ TEST_CLASS(jpegls_decoder_test) const auto source{read_file(image_filename)}; jpegls_decoder decoder{source, true}; - vector destination(decoder.destination_size(stride) - 1); + vector destination(decoder.get_destination_size(stride) - 1); assert_expect_exception(jpegls_errc::destination_too_small, [&decoder, &destination, &stride] { decoder.decode(destination, stride); }); diff --git a/unittest/jpegls_encoder_test.cpp b/unittest/jpegls_encoder_test.cpp index a47dc01b..f59c0167 100644 --- a/unittest/jpegls_encoder_test.cpp +++ b/unittest/jpegls_encoder_test.cpp @@ -461,8 +461,9 @@ TEST_CLASS(jpegls_encoder_test) encoder.write_standard_spiff_header(spiff_color_space::grayscale); constexpr int32_t spiff_end_of_directory_entry_type{1}; - assert_expect_exception(jpegls_errc::invalid_argument, [&encoder, spiff_end_of_directory_entry_type] - { encoder.write_spiff_entry(spiff_end_of_directory_entry_type, "test", 4); }); + assert_expect_exception(jpegls_errc::invalid_argument, [&encoder, spiff_end_of_directory_entry_type] { + encoder.write_spiff_entry(spiff_end_of_directory_entry_type, "test", 4); + }); } TEST_METHOD(write_spiff_entry_with_invalid_size_throws) // NOLINT @@ -1059,7 +1060,8 @@ TEST_CLASS(jpegls_encoder_test) array destination; encoder.destination(destination); - assert_expect_exception(jpegls_errc::invalid_operation, [&encoder] { ignore = encoder.create_abbreviated_format(); }); + assert_expect_exception(jpegls_errc::invalid_operation, + [&encoder] { ignore = encoder.create_abbreviated_format(); }); } TEST_METHOD(set_preset_coding_parameters) // NOLINT @@ -1122,7 +1124,7 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); jpegls_decoder decoder(destination, true); - vector destination_decoded(decoder.destination_size()); + vector destination_decoded(decoder.get_destination_size()); decoder.decode(destination_decoded); Assert::AreEqual(1, decoder.get_mapping_table_id(0)); } @@ -1142,7 +1144,7 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); jpegls_decoder decoder(destination, true); - vector destination_decoded(decoder.destination_size()); + vector destination_decoded(decoder.get_destination_size()); decoder.decode(destination_decoded); Assert::AreEqual(0, decoder.get_mapping_table_id(0)); } @@ -1257,9 +1259,10 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source, 10)}; destination.resize(bytes_written); - constexpr array expected{byte{100}, byte{100}, byte{100}, byte{150}, byte{150}, - byte{150}, byte{200}, byte{200}, byte{200}}; - test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::none); + constexpr array expected_destination{byte{100}, byte{100}, byte{100}, byte{150}, byte{150}, + byte{150}, byte{200}, byte{200}, byte{200}}; + test_by_decoding(destination, frame_info, expected_destination.data(), expected_destination.size(), + interleave_mode::none); } TEST_METHOD(encode_with_stride_interleave_none_8_bit_small_image) // NOLINT @@ -1275,8 +1278,9 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source, 4)}; destination.resize(bytes_written); - constexpr array expected{byte{100}, byte{99}, byte{101}, byte{98}}; - test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::none); + constexpr array expected_destination{byte{100}, byte{99}, byte{101}, byte{98}}; + test_by_decoding(destination, frame_info, expected_destination.data(), expected_destination.size(), + interleave_mode::none); } TEST_METHOD(encode_with_stride_interleave_none_16_bit) // NOLINT @@ -1293,9 +1297,9 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source, 10 * sizeof(uint16_t))}; destination.resize(bytes_written); - constexpr array expected{100, 100, 100, 150, 150, 150, 200, 200, 200}; - test_by_decoding(destination, frame_info, expected.data(), expected.size() * sizeof(uint16_t), - interleave_mode::none); + constexpr array expected_destination{100, 100, 100, 150, 150, 150, 200, 200, 200}; + test_by_decoding(destination, frame_info, expected_destination.data(), + expected_destination.size() * sizeof(uint16_t), interleave_mode::none); } TEST_METHOD(encode_with_stride_interleave_sample_8_bit) // NOLINT @@ -1312,9 +1316,10 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source, 10)}; destination.resize(bytes_written); - constexpr array expected{byte{100}, byte{150}, byte{200}, byte{100}, byte{150}, - byte{200}, byte{100}, byte{150}, byte{200}}; - test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::sample); + constexpr array expected_destination{byte{100}, byte{150}, byte{200}, byte{100}, byte{150}, + byte{200}, byte{100}, byte{150}, byte{200}}; + test_by_decoding(destination, frame_info, expected_destination.data(), expected_destination.size(), + interleave_mode::sample); } TEST_METHOD(encode_with_stride_interleave_sample_16_bit) // NOLINT @@ -1330,9 +1335,9 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source, 10 * sizeof(uint16_t))}; destination.resize(bytes_written); - constexpr array expected{100, 150, 200, 100, 150, 200, 100, 150, 200}; - test_by_decoding(destination, frame_info, expected.data(), expected.size() * sizeof(uint16_t), - interleave_mode::sample); + constexpr array expected_destination{100, 150, 200, 100, 150, 200, 100, 150, 200}; + test_by_decoding(destination, frame_info, expected_destination.data(), + expected_destination.size() * sizeof(uint16_t), interleave_mode::sample); } TEST_METHOD(encode_with_bad_stride_interleave_none_throws) // NOLINT @@ -1347,7 +1352,7 @@ TEST_CLASS(jpegls_encoder_test) vector destination(encoder.estimated_destination_size()); encoder.destination(destination); - assert_expect_exception(jpegls_errc::invalid_argument_stride, + assert_expect_exception(jpegls_errc::invalid_argument_size, [&encoder, &source] { ignore = encoder.encode(source, 4); }); } @@ -1362,7 +1367,7 @@ TEST_CLASS(jpegls_encoder_test) vector destination(encoder.estimated_destination_size()); encoder.destination(destination); - assert_expect_exception(jpegls_errc::invalid_argument_stride, + assert_expect_exception(jpegls_errc::invalid_argument_size, [&encoder, &source] { ignore = encoder.encode(source, 7); }); } @@ -1506,13 +1511,13 @@ TEST_CLASS(jpegls_encoder_test) test_by_decoding(destination, frame_info, expected.data(), expected.size() * 2, interleave_mode::line); } - TEST_METHOD(encode_4_components_6_bit_with_high_bits_set_interleave_mode_sample) // NOLINT + TEST_METHOD(encode_4_components_5_bit_with_high_bits_set_interleave_mode_line) // NOLINT { const vector source(size_t{512} * 512 * 4, byte{0xFF}); - constexpr frame_info frame_info{512, 512, 6, 4}; + constexpr frame_info frame_info{512, 512, 5, 4}; jpegls_encoder encoder; - encoder.frame_info(frame_info).interleave_mode(interleave_mode::sample); + encoder.frame_info(frame_info).interleave_mode(interleave_mode::line); vector destination(encoder.estimated_destination_size()); encoder.destination(destination); @@ -1520,17 +1525,17 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); - const vector expected(size_t{512} * 512 * 4, byte{63}); - test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::sample); + const vector expected(size_t{512} * 512 * 4, byte{31}); + test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::line); } - TEST_METHOD(encode_4_components_6_bit_with_high_bits_set_interleave_mode_line) // NOLINT + TEST_METHOD(encode_4_components_7_bit_with_high_bits_set_interleave_mode_sample) // NOLINT { const vector source(size_t{512} * 512 * 4, byte{0xFF}); - constexpr frame_info frame_info{512, 512, 6, 4}; + constexpr frame_info frame_info{512, 512, 7, 4}; jpegls_encoder encoder; - encoder.frame_info(frame_info).interleave_mode(interleave_mode::line); + encoder.frame_info(frame_info).interleave_mode(interleave_mode::sample); vector destination(encoder.estimated_destination_size()); encoder.destination(destination); @@ -1538,17 +1543,17 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); - const vector expected(size_t{512} * 512 * 4, byte{63}); - test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::line); + const vector expected(size_t{512} * 512 * 4, byte{127}); + test_by_decoding(destination, frame_info, expected.data(), expected.size(), interleave_mode::sample); } - TEST_METHOD(encode_4_components_10_bit_with_high_bits_set_interleave_mode_sample) // NOLINT + TEST_METHOD(encode_4_components_11_bit_with_high_bits_set_interleave_mode_line) // NOLINT { const vector source(size_t{512} * 512 * 2 * 4, byte{0xFF}); - constexpr frame_info frame_info{512, 512, 10, 4}; + constexpr frame_info frame_info{512, 512, 11, 4}; jpegls_encoder encoder; - encoder.frame_info(frame_info).interleave_mode(interleave_mode::sample); + encoder.frame_info(frame_info).interleave_mode(interleave_mode::line); vector destination(encoder.estimated_destination_size()); encoder.destination(destination); @@ -1556,17 +1561,17 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); - const vector expected(size_t{512} * 512 * 4, 1023); - test_by_decoding(destination, frame_info, expected.data(), expected.size() * 2, interleave_mode::sample); + const vector expected(size_t{512} * 512 * 4, 2047); + test_by_decoding(destination, frame_info, expected.data(), expected.size() * 2, interleave_mode::line); } - TEST_METHOD(encode_4_components_10_bit_with_high_bits_set_interleave_mode_line) // NOLINT + TEST_METHOD(encode_4_components_13_bit_with_high_bits_set_interleave_mode_sample) // NOLINT { const vector source(size_t{512} * 512 * 2 * 4, byte{0xFF}); - constexpr frame_info frame_info{512, 512, 10, 4}; + constexpr frame_info frame_info{512, 512, 13, 4}; jpegls_encoder encoder; - encoder.frame_info(frame_info).interleave_mode(interleave_mode::line); + encoder.frame_info(frame_info).interleave_mode(interleave_mode::sample); vector destination(encoder.estimated_destination_size()); encoder.destination(destination); @@ -1574,8 +1579,8 @@ TEST_CLASS(jpegls_encoder_test) const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); - const vector expected(size_t{512} * 512 * 4, 1023); - test_by_decoding(destination, frame_info, expected.data(), expected.size() * 2, interleave_mode::line); + const vector expected(size_t{512} * 512 * 4, 8191); + test_by_decoding(destination, frame_info, expected.data(), expected.size() * 2, interleave_mode::sample); } TEST_METHOD(rewind) // NOLINT @@ -1681,8 +1686,6 @@ TEST_CLASS(jpegls_encoder_test) vector destination(encoder.estimated_destination_size()); encoder.destination(destination).encoding_options(encoding_options::include_pc_parameters_jai); - // Note: encoding_options::include_pc_parameters_jai is enabled by default (until the next major version) - const size_t bytes_written{encoder.encode(source)}; destination.resize(bytes_written); @@ -1718,7 +1721,7 @@ TEST_CLASS(jpegls_encoder_test) Assert::AreEqual(expected.reset, reset); } - TEST_METHOD(encode_image_with_disabled_include_pc_parameters_jai) // NOLINT + TEST_METHOD(encode_image_with_include_pc_parameters_jai_not_set) // NOLINT { constexpr frame_info frame_info{1, 1, 16, 1}; const vector source(static_cast(frame_info.width) * frame_info.height); @@ -1892,12 +1895,12 @@ TEST_CLASS(jpegls_encoder_test) Assert::IsTrue(interleave_mode == decoder.interleave_mode()); Assert::IsTrue(color_transformation == decoder.color_transformation()); - vector destination(decoder.destination_size()); + vector destination(decoder.get_destination_size()); decoder.decode(destination); Assert::AreEqual(destination.size(), expected_destination_size); - if (decoder.near_lossless() == 0) + if (decoder.get_near_lossless() == 0) { const auto* expected_destination_byte{static_cast(expected_destination)}; diff --git a/unittest/util.cpp b/unittest/util.cpp index 9c6b1311..c5e4bb94 100644 --- a/unittest/util.cpp +++ b/unittest/util.cpp @@ -182,7 +182,7 @@ bool verify_encoded_bytes(const vector& uncompressed_source, const vector< jpegls_encoder encoder; encoder.frame_info(decoder.frame_info()) .interleave_mode(decoder.interleave_mode()) - .near_lossless(decoder.near_lossless()) + .near_lossless(decoder.get_near_lossless()) .preset_coding_parameters(decoder.preset_coding_parameters()); vector our_encoded_bytes(encoded_source.size() + 16); @@ -243,7 +243,7 @@ void test_compliance(const vector& encoded_source, const vector& unc jpegls_decoder decoder{encoded_source, true}; const auto destination{decoder.decode>()}; - if (decoder.near_lossless() == 0) + if (decoder.get_near_lossless() == 0) { for (size_t i{}; i != uncompressed_source.size(); ++i) { @@ -256,7 +256,7 @@ void test_compliance(const vector& encoded_source, const vector& unc else { const frame_info frame_info{decoder.frame_info()}; - const auto near_lossless{decoder.near_lossless()}; + const auto near_lossless{decoder.get_near_lossless()}; if (frame_info.bits_per_sample <= 8) {