/src/libjxl/lib/jxl/enc_progressive_split.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) the JPEG XL Project Authors. All rights reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style |
4 | | // license that can be found in the LICENSE file. |
5 | | |
6 | | #include "lib/jxl/enc_progressive_split.h" |
7 | | |
8 | | #include <string.h> |
9 | | |
10 | | #include <algorithm> |
11 | | #include <memory> |
12 | | |
13 | | #include "lib/jxl/ac_strategy.h" |
14 | | #include "lib/jxl/common.h" // kMaxNumPasses |
15 | | #include "lib/jxl/image.h" |
16 | | |
17 | | namespace jxl { |
18 | | |
19 | | template <typename T> |
20 | | void ProgressiveSplitter::SplitACCoefficients( |
21 | | const T* JXL_RESTRICT block, const AcStrategy& acs, size_t bx, size_t by, |
22 | 0 | T* JXL_RESTRICT output[kMaxNumPasses]) { |
23 | 0 | size_t size = acs.covered_blocks_x() * acs.covered_blocks_y() * kDCTBlockSize; |
24 | 0 | auto shift_right_round0 = [&](T v, int shift) { |
25 | 0 | T one_if_negative = static_cast<uint32_t>(v) >> 31; |
26 | 0 | T add = (one_if_negative << shift) - one_if_negative; |
27 | 0 | return (v + add) >> shift; |
28 | 0 | }; Unexecuted instantiation: jxl::ProgressiveSplitter::SplitACCoefficients<int>(int const*, jxl::AcStrategy const&, unsigned long, unsigned long, int* restrict*)::{lambda(int, int)#1}::operator()(int, int) const Unexecuted instantiation: jxl::ProgressiveSplitter::SplitACCoefficients<short>(short const*, jxl::AcStrategy const&, unsigned long, unsigned long, short* restrict*)::{lambda(short, int)#1}::operator()(short, int) const |
29 | | // Early quit for the simple case of only one pass. |
30 | 0 | if (mode_.num_passes == 1) { |
31 | 0 | memcpy(output[0], block, sizeof(T) * size); |
32 | 0 | return; |
33 | 0 | } |
34 | 0 | size_t ncoeffs_all_done_from_earlier_passes = 1; |
35 | |
|
36 | 0 | int previous_pass_shift = 0; |
37 | 0 | for (size_t num_pass = 0; num_pass < mode_.num_passes; num_pass++) { // pass |
38 | | // Zero out output block. |
39 | 0 | memset(output[num_pass], 0, size * sizeof(T)); |
40 | 0 | const int pass_shift = mode_.passes[num_pass].shift; |
41 | 0 | size_t frame_ncoeffs = mode_.passes[num_pass].num_coefficients; |
42 | 0 | size_t xsize = acs.covered_blocks_x(); |
43 | 0 | size_t ysize = acs.covered_blocks_y(); |
44 | 0 | CoefficientLayout(&ysize, &xsize); |
45 | 0 | for (size_t y = 0; y < ysize * frame_ncoeffs; y++) { // superblk-y |
46 | 0 | for (size_t x = 0; x < xsize * frame_ncoeffs; x++) { // superblk-x |
47 | 0 | size_t pos = y * xsize * kBlockDim + x; |
48 | 0 | if (x < xsize * ncoeffs_all_done_from_earlier_passes && |
49 | 0 | y < ysize * ncoeffs_all_done_from_earlier_passes) { |
50 | | // This coefficient was already included in an earlier pass, |
51 | | // which included a genuinely smaller set of coefficients. |
52 | 0 | continue; |
53 | 0 | } |
54 | 0 | T v = block[pos]; |
55 | | // Previous pass discarded some bits: do not encode them again. |
56 | 0 | if (previous_pass_shift != 0) { |
57 | 0 | T previous_v = shift_right_round0(v, previous_pass_shift) * |
58 | 0 | (1 << previous_pass_shift); |
59 | 0 | v -= previous_v; |
60 | 0 | } |
61 | 0 | output[num_pass][pos] = shift_right_round0(v, pass_shift); |
62 | 0 | } // superblk-x |
63 | 0 | } // superblk-y |
64 | | // We just finished a pass. |
65 | | // Hence, we are now guaranteed to have included all coeffs up to |
66 | | // frame_ncoeffs in every block, unless the current pass is shifted. |
67 | 0 | if (mode_.passes[num_pass].shift == 0) { |
68 | 0 | ncoeffs_all_done_from_earlier_passes = frame_ncoeffs; |
69 | 0 | } |
70 | 0 | previous_pass_shift = mode_.passes[num_pass].shift; |
71 | 0 | } // num_pass |
72 | 0 | } Unexecuted instantiation: void jxl::ProgressiveSplitter::SplitACCoefficients<int>(int const*, jxl::AcStrategy const&, unsigned long, unsigned long, int* restrict*) Unexecuted instantiation: void jxl::ProgressiveSplitter::SplitACCoefficients<short>(short const*, jxl::AcStrategy const&, unsigned long, unsigned long, short* restrict*) |
73 | | |
74 | | template void ProgressiveSplitter::SplitACCoefficients<int32_t>( |
75 | | const int32_t* JXL_RESTRICT, const AcStrategy&, size_t, size_t, |
76 | | int32_t* JXL_RESTRICT[kMaxNumPasses]); |
77 | | |
78 | | template void ProgressiveSplitter::SplitACCoefficients<int16_t>( |
79 | | const int16_t* JXL_RESTRICT, const AcStrategy&, size_t, size_t, |
80 | | int16_t* JXL_RESTRICT[kMaxNumPasses]); |
81 | | |
82 | | } // namespace jxl |