Coverage Report

Created: 2022-08-24 06:04

/src/libjxl/lib/jxl/splines.h
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
#ifndef LIB_JXL_SPLINES_H_
7
#define LIB_JXL_SPLINES_H_
8
9
#include <stddef.h>
10
#include <stdint.h>
11
12
#include <utility>
13
#include <vector>
14
15
#include "lib/jxl/ans_params.h"
16
#include "lib/jxl/aux_out.h"
17
#include "lib/jxl/aux_out_fwd.h"
18
#include "lib/jxl/base/status.h"
19
#include "lib/jxl/chroma_from_luma.h"
20
#include "lib/jxl/dec_ans.h"
21
#include "lib/jxl/dec_bit_reader.h"
22
#include "lib/jxl/entropy_coder.h"
23
#include "lib/jxl/image.h"
24
25
namespace jxl {
26
27
static constexpr float kDesiredRenderingDistance = 1.f;
28
29
enum SplineEntropyContexts : size_t {
30
  kQuantizationAdjustmentContext = 0,
31
  kStartingPositionContext,
32
  kNumSplinesContext,
33
  kNumControlPointsContext,
34
  kControlPointsContext,
35
  kDCTContext,
36
  kNumSplineContexts
37
};
38
39
struct Spline {
40
  struct Point {
41
0
    Point() : x(0.0f), y(0.0f) {}
42
0
    Point(float x, float y) : x(x), y(y) {}
43
    float x, y;
44
0
    bool operator==(const Point& other) const {
45
0
      return std::fabs(x - other.x) < 1e-3f && std::fabs(y - other.y) < 1e-3f;
46
0
    }
47
  };
48
  std::vector<Point> control_points;
49
  // X, Y, B.
50
  float color_dct[3][32];
51
  // Splines are draws by normalized Gaussian splatting. This controls the
52
  // Gaussian's parameter along the spline.
53
  float sigma_dct[32];
54
};
55
56
class QuantizedSplineEncoder;
57
58
class QuantizedSpline {
59
 public:
60
0
  QuantizedSpline() = default;
61
  explicit QuantizedSpline(const Spline& original,
62
                           int32_t quantization_adjustment, float y_to_x,
63
                           float y_to_b);
64
65
  Status Dequantize(const Spline::Point& starting_point,
66
                    int32_t quantization_adjustment, float y_to_x, float y_to_b,
67
                    Spline& result) const;
68
69
  Status Decode(const std::vector<uint8_t>& context_map,
70
                ANSSymbolReader* decoder, BitReader* br,
71
                size_t max_control_points, size_t* total_num_control_points);
72
73
 private:
74
  friend class QuantizedSplineEncoder;
75
76
  std::vector<std::pair<int64_t, int64_t>>
77
      control_points_;  // Double delta-encoded.
78
  int color_dct_[3][32] = {};
79
  int sigma_dct_[32] = {};
80
};
81
82
// A single "drawable unit" of a spline, i.e. a line of the region in which we
83
// render each Gaussian. The structure doesn't actually depend on the exact
84
// row, which allows reuse for different y values (which are tracked
85
// separately).
86
struct SplineSegment {
87
  float center_x, center_y;
88
  float maximum_distance;
89
  float inv_sigma;
90
  float sigma_over_4_times_intensity;
91
  float color[3];
92
};
93
94
class Splines {
95
 public:
96
184
  Splines() = default;
97
  explicit Splines(const int32_t quantization_adjustment,
98
                   std::vector<QuantizedSpline> splines,
99
                   std::vector<Spline::Point> starting_points)
100
      : quantization_adjustment_(quantization_adjustment),
101
        splines_(std::move(splines)),
102
0
        starting_points_(std::move(starting_points)) {}
103
104
184
  bool HasAny() const { return !splines_.empty(); }
105
106
  void Clear();
107
108
  Status Decode(BitReader* br, size_t num_pixels);
109
110
  void AddTo(Image3F* opsin, const Rect& opsin_rect,
111
             const Rect& image_rect) const;
112
  void AddToRow(float* JXL_RESTRICT row_x, float* JXL_RESTRICT row_y,
113
                float* JXL_RESTRICT row_b, const Rect& image_row) const;
114
  void SubtractFrom(Image3F* opsin) const;
115
116
0
  const std::vector<QuantizedSpline>& QuantizedSplines() const {
117
0
    return splines_;
118
0
  }
119
0
  const std::vector<Spline::Point>& StartingPoints() const {
120
0
    return starting_points_;
121
0
  }
122
123
0
  int32_t GetQuantizationAdjustment() const { return quantization_adjustment_; }
124
125
  Status InitializeDrawCache(size_t image_xsize, size_t image_ysize,
126
                             const ColorCorrelationMap& cmap);
127
128
 private:
129
  template <bool>
130
  void ApplyToRow(float* JXL_RESTRICT row_x, float* JXL_RESTRICT row_y,
131
                  float* JXL_RESTRICT row_b, const Rect& image_row) const;
132
  template <bool>
133
  void Apply(Image3F* opsin, const Rect& opsin_rect,
134
             const Rect& image_rect) const;
135
136
  // If positive, quantization weights are multiplied by 1 + this/8, which
137
  // increases precision. If negative, they are divided by 1 - this/8. If 0,
138
  // they are unchanged.
139
  int32_t quantization_adjustment_ = 0;
140
  std::vector<QuantizedSpline> splines_;
141
  std::vector<Spline::Point> starting_points_;
142
  std::vector<SplineSegment> segments_;
143
  std::vector<size_t> segment_indices_;
144
  std::vector<size_t> segment_y_start_;
145
};
146
147
}  // namespace jxl
148
149
#endif  // LIB_JXL_SPLINES_H_