1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include <algorithm>
#include "lib/jxl/ans_params.h"
#include "lib/jxl/base/status.h"
#include "lib/jxl/chroma_from_luma.h"
#include "lib/jxl/dct_scales.h"
#include "lib/jxl/enc_ans.h"
#include "lib/jxl/entropy_coder.h"
#include "lib/jxl/pack_signed.h"
#include "lib/jxl/splines.h"
namespace jxl {
struct AuxOut;
class QuantizedSplineEncoder {
public:
// Only call if HasAny().
static void Tokenize(const QuantizedSpline& spline,
std::vector<Token>* const tokens) {
tokens->emplace_back(kNumControlPointsContext,
spline.control_points_.size());
for (const auto& point : spline.control_points_) {
tokens->emplace_back(kControlPointsContext, PackSigned(point.first));
tokens->emplace_back(kControlPointsContext, PackSigned(point.second));
}
const auto encode_dct = [tokens](const int dct[32]) {
for (int i = 0; i < 32; ++i) {
tokens->emplace_back(kDCTContext, PackSigned(dct[i]));
}
};
for (const auto& dct : spline.color_dct_) {
encode_dct(dct);
}
encode_dct(spline.sigma_dct_);
}
};
namespace {
void EncodeAllStartingPoints(const std::vector<Spline::Point>& points,
std::vector<Token>* tokens) {
int64_t last_x = 0;
int64_t last_y = 0;
for (size_t i = 0; i < points.size(); i++) {
const int64_t x = lroundf(points[i].x);
const int64_t y = lroundf(points[i].y);
if (i == 0) {
tokens->emplace_back(kStartingPositionContext, x);
tokens->emplace_back(kStartingPositionContext, y);
} else {
tokens->emplace_back(kStartingPositionContext, PackSigned(x - last_x));
tokens->emplace_back(kStartingPositionContext, PackSigned(y - last_y));
}
last_x = x;
last_y = y;
}
}
} // namespace
void EncodeSplines(const Splines& splines, BitWriter* writer,
const size_t layer, const HistogramParams& histogram_params,
AuxOut* aux_out) {
JXL_ASSERT(splines.HasAny());
const std::vector<QuantizedSpline>& quantized_splines =
splines.QuantizedSplines();
std::vector<std::vector<Token>> tokens(1);
tokens[0].emplace_back(kNumSplinesContext, quantized_splines.size() - 1);
EncodeAllStartingPoints(splines.StartingPoints(), tokens.data());
tokens[0].emplace_back(kQuantizationAdjustmentContext,
PackSigned(splines.GetQuantizationAdjustment()));
for (const QuantizedSpline& spline : quantized_splines) {
QuantizedSplineEncoder::Tokenize(spline, tokens.data());
}
EntropyEncodingData codes;
std::vector<uint8_t> context_map;
BuildAndEncodeHistograms(histogram_params, kNumSplineContexts, tokens, &codes,
&context_map, writer, layer, aux_out);
WriteTokens(tokens[0], codes, context_map, 0, writer, layer, aux_out);
}
Splines FindSplines(const Image3F& opsin) {
// TODO(user): implement spline detection.
return {};
}
} // namespace jxl
|