libjxl

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

field_encodings.h (3954B)


      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_FIELD_ENCODINGS_H_
      7 #define LIB_JXL_FIELD_ENCODINGS_H_
      8 
      9 // Constants needed to encode/decode fields; avoids including the full fields.h.
     10 
     11 #include <stddef.h>
     12 #include <stdint.h>
     13 
     14 #include <hwy/base.h>
     15 #include <vector>
     16 
     17 #include "lib/jxl/base/bits.h"
     18 #include "lib/jxl/base/status.h"
     19 
     20 namespace jxl {
     21 
     22 // Macro to define the Fields' derived class Name when compiling with debug
     23 // names.
     24 #if JXL_IS_DEBUG_BUILD
     25 #define JXL_FIELDS_NAME(X) \
     26   const char* Name() const override { return #X; }
     27 #else
     28 #define JXL_FIELDS_NAME(X)
     29 #endif  // JXL_IS_DEBUG_BUILD
     30 
     31 class Visitor;
     32 class Fields {
     33  public:
     34   virtual ~Fields() = default;
     35 #if JXL_IS_DEBUG_BUILD
     36   virtual const char* Name() const = 0;
     37 #endif  // JXL_IS_DEBUG_BUILD
     38   virtual Status VisitFields(Visitor* JXL_RESTRICT visitor) = 0;
     39 };
     40 
     41 // Distribution of U32 values for one particular selector. Represents either a
     42 // power of two-sized range, or a single value. A separate type ensures this is
     43 // only passed to the U32Enc ctor.
     44 struct U32Distr {
     45   // No need to validate - all `d` are legitimate.
     46   constexpr explicit U32Distr(uint32_t d) : d(d) {}
     47 
     48   static constexpr uint32_t kDirect = 0x80000000u;
     49 
     50   constexpr bool IsDirect() const { return (d & kDirect) != 0; }
     51 
     52   // Only call if IsDirect().
     53   constexpr uint32_t Direct() const { return d & (kDirect - 1); }
     54 
     55   // Only call if !IsDirect().
     56   constexpr size_t ExtraBits() const { return (d & 0x1F) + 1; }
     57   uint32_t Offset() const { return (d >> 5) & 0x3FFFFFF; }
     58 
     59   uint32_t d;
     60 };
     61 
     62 // A direct-coded 31-bit value occupying 2 bits in the bitstream.
     63 constexpr U32Distr Val(uint32_t value) {
     64   return U32Distr(value | U32Distr::kDirect);
     65 }
     66 
     67 // Value - `offset` will be signaled in `bits` extra bits.
     68 constexpr U32Distr BitsOffset(uint32_t bits, uint32_t offset) {
     69   return U32Distr(((bits - 1) & 0x1F) + ((offset & 0x3FFFFFF) << 5));
     70 }
     71 
     72 // Value will be signaled in `bits` extra bits.
     73 constexpr U32Distr Bits(uint32_t bits) { return BitsOffset(bits, 0); }
     74 
     75 // See U32Coder documentation in fields.h.
     76 class U32Enc {
     77  public:
     78   constexpr U32Enc(const U32Distr d0, const U32Distr d1, const U32Distr d2,
     79                    const U32Distr d3)
     80       : d_{d0, d1, d2, d3} {}
     81 
     82   // Returns the U32Distr at `selector` = 0..3, least-significant first.
     83   U32Distr GetDistr(const uint32_t selector) const {
     84     JXL_ASSERT(selector < 4);
     85     return d_[selector];
     86   }
     87 
     88  private:
     89   U32Distr d_[4];
     90 };
     91 
     92 // Returns bit with the given `index` (0 = least significant).
     93 template <typename T>
     94 static inline constexpr uint64_t MakeBit(T index) {
     95   return 1ULL << static_cast<uint32_t>(index);
     96 }
     97 
     98 // Returns vector of all possible values of an Enum type. Relies on each Enum
     99 // providing an overload of EnumBits() that returns a bit array of its values,
    100 // which implies values must be in [0, 64).
    101 template <typename Enum>
    102 std::vector<Enum> Values() {
    103   uint64_t bits = EnumBits(Enum());
    104 
    105   std::vector<Enum> values;
    106   values.reserve(hwy::PopCount(bits));
    107 
    108   // For each 1-bit in bits: add its index as value
    109   while (bits != 0) {
    110     const int index = Num0BitsBelowLS1Bit_Nonzero(bits);
    111     values.push_back(static_cast<Enum>(index));
    112     bits &= bits - 1;  // clear least-significant bit
    113   }
    114   return values;
    115 }
    116 
    117 // Returns true if value is one of Values<Enum>().
    118 template <class Enum>
    119 Status EnumValid(const Enum value) {
    120   if (static_cast<uint32_t>(value) >= 64) {
    121     return JXL_FAILURE("Value %u too large for %s\n",
    122                        static_cast<uint32_t>(value), EnumName(Enum()));
    123   }
    124   const uint64_t bit = MakeBit(value);
    125   if ((EnumBits(Enum()) & bit) == 0) {
    126     return JXL_FAILURE("Invalid value %u for %s\n",
    127                        static_cast<uint32_t>(value), EnumName(Enum()));
    128   }
    129   return true;
    130 }
    131 
    132 }  // namespace jxl
    133 
    134 #endif  // LIB_JXL_FIELD_ENCODINGS_H_