libjxl

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

encoding.h (5219B)


      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 <vector>
     13 
     14 #include "lib/jxl/base/compiler_specific.h"
     15 #include "lib/jxl/base/status.h"
     16 #include "lib/jxl/field_encodings.h"
     17 #include "lib/jxl/image.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;
     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_MULTIPLIERS>
     63 struct TreeLut {
     64   std::array<T, 2 * kPropRangeFast> context_lookup;
     65   std::array<int8_t, 2 * kPropRangeFast> offsets;
     66   std::array<int8_t, HAS_MULTIPLIERS ? (2 * kPropRangeFast) : 0> multipliers;
     67 };
     68 
     69 template <typename T, bool HAS_MULTIPLIERS>
     70 bool TreeToLookupTable(const FlatTree &tree, TreeLut<T, HAS_MULTIPLIERS> &lut) {
     71   struct TreeRange {
     72     // Begin *excluded*, end *included*. This works best with > vs <= decision
     73     // nodes.
     74     int begin, end;
     75     size_t pos;
     76   };
     77   std::vector<TreeRange> ranges;
     78   ranges.push_back(TreeRange{-kPropRangeFast - 1, kPropRangeFast - 1, 0});
     79   while (!ranges.empty()) {
     80     TreeRange cur = ranges.back();
     81     ranges.pop_back();
     82     if (cur.begin < -kPropRangeFast - 1 || cur.begin >= kPropRangeFast - 1 ||
     83         cur.end > kPropRangeFast - 1) {
     84       // Tree is outside the allowed range, exit.
     85       return false;
     86     }
     87     auto &node = tree[cur.pos];
     88     // Leaf.
     89     if (node.property0 == -1) {
     90       if (node.predictor_offset < std::numeric_limits<int8_t>::min() ||
     91           node.predictor_offset > std::numeric_limits<int8_t>::max()) {
     92         return false;
     93       }
     94       if (node.multiplier < std::numeric_limits<int8_t>::min() ||
     95           node.multiplier > std::numeric_limits<int8_t>::max()) {
     96         return false;
     97       }
     98       if (!HAS_MULTIPLIERS && node.multiplier != 1) {
     99         return false;
    100       }
    101       for (int i = cur.begin + 1; i < cur.end + 1; i++) {
    102         lut.context_lookup[i + kPropRangeFast] = node.childID;
    103         if (HAS_MULTIPLIERS) {
    104           lut.multipliers[i + kPropRangeFast] = node.multiplier;
    105         }
    106         lut.offsets[i + kPropRangeFast] = node.predictor_offset;
    107       }
    108       continue;
    109     }
    110     // > side of top node.
    111     if (node.properties[0] >= kNumStaticProperties) {
    112       ranges.push_back(TreeRange({node.splitvals[0], cur.end, node.childID}));
    113       ranges.push_back(
    114           TreeRange({node.splitval0, node.splitvals[0], node.childID + 1}));
    115     } else {
    116       ranges.push_back(TreeRange({node.splitval0, cur.end, node.childID}));
    117     }
    118     // <= side
    119     if (node.properties[1] >= kNumStaticProperties) {
    120       ranges.push_back(
    121           TreeRange({node.splitvals[1], node.splitval0, node.childID + 2}));
    122       ranges.push_back(
    123           TreeRange({cur.begin, node.splitvals[1], node.childID + 3}));
    124     } else {
    125       ranges.push_back(
    126           TreeRange({cur.begin, node.splitval0, node.childID + 2}));
    127     }
    128   }
    129   return true;
    130 }
    131 // TODO(veluca): make cleaner interfaces.
    132 
    133 Status ValidateChannelDimensions(const Image &image,
    134                                  const ModularOptions &options);
    135 
    136 Status ModularGenericDecompress(BitReader *br, Image &image,
    137                                 GroupHeader *header, size_t group_id,
    138                                 ModularOptions *options,
    139                                 bool undo_transforms = true,
    140                                 const Tree *tree = nullptr,
    141                                 const ANSCode *code = nullptr,
    142                                 const std::vector<uint8_t> *ctx_map = nullptr,
    143                                 bool allow_truncated_group = false);
    144 }  // namespace jxl
    145 
    146 #endif  // LIB_JXL_MODULAR_ENCODING_ENCODING_H_