libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

splines.h (4563B)


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