Coverage Report

Created: 2025-06-16 07:00

/src/libjxl/lib/jxl/enc_splines.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 <cmath>
7
#include <cstddef>
8
#include <cstdint>
9
#include <vector>
10
11
#include "lib/jxl/base/status.h"
12
#include "lib/jxl/enc_ans.h"
13
#include "lib/jxl/enc_ans_params.h"
14
#include "lib/jxl/enc_bit_writer.h"
15
#include "lib/jxl/image.h"
16
#include "lib/jxl/pack_signed.h"
17
#include "lib/jxl/splines.h"
18
19
namespace jxl {
20
21
struct AuxOut;
22
enum class LayerType : uint8_t;
23
24
class QuantizedSplineEncoder {
25
 public:
26
  // Only call if HasAny().
27
  static void Tokenize(const QuantizedSpline& spline,
28
0
                       std::vector<Token>* const tokens) {
29
0
    tokens->emplace_back(kNumControlPointsContext,
30
0
                         spline.control_points_.size());
31
0
    for (const auto& point : spline.control_points_) {
32
0
      tokens->emplace_back(kControlPointsContext, PackSigned(point.first));
33
0
      tokens->emplace_back(kControlPointsContext, PackSigned(point.second));
34
0
    }
35
0
    const auto encode_dct = [tokens](const int dct[32]) {
36
0
      for (int i = 0; i < 32; ++i) {
37
0
        tokens->emplace_back(kDCTContext, PackSigned(dct[i]));
38
0
      }
39
0
    };
40
0
    for (const auto& dct : spline.color_dct_) {
41
0
      encode_dct(dct);
42
0
    }
43
0
    encode_dct(spline.sigma_dct_);
44
0
  }
45
};
46
47
namespace {
48
49
void EncodeAllStartingPoints(const std::vector<Spline::Point>& points,
50
0
                             std::vector<Token>* tokens) {
51
0
  int64_t last_x = 0;
52
0
  int64_t last_y = 0;
53
0
  for (size_t i = 0; i < points.size(); i++) {
54
0
    const int64_t x = std::lround(points[i].x);
55
0
    const int64_t y = std::lround(points[i].y);
56
0
    if (i == 0) {
57
0
      tokens->emplace_back(kStartingPositionContext, x);
58
0
      tokens->emplace_back(kStartingPositionContext, y);
59
0
    } else {
60
0
      tokens->emplace_back(kStartingPositionContext, PackSigned(x - last_x));
61
0
      tokens->emplace_back(kStartingPositionContext, PackSigned(y - last_y));
62
0
    }
63
0
    last_x = x;
64
0
    last_y = y;
65
0
  }
66
0
}
67
68
}  // namespace
69
70
Status EncodeSplines(const Splines& splines, BitWriter* writer,
71
                     const LayerType layer,
72
0
                     const HistogramParams& histogram_params, AuxOut* aux_out) {
73
0
  JXL_ENSURE(splines.HasAny());
74
75
0
  const std::vector<QuantizedSpline>& quantized_splines =
76
0
      splines.QuantizedSplines();
77
0
  std::vector<std::vector<Token>> tokens(1);
78
0
  tokens[0].emplace_back(kNumSplinesContext, quantized_splines.size() - 1);
79
0
  EncodeAllStartingPoints(splines.StartingPoints(), tokens.data());
80
81
0
  tokens[0].emplace_back(kQuantizationAdjustmentContext,
82
0
                         PackSigned(splines.GetQuantizationAdjustment()));
83
84
0
  for (const QuantizedSpline& spline : quantized_splines) {
85
0
    QuantizedSplineEncoder::Tokenize(spline, tokens.data());
86
0
  }
87
88
0
  EntropyEncodingData codes;
89
0
  JXL_ASSIGN_OR_RETURN(
90
0
      size_t cost,
91
0
      BuildAndEncodeHistograms(writer->memory_manager(), histogram_params,
92
0
                               kNumSplineContexts, tokens, &codes, writer,
93
0
                               layer, aux_out));
94
0
  (void)cost;
95
0
  JXL_RETURN_IF_ERROR(WriteTokens(tokens[0], codes, 0, writer, layer, aux_out));
96
0
  return true;
97
0
}
98
99
186
Splines FindSplines(const Image3F& opsin) {
100
  // TODO(user): implement spline detection.
101
186
  return {};
102
186
}
103
104
}  // namespace jxl