Coverage Report

Created: 2025-06-22 08:04

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