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