19 std::clamp(compression_level,
21 kMaxCompressionLevel)) {}
29 return kTransferSyntaxUID;
33 return "Frame Deflate";
41 if (params.width == 0 || params.height == 0) {
46 if (params.samples_per_pixel != 1) {
51 if (params.bits_stored < 1 || params.bits_stored > 16) {
59 return can_encode(params);
69 std::span<const uint8_t> pixel_data,
73 if (pixel_data.empty()) {
85 if (pixel_data.size() < expected_size) {
88 "Pixel data too small: expected " + std::to_string(expected_size)
89 +
" bytes, got " + std::to_string(pixel_data.size()));
93 uLong source_len =
static_cast<uLong
>(expected_size);
94 uLong bound = compressBound(source_len);
95 std::vector<uint8_t> compressed(bound);
97 uLong dest_len = bound;
98 int ret = compress2(compressed.data(), &dest_len,
99 pixel_data.data(), source_len,
105 "zlib compress2 failed with error code: " + std::to_string(ret));
108 compressed.resize(dest_len);
110 return kcenon::pacs::ok<compression_result>(
111 compression_result{std::move(compressed), params});
115 std::span<const uint8_t> compressed_data,
116 const image_params& params)
const {
118 if (compressed_data.empty()) {
124 const size_t expected_size = params.frame_size_bytes();
125 if (expected_size == 0) {
128 "Cannot determine output size from image parameters");
131 std::vector<uint8_t> decompressed(expected_size);
132 uLong dest_len =
static_cast<uLong
>(expected_size);
133 uLong source_len =
static_cast<uLong
>(compressed_data.size());
135 int ret = uncompress(decompressed.data(), &dest_len,
136 compressed_data.data(), source_len);
141 "zlib uncompress failed with error code: " + std::to_string(ret));
144 if (dest_len != expected_size) {
147 "Decompressed size mismatch: expected " + std::to_string(expected_size)
148 +
" bytes, got " + std::to_string(dest_len));
151 return kcenon::pacs::ok<compression_result>(
152 compression_result{std::move(decompressed), params});
158 [[maybe_unused]] std::span<const uint8_t> pixel_data,
163 "Frame Deflate codec not available: zlib library not found at build time");
167 [[maybe_unused]] std::span<const uint8_t> compressed_data,
171 "Frame Deflate codec not available: zlib library not found at build time");
Frame-level Deflate codec implementation (Supplement 244).
int compression_level() const noexcept
Gets the current zlib compression level.
frame_deflate_codec(int compression_level=kDefaultCompressionLevel)
Constructs a Frame Deflate codec instance.
bool can_encode(const image_params ¶ms) const noexcept override
Checks if this codec supports the given image parameters.
bool is_lossy() const noexcept override
Checks if this codec produces lossy compression.
std::string_view name() const noexcept override
Returns a human-readable name for the codec.
codec_result encode(std::span< const uint8_t > pixel_data, const image_params ¶ms, const compression_options &options={}) const override
Compresses pixel data using zlib deflate.
~frame_deflate_codec() override
bool can_decode(const image_params ¶ms) const noexcept override
Checks if this codec can decode data with given parameters.
codec_result decode(std::span< const uint8_t > compressed_data, const image_params ¶ms) const override
Decompresses deflate-compressed pixel data.
constexpr int compression_error
constexpr int decompression_error
Result< T > pacs_error(int code, const std::string &message, const std::string &details="")
Create a PACS error result with module context.
Result<T> type aliases and helpers for PACS system.
Compression quality settings for lossy codecs.
Parameters describing image pixel data.
uint16_t height
Image height in pixels (Rows - 0028,0010)
size_t frame_size_bytes() const noexcept
Calculates the size of uncompressed pixel data in bytes.
uint16_t width
Image width in pixels (Columns - 0028,0011)