libjxl

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

chroma_from_luma.h (4812B)


      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_CHROMA_FROM_LUMA_H_
      7 #define LIB_JXL_CHROMA_FROM_LUMA_H_
      8 
      9 // Chroma-from-luma, computed using heuristics to determine the best linear
     10 // model for the X and B channels from the Y channel.
     11 
     12 #include <stddef.h>
     13 #include <stdint.h>
     14 
     15 #include <limits>
     16 
     17 #include "lib/jxl/base/status.h"
     18 #include "lib/jxl/cms/opsin_params.h"
     19 #include "lib/jxl/dec_bit_reader.h"
     20 #include "lib/jxl/field_encodings.h"
     21 #include "lib/jxl/fields.h"
     22 #include "lib/jxl/frame_dimensions.h"
     23 #include "lib/jxl/image.h"
     24 
     25 namespace jxl {
     26 
     27 // Tile is the rectangular grid of blocks that share color correlation
     28 // parameters ("factor_x/b" such that residual_b = blue - Y * factor_b).
     29 static constexpr size_t kColorTileDim = 64;
     30 
     31 static_assert(kColorTileDim % kBlockDim == 0,
     32               "Color tile dim should be divisible by block dim");
     33 static constexpr size_t kColorTileDimInBlocks = kColorTileDim / kBlockDim;
     34 
     35 static_assert(kGroupDimInBlocks % kColorTileDimInBlocks == 0,
     36               "Group dim should be divisible by color tile dim");
     37 
     38 static constexpr uint8_t kDefaultColorFactor = 84;
     39 
     40 // JPEG DCT coefficients are at most 1024. CfL constants are at most 127, and
     41 // the ratio of two entries in a JPEG quantization table is at most 255. Thus,
     42 // since the CfL denominator is 84, this leaves 12 bits of mantissa to be used.
     43 // For extra caution, we use 11.
     44 static constexpr uint8_t kCFLFixedPointPrecision = 11;
     45 
     46 static constexpr U32Enc kColorFactorDist(Val(kDefaultColorFactor), Val(256),
     47                                          BitsOffset(8, 2), BitsOffset(16, 258));
     48 
     49 struct ColorCorrelationMap {
     50   ColorCorrelationMap() = default;
     51   // xsize/ysize are in pixels
     52   // set XYB=false to do something close to no-op cmap (needed for now since
     53   // cmap is mandatory)
     54   static StatusOr<ColorCorrelationMap> Create(size_t xsize, size_t ysize,
     55                                               bool XYB = true);
     56 
     57   float YtoXRatio(int32_t x_factor) const {
     58     return base_correlation_x_ + x_factor * color_scale_;
     59   }
     60 
     61   float YtoBRatio(int32_t b_factor) const {
     62     return base_correlation_b_ + b_factor * color_scale_;
     63   }
     64 
     65   Status DecodeDC(BitReader* br) {
     66     if (br->ReadFixedBits<1>() == 1) {
     67       // All default.
     68       return true;
     69     }
     70     SetColorFactor(U32Coder::Read(kColorFactorDist, br));
     71     JXL_RETURN_IF_ERROR(F16Coder::Read(br, &base_correlation_x_));
     72     if (std::abs(base_correlation_x_) > 4.0f) {
     73       return JXL_FAILURE("Base X correlation is out of range");
     74     }
     75     JXL_RETURN_IF_ERROR(F16Coder::Read(br, &base_correlation_b_));
     76     if (std::abs(base_correlation_b_) > 4.0f) {
     77       return JXL_FAILURE("Base B correlation is out of range");
     78     }
     79     ytox_dc_ = static_cast<int>(br->ReadFixedBits<kBitsPerByte>()) +
     80                std::numeric_limits<int8_t>::min();
     81     ytob_dc_ = static_cast<int>(br->ReadFixedBits<kBitsPerByte>()) +
     82                std::numeric_limits<int8_t>::min();
     83     RecomputeDCFactors();
     84     return true;
     85   }
     86 
     87   // We consider a CfL map to be JPEG-reconstruction-compatible if base
     88   // correlation is 0, no DC correlation is used, and we use the default color
     89   // factor.
     90   bool IsJPEGCompatible() const {
     91     return base_correlation_x_ == 0 && base_correlation_b_ == 0 &&
     92            ytob_dc_ == 0 && ytox_dc_ == 0 &&
     93            color_factor_ == kDefaultColorFactor;
     94   }
     95 
     96   static int32_t RatioJPEG(int32_t factor) {
     97     return factor * (1 << kCFLFixedPointPrecision) / kDefaultColorFactor;
     98   }
     99 
    100   void SetColorFactor(uint32_t factor) {
    101     color_factor_ = factor;
    102     color_scale_ = 1.0f / color_factor_;
    103     RecomputeDCFactors();
    104   }
    105 
    106   void SetYToBDC(int32_t ytob_dc) {
    107     ytob_dc_ = ytob_dc;
    108     RecomputeDCFactors();
    109   }
    110   void SetYToXDC(int32_t ytox_dc) {
    111     ytox_dc_ = ytox_dc;
    112     RecomputeDCFactors();
    113   }
    114 
    115   int32_t GetYToXDC() const { return ytox_dc_; }
    116   int32_t GetYToBDC() const { return ytob_dc_; }
    117   float GetColorFactor() const { return color_factor_; }
    118   float GetBaseCorrelationX() const { return base_correlation_x_; }
    119   float GetBaseCorrelationB() const { return base_correlation_b_; }
    120 
    121   const float* DCFactors() const { return dc_factors_; }
    122 
    123   void RecomputeDCFactors() {
    124     dc_factors_[0] = YtoXRatio(ytox_dc_);
    125     dc_factors_[2] = YtoBRatio(ytob_dc_);
    126   }
    127 
    128   ImageSB ytox_map;
    129   ImageSB ytob_map;
    130 
    131  private:
    132   float dc_factors_[4] = {};
    133   // range of factor: -1.51 to +1.52
    134   uint32_t color_factor_ = kDefaultColorFactor;
    135   float color_scale_ = 1.0f / color_factor_;
    136   float base_correlation_x_ = 0.0f;
    137   float base_correlation_b_ = jxl::cms::kYToBRatio;
    138   int32_t ytox_dc_ = 0;
    139   int32_t ytob_dc_ = 0;
    140 };
    141 
    142 }  // namespace jxl
    143 
    144 #endif  // LIB_JXL_CHROMA_FROM_LUMA_H_