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_