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