tor-browser

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

encoding.h (5432B)


      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_MODULAR_ENCODING_ENCODING_H_
      7 #define LIB_JXL_MODULAR_ENCODING_ENCODING_H_
      8 
      9 #include <array>
     10 #include <cstddef>
     11 #include <cstdint>
     12 #include <limits>
     13 #include <vector>
     14 
     15 #include "lib/jxl/base/compiler_specific.h"
     16 #include "lib/jxl/base/status.h"
     17 #include "lib/jxl/field_encodings.h"
     18 #include "lib/jxl/modular/encoding/context_predict.h"
     19 #include "lib/jxl/modular/encoding/dec_ma.h"
     20 #include "lib/jxl/modular/modular_image.h"
     21 #include "lib/jxl/modular/options.h"
     22 #include "lib/jxl/modular/transform/transform.h"
     23 
     24 namespace jxl {
     25 
     26 struct ANSCode;
     27 class BitReader;
     28 
     29 // Valid range of properties for using lookup tables instead of trees.
     30 constexpr int32_t kPropRangeFast = 512 << 4;
     31 
     32 struct GroupHeader : public Fields {
     33  GroupHeader();
     34 
     35  JXL_FIELDS_NAME(GroupHeader)
     36 
     37  Status VisitFields(Visitor *JXL_RESTRICT visitor) override {
     38    JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(false, &use_global_tree));
     39    JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&wp_header));
     40    uint32_t num_transforms = static_cast<uint32_t>(transforms.size());
     41    JXL_QUIET_RETURN_IF_ERROR(visitor->U32(Val(0), Val(1), BitsOffset(4, 2),
     42                                           BitsOffset(8, 18), 0,
     43                                           &num_transforms));
     44    if (visitor->IsReading()) transforms.resize(num_transforms);
     45    for (size_t i = 0; i < num_transforms; i++) {
     46      JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&transforms[i]));
     47    }
     48    return true;
     49  }
     50 
     51  bool use_global_tree;
     52  weighted::Header wp_header;
     53 
     54  std::vector<Transform> transforms;
     55 };
     56 
     57 FlatTree FilterTree(const Tree &global_tree,
     58                    std::array<pixel_type, kNumStaticProperties> &static_props,
     59                    size_t *num_props, bool *use_wp, bool *wp_only,
     60                    bool *gradient_only);
     61 
     62 template <typename T, bool HAS_OFFSETS, bool HAS_MULTIPLIERS>
     63 struct TreeLut {
     64  std::array<T, 2 * kPropRangeFast> context_lookup;
     65  std::array<int8_t, HAS_OFFSETS ? (2 * kPropRangeFast) : 0> offsets;
     66  std::array<int8_t, HAS_MULTIPLIERS ? (2 * kPropRangeFast) : 0> multipliers;
     67 };
     68 
     69 template <typename T, bool HAS_OFFSETS, bool HAS_MULTIPLIERS>
     70 bool TreeToLookupTable(const FlatTree &tree,
     71                       TreeLut<T, HAS_OFFSETS, HAS_MULTIPLIERS> &lut) {
     72  struct TreeRange {
     73    // Begin *excluded*, end *included*. This works best with > vs <= decision
     74    // nodes.
     75    int begin, end;
     76    size_t pos;
     77  };
     78  std::vector<TreeRange> ranges;
     79  ranges.push_back(TreeRange{-kPropRangeFast - 1, kPropRangeFast - 1, 0});
     80  while (!ranges.empty()) {
     81    TreeRange cur = ranges.back();
     82    ranges.pop_back();
     83    if (cur.begin < -kPropRangeFast - 1 || cur.begin >= kPropRangeFast - 1 ||
     84        cur.end > kPropRangeFast - 1) {
     85      // Tree is outside the allowed range, exit.
     86      return false;
     87    }
     88    auto &node = tree[cur.pos];
     89    // Leaf.
     90    if (node.property0 == -1) {
     91      if (node.predictor_offset < std::numeric_limits<int8_t>::min() ||
     92          node.predictor_offset > std::numeric_limits<int8_t>::max()) {
     93        return false;
     94      }
     95      if (node.multiplier < std::numeric_limits<int8_t>::min() ||
     96          node.multiplier > std::numeric_limits<int8_t>::max()) {
     97        return false;
     98      }
     99      if (!HAS_MULTIPLIERS && node.multiplier != 1) {
    100        return false;
    101      }
    102      if (!HAS_OFFSETS && node.predictor_offset != 0) {
    103        return false;
    104      }
    105      for (int i = cur.begin + 1; i < cur.end + 1; i++) {
    106        lut.context_lookup[i + kPropRangeFast] = node.childID;
    107        if (HAS_MULTIPLIERS) {
    108          lut.multipliers[i + kPropRangeFast] = node.multiplier;
    109        }
    110        if (HAS_OFFSETS) {
    111          lut.offsets[i + kPropRangeFast] = node.predictor_offset;
    112        }
    113      }
    114      continue;
    115    }
    116    // > side of top node.
    117    if (node.properties[0] >= kNumStaticProperties) {
    118      ranges.push_back(TreeRange({node.splitvals[0], cur.end, node.childID}));
    119      ranges.push_back(
    120          TreeRange({node.splitval0, node.splitvals[0], node.childID + 1}));
    121    } else {
    122      ranges.push_back(TreeRange({node.splitval0, cur.end, node.childID}));
    123    }
    124    // <= side
    125    if (node.properties[1] >= kNumStaticProperties) {
    126      ranges.push_back(
    127          TreeRange({node.splitvals[1], node.splitval0, node.childID + 2}));
    128      ranges.push_back(
    129          TreeRange({cur.begin, node.splitvals[1], node.childID + 3}));
    130    } else {
    131      ranges.push_back(
    132          TreeRange({cur.begin, node.splitval0, node.childID + 2}));
    133    }
    134  }
    135  return true;
    136 }
    137 // TODO(veluca): make cleaner interfaces.
    138 
    139 Status ValidateChannelDimensions(const Image &image,
    140                                 const ModularOptions &options);
    141 
    142 Status ModularGenericDecompress(BitReader *br, Image &image,
    143                                GroupHeader *header, size_t group_id,
    144                                ModularOptions *options,
    145                                bool undo_transforms = true,
    146                                const Tree *tree = nullptr,
    147                                const ANSCode *code = nullptr,
    148                                const std::vector<uint8_t> *ctx_map = nullptr,
    149                                bool allow_truncated_group = false);
    150 }  // namespace jxl
    151 
    152 #endif  // LIB_JXL_MODULAR_ENCODING_ENCODING_H_