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