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