tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

splines.h (4819B)


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