Coverage Report

Created: 2022-08-24 06:33

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