tor-browser

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

dec_patch_dictionary.h (5412B)


      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_DEC_PATCH_DICTIONARY_H_
      7 #define LIB_JXL_DEC_PATCH_DICTIONARY_H_
      8 
      9 // Chooses reference patches, and avoids encoding them once per occurrence.
     10 
     11 #include <jxl/memory_manager.h>
     12 #include <sys/types.h>
     13 
     14 #include <array>
     15 #include <cstddef>
     16 #include <cstdint>
     17 #include <cstring>
     18 #include <memory>
     19 #include <utility>
     20 #include <vector>
     21 
     22 #include "lib/jxl/base/status.h"
     23 #include "lib/jxl/dec_bit_reader.h"
     24 #include "lib/jxl/image_bundle.h"
     25 #include "lib/jxl/image_metadata.h"
     26 
     27 namespace jxl {
     28 
     29 struct ReferceFrame {
     30  std::unique_ptr<ImageBundle> frame;
     31  // ImageBundle doesn't yet have a simple way to state it is in XYB.
     32  bool ib_is_in_xyb = false;
     33 };
     34 
     35 enum class PatchBlendMode : uint8_t {
     36  // The new values are the old ones. Useful to skip some channels.
     37  kNone = 0,
     38  // The new values (in the crop) replace the old ones: sample = new
     39  kReplace = 1,
     40  // The new values (in the crop) get added to the old ones: sample = old + new
     41  kAdd = 2,
     42  // The new values (in the crop) get multiplied by the old ones:
     43  // sample = old * new
     44  // This blend mode is only supported if BlendColorSpace is kEncoded. The
     45  // range of the new value matters for multiplication purposes, and its
     46  // nominal range of 0..1 is computed the same way as this is done for the
     47  // alpha values in kBlend and kAlphaWeightedAdd.
     48  kMul = 3,
     49  // The new values (in the crop) replace the old ones if alpha>0:
     50  // For first alpha channel:
     51  // alpha = old + new * (1 - old)
     52  // For other channels if !alpha_associated:
     53  // sample = ((1 - new_alpha) * old * old_alpha + new_alpha * new) / alpha
     54  // For other channels if alpha_associated:
     55  // sample = (1 - new_alpha) * old + new
     56  // The alpha formula applies to the alpha used for the division in the other
     57  // channels formula, and applies to the alpha channel itself if its
     58  // blend_channel value matches itself.
     59  // If using kBlendAbove, new is the patch and old is the original image; if
     60  // using kBlendBelow, the meaning is inverted.
     61  kBlendAbove = 4,
     62  kBlendBelow = 5,
     63  // The new values (in the crop) are added to the old ones if alpha>0:
     64  // For first alpha channel: sample = sample = old + new * (1 - old)
     65  // For other channels: sample = old + alpha * new
     66  kAlphaWeightedAddAbove = 6,
     67  kAlphaWeightedAddBelow = 7,
     68 };
     69 
     70 constexpr uint8_t kNumPatchBlendModes =
     71    static_cast<uint8_t>(PatchBlendMode::kAlphaWeightedAddBelow) + 1;
     72 
     73 inline bool UsesAlpha(PatchBlendMode mode) {
     74  return mode == PatchBlendMode::kBlendAbove ||
     75         mode == PatchBlendMode::kBlendBelow ||
     76         mode == PatchBlendMode::kAlphaWeightedAddAbove ||
     77         mode == PatchBlendMode::kAlphaWeightedAddBelow;
     78 }
     79 inline bool UsesClamp(PatchBlendMode mode) {
     80  return UsesAlpha(mode) || mode == PatchBlendMode::kMul;
     81 }
     82 
     83 struct PatchBlending {
     84  PatchBlendMode mode;
     85  uint32_t alpha_channel;
     86  bool clamp;
     87 };
     88 
     89 // Position and size of the patch in the reference frame.
     90 struct PatchReferencePosition {
     91  size_t ref, x0, y0, xsize, ysize;
     92 };
     93 
     94 struct PatchPosition {
     95  // Position of top-left corner of the patch in the image.
     96  size_t x, y;
     97  size_t ref_pos_idx;
     98 };
     99 
    100 struct PassesSharedState;
    101 
    102 // Encoder-side helper class to encode the PatchesDictionary.
    103 class PatchDictionaryEncoder;
    104 
    105 class PatchDictionary {
    106 public:
    107  explicit PatchDictionary(JxlMemoryManager* memory_manager)
    108      : memory_manager_(memory_manager) {}
    109 
    110  void SetShared(const std::array<ReferceFrame, 4>* reference_frames) {
    111    reference_frames_ = reference_frames;
    112  }
    113 
    114  bool HasAny() const { return !positions_.empty(); }
    115 
    116  Status Decode(JxlMemoryManager* memory_manager, BitReader* br, size_t xsize,
    117                size_t ysize, size_t num_extra_channels,
    118                bool* uses_extra_channels);
    119 
    120  void Clear() {
    121    positions_.clear();
    122    ComputePatchTree();
    123  }
    124 
    125  // Adds patches to a segment of `xsize` pixels, starting at `inout`, assumed
    126  // to be located at position (x0, y) in the frame.
    127  Status AddOneRow(
    128      float* const* inout, size_t y, size_t x0, size_t xsize,
    129      const std::vector<ExtraChannelInfo>& extra_channel_info) const;
    130 
    131  // Returns dependencies of this patch dictionary on reference frame ids as a
    132  // bit mask: bits 0-3 indicate reference frame 0-3.
    133  int GetReferences() const;
    134 
    135  std::vector<size_t> GetPatchesForRow(size_t y) const;
    136 
    137 private:
    138  friend class PatchDictionaryEncoder;
    139 
    140  JxlMemoryManager* memory_manager_;
    141  const std::array<ReferceFrame, 4>* reference_frames_;
    142  std::vector<PatchPosition> positions_;
    143  std::vector<PatchReferencePosition> ref_positions_;
    144  std::vector<PatchBlending> blendings_;
    145  size_t blendings_stride_;
    146 
    147  // Interval tree on the y coordinates of the patches.
    148  struct PatchTreeNode {
    149    ssize_t left_child;
    150    ssize_t right_child;
    151    size_t y_center;
    152    // Range of patches in sorted_patches_y0_ and sorted_patches_y1_ that
    153    // contain the row y_center.
    154    size_t start;
    155    size_t num;
    156  };
    157  std::vector<PatchTreeNode> patch_tree_;
    158  // Number of patches for each row.
    159  std::vector<size_t> num_patches_;
    160  std::vector<std::pair<size_t, size_t>> sorted_patches_y0_;
    161  std::vector<std::pair<size_t, size_t>> sorted_patches_y1_;
    162 
    163  void ComputePatchTree();
    164 };
    165 
    166 }  // namespace jxl
    167 
    168 #endif  // LIB_JXL_DEC_PATCH_DICTIONARY_H_