1 // Copyright (c) Team CharLS.
2 // SPDX-License-Identifier: BSD-3-Clause
3
4 #pragma once
5
6 #include "coding_parameters.h"
7 #include "color_transform.h"
8 #include "constants.h"
9 #include "context.h"
10 #include "context_run_mode.h"
11 #include "lookup_table.h"
12 #include "process_line.h"
13
14 #include <array>
15 #include <sstream>
16
17 // This file contains the code for handling a "scan". Usually an image is encoded as a single scan.
18 // Note: the functions in this header could be moved into jpegls.cpp as they are only used in that file.
19
20 namespace charls {
21
22 class decoder_strategy;
23 class encoder_strategy;
24
25 extern const std::array<golomb_code_table, max_k_value> decoding_tables;
26 extern const std::vector<int8_t> quantization_lut_lossless_8;
27 extern const std::vector<int8_t> quantization_lut_lossless_10;
28 extern const std::vector<int8_t> quantization_lut_lossless_12;
29 extern const std::vector<int8_t> quantization_lut_lossless_16;
30
31 // Used to determine how large runs should be encoded at a time. Defined by the JPEG-LS standard, A.2.1., Initialization
32 // step 3.
33 constexpr std::array<int, 32> J{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
34 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15};
35
apply_sign(const int32_t i,const int32_t sign)36 constexpr int32_t apply_sign(const int32_t i, const int32_t sign) noexcept
37 {
38 return (sign ^ i) - sign;
39 }
40
41
42 // Two alternatives for GetPredictedValue() (second is slightly faster due to reduced branching)
43
44 #if 0
45
46 inline int32_t get_predicted_value(int32_t Ra, int32_t Rb, int32_t Rc)
47 {
48 if (Ra < Rb)
49 {
50 if (Rc < Ra)
51 return Rb;
52
53 if (Rc > Rb)
54 return Ra;
55 }
56 else
57 {
58 if (Rc < Rb)
59 return Ra;
60
61 if (Rc > Ra)
62 return Rb;
63 }
64
65 return Ra + Rb - Rc;
66 }
67
68 #else
69
get_predicted_value(const int32_t ra,const int32_t rb,const int32_t rc)70 inline int32_t get_predicted_value(const int32_t ra, const int32_t rb, const int32_t rc) noexcept
71 {
72 // sign trick reduces the number of if statements (branches)
73 const int32_t sign{bit_wise_sign(rb - ra)};
74
75 // is Ra between Rc and Rb?
76 if ((sign ^ (rc - ra)) < 0)
77 {
78 return rb;
79 }
80 if ((sign ^ (rb - rc)) < 0)
81 {
82 return ra;
83 }
84
85 // default case, valid if Rc element of [Ra,Rb]
86 return ra + rb - rc;
87 }
88
89 #endif
90
91 /// <summary>
92 /// This is the optimized inverse algorithm of ISO/IEC 14495-1, A.5.2, Code Segment A.11 (second else branch)
93 /// It will map unsigned values back to signed values.
94 /// </summary>
unmap_error_value(const int32_t mapped_error)95 CONSTEXPR int32_t unmap_error_value(const int32_t mapped_error) noexcept
96 {
97 const int32_t sign{static_cast<int32_t>(static_cast<uint32_t>(mapped_error) << (int32_t_bit_count - 1)) >>
98 (int32_t_bit_count - 1)};
99 return sign ^ (mapped_error >> 1);
100 }
101
102 /// <summary>
103 /// This is the algorithm of ISO/IEC 14495-1, A.5.2, Code Segment A.11 (second else branch)
104 /// It will map signed values to unsigned values. It has been optimized to prevent branching.
105 /// </summary>
map_error_value(const int32_t error_value)106 CONSTEXPR int32_t map_error_value(const int32_t error_value) noexcept
107 {
108 ASSERT(error_value <= INT32_MAX / 2);
109
110 const int32_t mapped_error{(error_value >> (int32_t_bit_count - 2)) ^ (2 * error_value)};
111 return mapped_error;
112 }
113
compute_context_id(const int32_t q1,const int32_t q2,const int32_t q3)114 constexpr int32_t compute_context_id(const int32_t q1, const int32_t q2, const int32_t q3) noexcept
115 {
116 return (q1 * 9 + q2) * 9 + q3;
117 }
118
119
120 template<typename Traits, typename Strategy>
121 class jls_codec final : public Strategy
122 {
123 public:
124 using pixel_type = typename Traits::pixel_type;
125 using sample_type = typename Traits::sample_type;
126
jls_codec(Traits traits,const frame_info & frame_info,const coding_parameters & parameters)127 jls_codec(Traits traits, const frame_info& frame_info, const coding_parameters& parameters) noexcept :
128 Strategy{update_component_count(frame_info, parameters), parameters},
129 traits_{std::move(traits)},
130 width_{frame_info.width}
131 {
132 ASSERT((parameters.interleave_mode == interleave_mode::none && this->frame_info().component_count == 1) ||
133 parameters.interleave_mode != interleave_mode::none);
134 }
135
136 // Factory function for ProcessLine objects to copy/transform un encoded pixels to/from our scan line buffers.
create_process_line(byte_span info,const size_t stride)137 std::unique_ptr<process_line> create_process_line(byte_span info, const size_t stride) override
138 {
139 if (!is_interleaved())
140 {
141 if (frame_info().bits_per_sample == sizeof(sample_type) * 8)
142 {
143 return std::make_unique<post_process_single_component>(info.data, stride,
144 sizeof(typename Traits::pixel_type));
145 }
146
147 return std::make_unique<post_process_single_component_masked>(
148 info.data, stride, sizeof(typename Traits::pixel_type), frame_info().bits_per_sample);
149 }
150
151 if (parameters().transformation == color_transformation::none)
152 return std::make_unique<process_transformed<transform_none<typename Traits::sample_type>>>(
153 info, stride, frame_info(), parameters(), transform_none<sample_type>());
154
155 if (frame_info().bits_per_sample == sizeof(sample_type) * 8)
156 {
157 switch (parameters().transformation)
158 {
159 case color_transformation::hp1:
160 return std::make_unique<process_transformed<transform_hp1<sample_type>>>(
161 info, stride, frame_info(), parameters(), transform_hp1<sample_type>());
162 case color_transformation::hp2:
163 return std::make_unique<process_transformed<transform_hp2<sample_type>>>(
164 info, stride, frame_info(), parameters(), transform_hp2<sample_type>());
165 case color_transformation::hp3:
166 return std::make_unique<process_transformed<transform_hp3<sample_type>>>(
167 info, stride, frame_info(), parameters(), transform_hp3<sample_type>());
168 default:
169 impl::throw_jpegls_error(jpegls_errc::color_transform_not_supported);
170 }
171 }
172
173 impl::throw_jpegls_error(jpegls_errc::bit_depth_for_transform_not_supported);
174 }
175
176 private:
set_presets(const jpegls_pc_parameters & presets)177 void set_presets(const jpegls_pc_parameters& presets) override
178 {
179 const jpegls_pc_parameters preset_default{compute_default(traits_.maximum_sample_value, traits_.near_lossless)};
180
181 initialize_parameters(presets.threshold1 != 0 ? presets.threshold1 : preset_default.threshold1,
182 presets.threshold2 != 0 ? presets.threshold2 : preset_default.threshold2,
183 presets.threshold3 != 0 ? presets.threshold3 : preset_default.threshold3,
184 presets.reset_value != 0 ? presets.reset_value : preset_default.reset_value);
185 }
186
is_interleaved()187 bool is_interleaved() noexcept
188 {
189 ASSERT((parameters().interleave_mode == interleave_mode::none && frame_info().component_count == 1) ||
190 parameters().interleave_mode != interleave_mode::none);
191
192 return parameters().interleave_mode != interleave_mode::none;
193 }
194
parameters()195 const coding_parameters& parameters() const noexcept
196 {
197 return Strategy::parameters_;
198 }
199
frame_info()200 const charls::frame_info& frame_info() const noexcept
201 {
202 return Strategy::frame_info_;
203 }
204
quantize_gradient_org(const int32_t di)205 int8_t quantize_gradient_org(const int32_t di) const noexcept
206 {
207 if (di <= -t3_)
208 return -4;
209 if (di <= -t2_)
210 return -3;
211 if (di <= -t1_)
212 return -2;
213 if (di < -traits_.near_lossless)
214 return -1;
215 if (di <= traits_.near_lossless)
216 return 0;
217 if (di < t1_)
218 return 1;
219 if (di < t2_)
220 return 2;
221 if (di < t3_)
222 return 3;
223
224 return 4;
225 }
226
quantize_gradient(const int32_t di)227 FORCE_INLINE int32_t quantize_gradient(const int32_t di) const noexcept
228 {
229 ASSERT(quantize_gradient_org(di) == *(quantization_ + di));
230 return *(quantization_ + di);
231 }
232
233 // C4127 = conditional expression is constant (caused by some template methods that are not fully specialized) [VS2017]
234 // C6326 = Potential comparison of a constant with another constant. (false warning, triggered by template construction
235 // in Checked build) C26814 = The const variable 'RANGE' can be computed at compile-time. [incorrect warning, VS 16.3.0
236 // P3]
237 MSVC_WARNING_SUPPRESS(4127 6326 26814)
238
initialize_quantization_lut()239 void initialize_quantization_lut()
240 {
241 // for lossless mode with default parameters, we have precomputed the look up table for bit counts 8, 10, 12 and 16.
242 if (traits_.near_lossless == 0 && traits_.maximum_sample_value == (1 << traits_.bits_per_pixel) - 1)
243 {
244 const jpegls_pc_parameters presets{compute_default(traits_.maximum_sample_value, traits_.near_lossless)};
245 if (presets.threshold1 == t1_ && presets.threshold2 == t2_ && presets.threshold3 == t3_)
246 {
247 if (traits_.bits_per_pixel == 8)
248 {
249 quantization_ = &quantization_lut_lossless_8[quantization_lut_lossless_8.size() / 2];
250 return;
251 }
252 if (traits_.bits_per_pixel == 10)
253 {
254 quantization_ = &quantization_lut_lossless_10[quantization_lut_lossless_10.size() / 2];
255 return;
256 }
257 if (traits_.bits_per_pixel == 12)
258 {
259 quantization_ = &quantization_lut_lossless_12[quantization_lut_lossless_12.size() / 2];
260 return;
261 }
262 if (traits_.bits_per_pixel == 16)
263 {
264 quantization_ = &quantization_lut_lossless_16[quantization_lut_lossless_16.size() / 2];
265 return;
266 }
267 }
268 }
269
270 // Initialize the quantization lookup table dynamic.
271 const int32_t range{1 << traits_.bits_per_pixel};
272 quantization_lut_.resize(static_cast<size_t>(range) * 2);
273 for (size_t i{}; i < quantization_lut_.size(); ++i)
274 {
275 quantization_lut_[i] = quantize_gradient_org(-range + static_cast<int32_t>(i));
276 }
277
278 quantization_ = &quantization_lut_[range];
279 }
MSVC_WARNING_UNSUPPRESS()280 MSVC_WARNING_UNSUPPRESS()
281
282 int32_t decode_value(const int32_t k, const int32_t limit, const int32_t quantized_bits_per_pixel)
283 {
284 const int32_t high_bits{Strategy::read_high_bits()};
285
286 if (high_bits >= limit - (quantized_bits_per_pixel + 1))
287 return Strategy::read_value(quantized_bits_per_pixel) + 1;
288
289 if (k == 0)
290 return high_bits;
291
292 return (high_bits << k) + Strategy::read_value(k);
293 }
294
encode_mapped_value(const int32_t k,const int32_t mapped_error,const int32_t limit)295 FORCE_INLINE void encode_mapped_value(const int32_t k, const int32_t mapped_error, const int32_t limit)
296 {
297 int32_t high_bits{mapped_error >> k};
298
299 if (high_bits < limit - traits_.quantized_bits_per_pixel - 1)
300 {
301 if (high_bits + 1 > 31)
302 {
303 Strategy::append_to_bit_stream(0, high_bits / 2);
304 high_bits = high_bits - high_bits / 2;
305 }
306 Strategy::append_to_bit_stream(1, high_bits + 1);
307 Strategy::append_to_bit_stream((mapped_error & ((1 << k) - 1)), k);
308 return;
309 }
310
311 if (limit - traits_.quantized_bits_per_pixel > 31)
312 {
313 Strategy::append_to_bit_stream(0, 31);
314 Strategy::append_to_bit_stream(1, limit - traits_.quantized_bits_per_pixel - 31);
315 }
316 else
317 {
318 Strategy::append_to_bit_stream(1, limit - traits_.quantized_bits_per_pixel);
319 }
320 Strategy::append_to_bit_stream((mapped_error - 1) & ((1 << traits_.quantized_bits_per_pixel) - 1),
321 traits_.quantized_bits_per_pixel);
322 }
323
increment_run_index()324 void increment_run_index() noexcept
325 {
326 run_index_ = std::min(31, run_index_ + 1);
327 }
328
decrement_run_index()329 void decrement_run_index() noexcept
330 {
331 run_index_ = std::max(0, run_index_ - 1);
332 }
333
do_regular(const int32_t qs,int32_t,const int32_t predicted,decoder_strategy *)334 FORCE_INLINE sample_type do_regular(const int32_t qs, int32_t, const int32_t predicted, decoder_strategy*)
335 {
336 const int32_t sign = bit_wise_sign(qs);
337 jls_context& context = contexts_[apply_sign(qs, sign)];
338 const int32_t k = context.get_golomb_coding_parameter();
339 const int32_t predicted_value = traits_.correct_prediction(predicted + apply_sign(context.C, sign));
340
341 int32_t error_value;
342 const golomb_code& code = decoding_tables[k].get(Strategy::peek_byte());
343 if (code.length() != 0)
344 {
345 Strategy::skip(code.length());
346 error_value = code.value();
347 ASSERT(std::abs(error_value) < 65535);
348 }
349 else
350 {
351 error_value = unmap_error_value(decode_value(k, traits_.limit, traits_.quantized_bits_per_pixel));
352 if (std::abs(error_value) > 65535)
353 impl::throw_jpegls_error(jpegls_errc::invalid_encoded_data);
354 }
355 if (k == 0)
356 {
357 error_value = error_value ^ context.get_error_correction(traits_.near_lossless);
358 }
359 context.update_variables(error_value, traits_.near_lossless, traits_.reset_threshold);
360 error_value = apply_sign(error_value, sign);
361 return traits_.compute_reconstructed_sample(predicted_value, error_value);
362 }
363
do_regular(const int32_t qs,const int32_t x,const int32_t predicted,encoder_strategy *)364 FORCE_INLINE sample_type do_regular(const int32_t qs, const int32_t x, const int32_t predicted, encoder_strategy*)
365 {
366 const int32_t sign{bit_wise_sign(qs)};
367 jls_context& context{contexts_[apply_sign(qs, sign)]};
368 const int32_t k{context.get_golomb_coding_parameter()};
369 const int32_t predicted_value{traits_.correct_prediction(predicted + apply_sign(context.C, sign))};
370 const int32_t error_value{traits_.compute_error_value(apply_sign(x - predicted_value, sign))};
371
372 encode_mapped_value(k, map_error_value(context.get_error_correction(k | traits_.near_lossless) ^ error_value),
373 traits_.limit);
374 context.update_variables(error_value, traits_.near_lossless, traits_.reset_threshold);
375 ASSERT(traits_.is_near(traits_.compute_reconstructed_sample(predicted_value, apply_sign(error_value, sign)), x));
376 return static_cast<sample_type>(
377 traits_.compute_reconstructed_sample(predicted_value, apply_sign(error_value, sign)));
378 }
379
380 /// <summary>Encodes/Decodes a scan line of samples</summary>
do_line(sample_type *)381 void do_line(sample_type*)
382 {
383 int32_t index{};
384 int32_t rb{previous_line_[index - 1]};
385 int32_t rd{previous_line_[index]};
386
387 while (static_cast<uint32_t>(index) < width_)
388 {
389 const int32_t ra{current_line_[index - 1]};
390 const int32_t rc{rb};
391 rb = rd;
392 rd = previous_line_[index + 1];
393
394 const int32_t qs{
395 compute_context_id(quantize_gradient(rd - rb), quantize_gradient(rb - rc), quantize_gradient(rc - ra))};
396
397 if (qs != 0)
398 {
399 current_line_[index] =
400 do_regular(qs, current_line_[index], get_predicted_value(ra, rb, rc), static_cast<Strategy*>(nullptr));
401 ++index;
402 }
403 else
404 {
405 index += do_run_mode(index, static_cast<Strategy*>(nullptr));
406 rb = previous_line_[index - 1];
407 rd = previous_line_[index];
408 }
409 }
410 }
411
412 /// <summary>Encodes/Decodes a scan line of triplets in ILV_SAMPLE mode</summary>
do_line(triplet<sample_type> *)413 void do_line(triplet<sample_type>*)
414 {
415 int32_t index{};
416 while (static_cast<uint32_t>(index) < width_)
417 {
418 const triplet<sample_type> ra{current_line_[index - 1]};
419 const triplet<sample_type> rc{previous_line_[index - 1]};
420 const triplet<sample_type> rb{previous_line_[index]};
421 const triplet<sample_type> rd{previous_line_[index + 1]};
422
423 const int32_t qs1{compute_context_id(quantize_gradient(rd.v1 - rb.v1), quantize_gradient(rb.v1 - rc.v1),
424 quantize_gradient(rc.v1 - ra.v1))};
425 const int32_t qs2{compute_context_id(quantize_gradient(rd.v2 - rb.v2), quantize_gradient(rb.v2 - rc.v2),
426 quantize_gradient(rc.v2 - ra.v2))};
427 const int32_t qs3{compute_context_id(quantize_gradient(rd.v3 - rb.v3), quantize_gradient(rb.v3 - rc.v3),
428 quantize_gradient(rc.v3 - ra.v3))};
429
430 if (qs1 == 0 && qs2 == 0 && qs3 == 0)
431 {
432 index += do_run_mode(index, static_cast<Strategy*>(nullptr));
433 }
434 else
435 {
436 triplet<sample_type> rx;
437 rx.v1 = do_regular(qs1, current_line_[index].v1, get_predicted_value(ra.v1, rb.v1, rc.v1),
438 static_cast<Strategy*>(nullptr));
439 rx.v2 = do_regular(qs2, current_line_[index].v2, get_predicted_value(ra.v2, rb.v2, rc.v2),
440 static_cast<Strategy*>(nullptr));
441 rx.v3 = do_regular(qs3, current_line_[index].v3, get_predicted_value(ra.v3, rb.v3, rc.v3),
442 static_cast<Strategy*>(nullptr));
443 current_line_[index] = rx;
444 ++index;
445 }
446 }
447 }
448
449 // Setup codec for encoding and calls do_scan
450 #if defined(__clang__)
451 #pragma clang diagnostic push
452 #pragma clang diagnostic ignored "-Winconsistent-missing-override"
453 #endif
454
455 MSVC_WARNING_SUPPRESS(26433) // C.128: Virtual functions should specify exactly one of virtual, override, or final
456
457 // Note: depending on the base class encode_scan OR decode_scan will be virtual and abstract,
458 // cannot use override in all cases.
459 // clang-format off
460 // NOLINTNEXTLINE(cppcoreguidelines-explicit-virtual-functions, hicpp-use-override, modernize-use-override,clang-diagnostic-suggest-override)
encode_scan(std::unique_ptr<process_line> process_line,byte_span destination)461 size_t encode_scan(std::unique_ptr<process_line> process_line, byte_span destination)
462 {
463 Strategy::process_line_ = std::move(process_line);
464
465 Strategy::initialize(destination);
466 do_scan();
467
468 return Strategy::get_length();
469 }
470
471 // NOLINTNEXTLINE(cppcoreguidelines-explicit-virtual-functions, hicpp-use-override, modernize-use-override, clang-diagnostic-suggest-override)
decode_scan(std::unique_ptr<process_line> process_line,const JlsRect & rect,byte_span & compressed_data)472 void decode_scan(std::unique_ptr<process_line> process_line, const JlsRect& rect, byte_span& compressed_data)
473 {
474 Strategy::process_line_ = std::move(process_line);
475
476 const uint8_t* compressed_bytes{compressed_data.data};
477 rect_ = rect;
478
479 Strategy::initialize(compressed_data);
480 do_scan();
481 skip_bytes(compressed_data, static_cast<size_t>(Strategy::get_cur_byte_pos() - compressed_bytes));
482 }
483
484 // clang-format on
MSVC_WARNING_UNSUPPRESS()485 MSVC_WARNING_UNSUPPRESS()
486
487 #if defined(__clang__)
488 #pragma clang diagnostic pop
489 #endif
490
491 void initialize_parameters(const int32_t t1, const int32_t t2, const int32_t t3, const int32_t reset_threshold)
492 {
493 t1_ = t1;
494 t2_ = t2;
495 t3_ = t3;
496
497 initialize_quantization_lut();
498
499 const jls_context context_initial_value(std::max(2, (traits_.range + 32) / 64));
500 for (auto& context : contexts_)
501 {
502 context = context_initial_value;
503 }
504
505 context_runmode_[0] = context_run_mode(0, std::max(2, (traits_.range + 32) / 64), reset_threshold);
506 context_runmode_[1] = context_run_mode(1, std::max(2, (traits_.range + 32) / 64), reset_threshold);
507 run_index_ = 0;
508 }
509
update_component_count(charls::frame_info frame,const coding_parameters & parameters)510 static charls::frame_info update_component_count(charls::frame_info frame, const coding_parameters& parameters) noexcept
511 {
512 if (parameters.interleave_mode == interleave_mode::none)
513 {
514 frame.component_count = 1;
515 }
516
517 return frame;
518 }
519
520 // do_scan: Encodes or decodes a scan.
521 // In ILV_SAMPLE mode, multiple components are handled in do_line
522 // In ILV_LINE mode, a call do do_line is made for every component
523 // In ILV_NONE mode, do_scan is called for each component
do_scan()524 void do_scan()
525 {
526 const uint32_t pixel_stride{width_ + 4U};
527 const size_t component_count{
528 parameters().interleave_mode == interleave_mode::line ? static_cast<size_t>(frame_info().component_count) : 1U};
529
530 std::vector<pixel_type> line_buffer(static_cast<size_t>(2) * component_count * pixel_stride);
531 std::vector<int32_t> run_index(component_count);
532
533 for (uint32_t line{}; line < frame_info().height; ++line)
534 {
535 previous_line_ = &line_buffer[1];
536 current_line_ = &line_buffer[1 + static_cast<size_t>(component_count) * pixel_stride];
537 if ((line & 1) == 1)
538 {
539 std::swap(previous_line_, current_line_);
540 }
541
542 Strategy::on_line_begin(width_, current_line_, pixel_stride);
543
544 for (size_t component{}; component < component_count; ++component)
545 {
546 run_index_ = run_index[component];
547
548 // initialize edge pixels used for prediction
549 previous_line_[width_] = previous_line_[width_ - 1];
550 current_line_[-1] = previous_line_[0];
551 do_line(static_cast<pixel_type*>(nullptr)); // dummy argument for overload resolution
552
553 run_index[component] = run_index_;
554 previous_line_ += pixel_stride;
555 current_line_ += pixel_stride;
556 }
557
558 if (static_cast<uint32_t>(rect_.Y) <= line && line < static_cast<uint32_t>(rect_.Y + rect_.Height))
559 {
560 Strategy::on_line_end(rect_.Width,
561 current_line_ + rect_.X - (static_cast<size_t>(component_count) * pixel_stride),
562 pixel_stride);
563 }
564 }
565
566 Strategy::end_scan();
567 }
568
569 /// <summary>Encodes/Decodes a scan line of quads in ILV_SAMPLE mode</summary>
do_line(quad<sample_type> *)570 void do_line(quad<sample_type>*)
571 {
572 int32_t index{};
573 while (static_cast<uint32_t>(index) < width_)
574 {
575 const quad<sample_type> ra{current_line_[index - 1]};
576 const quad<sample_type> rc{previous_line_[index - 1]};
577 const quad<sample_type> rb{previous_line_[index]};
578 const quad<sample_type> rd{previous_line_[index + 1]};
579
580 const int32_t qs1{compute_context_id(quantize_gradient(rd.v1 - rb.v1), quantize_gradient(rb.v1 - rc.v1),
581 quantize_gradient(rc.v1 - ra.v1))};
582 const int32_t qs2{compute_context_id(quantize_gradient(rd.v2 - rb.v2), quantize_gradient(rb.v2 - rc.v2),
583 quantize_gradient(rc.v2 - ra.v2))};
584 const int32_t qs3{compute_context_id(quantize_gradient(rd.v3 - rb.v3), quantize_gradient(rb.v3 - rc.v3),
585 quantize_gradient(rc.v3 - ra.v3))};
586 const int32_t qs4{compute_context_id(quantize_gradient(rd.v4 - rb.v4), quantize_gradient(rb.v4 - rc.v4),
587 quantize_gradient(rc.v4 - ra.v4))};
588
589 if (qs1 == 0 && qs2 == 0 && qs3 == 0 && qs4 == 0)
590 {
591 index += do_run_mode(index, static_cast<Strategy*>(nullptr));
592 }
593 else
594 {
595 quad<sample_type> rx;
596 rx.v1 = do_regular(qs1, current_line_[index].v1, get_predicted_value(ra.v1, rb.v1, rc.v1),
597 static_cast<Strategy*>(nullptr));
598 rx.v2 = do_regular(qs2, current_line_[index].v2, get_predicted_value(ra.v2, rb.v2, rc.v2),
599 static_cast<Strategy*>(nullptr));
600 rx.v3 = do_regular(qs3, current_line_[index].v3, get_predicted_value(ra.v3, rb.v3, rc.v3),
601 static_cast<Strategy*>(nullptr));
602 rx.v4 = do_regular(qs4, current_line_[index].v4, get_predicted_value(ra.v4, rb.v4, rc.v4),
603 static_cast<Strategy*>(nullptr));
604 current_line_[index] = rx;
605 ++index;
606 }
607 }
608 }
609
decode_run_interruption_error(context_run_mode & context)610 int32_t decode_run_interruption_error(context_run_mode& context)
611 {
612 const int32_t k{context.get_golomb_code()};
613 const int32_t e_mapped_error_value{
614 decode_value(k, traits_.limit - J[run_index_] - 1, traits_.quantized_bits_per_pixel)};
615 const int32_t error_value{context.compute_error_value(e_mapped_error_value + context.run_interruption_type, k)};
616 context.update_variables(error_value, e_mapped_error_value);
617 return error_value;
618 }
619
decode_run_interruption_pixel(triplet<sample_type> ra,triplet<sample_type> rb)620 triplet<sample_type> decode_run_interruption_pixel(triplet<sample_type> ra, triplet<sample_type> rb)
621 {
622 const int32_t error_value1{decode_run_interruption_error(context_runmode_[0])};
623 const int32_t error_value2{decode_run_interruption_error(context_runmode_[0])};
624 const int32_t error_value3{decode_run_interruption_error(context_runmode_[0])};
625
626 return triplet<sample_type>(traits_.compute_reconstructed_sample(rb.v1, error_value1 * sign(rb.v1 - ra.v1)),
627 traits_.compute_reconstructed_sample(rb.v2, error_value2 * sign(rb.v2 - ra.v2)),
628 traits_.compute_reconstructed_sample(rb.v3, error_value3 * sign(rb.v3 - ra.v3)));
629 }
630
decode_run_interruption_pixel(quad<sample_type> ra,quad<sample_type> rb)631 quad<sample_type> decode_run_interruption_pixel(quad<sample_type> ra, quad<sample_type> rb)
632 {
633 const int32_t error_value1{decode_run_interruption_error(context_runmode_[0])};
634 const int32_t error_value2{decode_run_interruption_error(context_runmode_[0])};
635 const int32_t error_value3{decode_run_interruption_error(context_runmode_[0])};
636 const int32_t error_value4{decode_run_interruption_error(context_runmode_[0])};
637
638 return quad<sample_type>(
639 triplet<sample_type>(traits_.compute_reconstructed_sample(rb.v1, error_value1 * sign(rb.v1 - ra.v1)),
640 traits_.compute_reconstructed_sample(rb.v2, error_value2 * sign(rb.v2 - ra.v2)),
641 traits_.compute_reconstructed_sample(rb.v3, error_value3 * sign(rb.v3 - ra.v3))),
642 traits_.compute_reconstructed_sample(rb.v4, error_value4 * sign(rb.v4 - ra.v4)));
643 }
644
decode_run_interruption_pixel(int32_t ra,int32_t rb)645 sample_type decode_run_interruption_pixel(int32_t ra, int32_t rb)
646 {
647 if (std::abs(ra - rb) <= traits_.near_lossless)
648 {
649 const int32_t error_value{decode_run_interruption_error(context_runmode_[1])};
650 return static_cast<sample_type>(traits_.compute_reconstructed_sample(ra, error_value));
651 }
652
653 const int32_t error_value{decode_run_interruption_error(context_runmode_[0])};
654 return static_cast<sample_type>(traits_.compute_reconstructed_sample(rb, error_value * sign(rb - ra)));
655 }
656
decode_run_pixels(pixel_type ra,pixel_type * start_pos,const int32_t pixel_count)657 int32_t decode_run_pixels(pixel_type ra, pixel_type* start_pos, const int32_t pixel_count)
658 {
659 int32_t index{};
660 while (Strategy::read_bit())
661 {
662 const int count{std::min(1 << J[run_index_], pixel_count - index)};
663 index += count;
664 ASSERT(index <= pixel_count);
665
666 if (count == (1 << J[run_index_]))
667 {
668 increment_run_index();
669 }
670
671 if (index == pixel_count)
672 break;
673 }
674
675 if (index != pixel_count)
676 {
677 // incomplete run.
678 index += (J[run_index_] > 0) ? Strategy::read_value(J[run_index_]) : 0;
679 }
680
681 if (index > pixel_count)
682 impl::throw_jpegls_error(jpegls_errc::invalid_encoded_data);
683
684 for (int32_t i{}; i < index; ++i)
685 {
686 start_pos[i] = ra;
687 }
688
689 return index;
690 }
691
do_run_mode(const int32_t start_index,decoder_strategy *)692 int32_t do_run_mode(const int32_t start_index, decoder_strategy*)
693 {
694 const pixel_type ra{current_line_[start_index - 1]};
695
696 const int32_t run_length{decode_run_pixels(ra, current_line_ + start_index, width_ - start_index)};
697 const uint32_t end_index{static_cast<uint32_t>(start_index + run_length)};
698
699 if (end_index == width_)
700 return end_index - start_index;
701
702 // run interruption
703 const pixel_type rb{previous_line_[end_index]};
704 current_line_[end_index] = decode_run_interruption_pixel(ra, rb);
705 decrement_run_index();
706 return end_index - start_index + 1;
707 }
708
encode_run_interruption_error(context_run_mode & context,const int32_t error_value)709 void encode_run_interruption_error(context_run_mode& context, const int32_t error_value)
710 {
711 const int32_t k{context.get_golomb_code()};
712 const bool map{context.compute_map(error_value, k)};
713 const int32_t e_mapped_error_value{2 * std::abs(error_value) - context.run_interruption_type -
714 static_cast<int32_t>(map)};
715
716 ASSERT(error_value == context.compute_error_value(e_mapped_error_value + context.run_interruption_type, k));
717 encode_mapped_value(k, e_mapped_error_value, traits_.limit - J[run_index_] - 1);
718 context.update_variables(error_value, e_mapped_error_value);
719 }
720
encode_run_interruption_pixel(const int32_t x,const int32_t ra,const int32_t rb)721 sample_type encode_run_interruption_pixel(const int32_t x, const int32_t ra, const int32_t rb)
722 {
723 if (std::abs(ra - rb) <= traits_.near_lossless)
724 {
725 const int32_t error_value{traits_.compute_error_value(x - ra)};
726 encode_run_interruption_error(context_runmode_[1], error_value);
727 return static_cast<sample_type>(traits_.compute_reconstructed_sample(ra, error_value));
728 }
729
730 const int32_t error_value{traits_.compute_error_value((x - rb) * sign(rb - ra))};
731 encode_run_interruption_error(context_runmode_[0], error_value);
732 return static_cast<sample_type>(traits_.compute_reconstructed_sample(rb, error_value * sign(rb - ra)));
733 }
734
encode_run_interruption_pixel(const triplet<sample_type> x,const triplet<sample_type> ra,const triplet<sample_type> rb)735 triplet<sample_type> encode_run_interruption_pixel(const triplet<sample_type> x, const triplet<sample_type> ra,
736 const triplet<sample_type> rb)
737 {
738 const int32_t error_value1{traits_.compute_error_value(sign(rb.v1 - ra.v1) * (x.v1 - rb.v1))};
739 encode_run_interruption_error(context_runmode_[0], error_value1);
740
741 const int32_t error_value2{traits_.compute_error_value(sign(rb.v2 - ra.v2) * (x.v2 - rb.v2))};
742 encode_run_interruption_error(context_runmode_[0], error_value2);
743
744 const int32_t error_value3{traits_.compute_error_value(sign(rb.v3 - ra.v3) * (x.v3 - rb.v3))};
745 encode_run_interruption_error(context_runmode_[0], error_value3);
746
747 return triplet<sample_type>(traits_.compute_reconstructed_sample(rb.v1, error_value1 * sign(rb.v1 - ra.v1)),
748 traits_.compute_reconstructed_sample(rb.v2, error_value2 * sign(rb.v2 - ra.v2)),
749 traits_.compute_reconstructed_sample(rb.v3, error_value3 * sign(rb.v3 - ra.v3)));
750 }
751
encode_run_interruption_pixel(const quad<sample_type> x,const quad<sample_type> ra,const quad<sample_type> rb)752 quad<sample_type> encode_run_interruption_pixel(const quad<sample_type> x, const quad<sample_type> ra,
753 const quad<sample_type> rb)
754 {
755 const int32_t error_value1{traits_.compute_error_value(sign(rb.v1 - ra.v1) * (x.v1 - rb.v1))};
756 encode_run_interruption_error(context_runmode_[0], error_value1);
757
758 const int32_t error_value2{traits_.compute_error_value(sign(rb.v2 - ra.v2) * (x.v2 - rb.v2))};
759 encode_run_interruption_error(context_runmode_[0], error_value2);
760
761 const int32_t error_value3{traits_.compute_error_value(sign(rb.v3 - ra.v3) * (x.v3 - rb.v3))};
762 encode_run_interruption_error(context_runmode_[0], error_value3);
763
764 const int32_t error_value4{traits_.compute_error_value(sign(rb.v4 - ra.v4) * (x.v4 - rb.v4))};
765 encode_run_interruption_error(context_runmode_[0], error_value4);
766
767 return quad<sample_type>(
768 triplet<sample_type>(traits_.compute_reconstructed_sample(rb.v1, error_value1 * sign(rb.v1 - ra.v1)),
769 traits_.compute_reconstructed_sample(rb.v2, error_value2 * sign(rb.v2 - ra.v2)),
770 traits_.compute_reconstructed_sample(rb.v3, error_value3 * sign(rb.v3 - ra.v3))),
771 traits_.compute_reconstructed_sample(rb.v4, error_value4 * sign(rb.v4 - ra.v4)));
772 }
773
encode_run_pixels(int32_t run_length,const bool end_of_line)774 void encode_run_pixels(int32_t run_length, const bool end_of_line)
775 {
776 while (run_length >= 1 << J[run_index_])
777 {
778 Strategy::append_ones_to_bit_stream(1);
779 run_length = run_length - (1 << J[run_index_]);
780 increment_run_index();
781 }
782
783 if (end_of_line)
784 {
785 if (run_length != 0)
786 {
787 Strategy::append_ones_to_bit_stream(1);
788 }
789 }
790 else
791 {
792 Strategy::append_to_bit_stream(run_length, J[run_index_] + 1); // leading 0 + actual remaining length
793 }
794 }
795
do_run_mode(const int32_t index,encoder_strategy *)796 int32_t do_run_mode(const int32_t index, encoder_strategy*)
797 {
798 const int32_t count_type_remain = width_ - index;
799 pixel_type* type_cur_x{current_line_ + index};
800 const pixel_type* type_prev_x{previous_line_ + index};
801
802 const pixel_type ra{type_cur_x[-1]};
803
804 int32_t run_length{};
805 while (traits_.is_near(type_cur_x[run_length], ra))
806 {
807 type_cur_x[run_length] = ra;
808 ++run_length;
809
810 if (run_length == count_type_remain)
811 break;
812 }
813
814 encode_run_pixels(run_length, run_length == count_type_remain);
815
816 if (run_length == count_type_remain)
817 return run_length;
818
819 type_cur_x[run_length] = encode_run_interruption_pixel(type_cur_x[run_length], ra, type_prev_x[run_length]);
820 decrement_run_index();
821 return run_length + 1;
822 }
823
824 // codec parameters
825 Traits traits_;
826 JlsRect rect_{};
827 uint32_t width_;
828 int32_t t1_{};
829 int32_t t2_{};
830 int32_t t3_{};
831
832 // compression context
833 std::array<jls_context, 365> contexts_;
834 std::array<context_run_mode, 2> context_runmode_;
835 int32_t run_index_{};
836 pixel_type* previous_line_{};
837 pixel_type* current_line_{};
838
839 // quantization lookup table
840 const int8_t* quantization_{};
841 std::vector<int8_t> quantization_lut_;
842 };
843
844
845 // Functions to build tables used to decode short Golomb codes.
846
create_encoded_value(const int32_t k,const int32_t mapped_error)847 inline std::pair<int32_t, int32_t> create_encoded_value(const int32_t k, const int32_t mapped_error) noexcept
848 {
849 const int32_t high_bits{mapped_error >> k};
850 return std::make_pair(high_bits + k + 1, (1 << k) | (mapped_error & ((1 << k) - 1)));
851 }
852
initialize_table(const int32_t k)853 inline golomb_code_table initialize_table(const int32_t k) noexcept
854 {
855 golomb_code_table table;
856 for (int16_t error_value{};; ++error_value)
857 {
858 // Q is not used when k != 0
859 const int32_t mapped_error_value{map_error_value(error_value)};
860 const std::pair<int32_t, int32_t> pair_code{create_encoded_value(k, mapped_error_value)};
861 if (static_cast<size_t>(pair_code.first) > golomb_code_table::byte_bit_count)
862 break;
863
864 const golomb_code code(error_value, static_cast<int16_t>(pair_code.first));
865 table.add_entry(static_cast<uint8_t>(pair_code.second), code);
866 }
867
868 for (int16_t error_value{-1};; --error_value)
869 {
870 // Q is not used when k != 0
871 const int32_t mapped_error_value{map_error_value(error_value)};
872 const std::pair<int32_t, int32_t> pair_code{create_encoded_value(k, mapped_error_value)};
873 if (static_cast<size_t>(pair_code.first) > golomb_code_table::byte_bit_count)
874 break;
875
876 const auto code{golomb_code(error_value, static_cast<int16_t>(pair_code.first))};
877 table.add_entry(static_cast<uint8_t>(pair_code.second), code);
878 }
879
880 return table;
881 }
882
883 } // namespace charls
884