Coverage Report

Created: 2026-06-30 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jxl/chroma_from_luma.h
Line
Count
Source
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
static constexpr int32_t kCFLFixedPointRatioMax =
45
    (int32_t{256} << kCFLFixedPointPrecision) - 1;
46
47
static constexpr U32Enc kColorFactorDist(Val(kDefaultColorFactor), Val(256),
48
                                         BitsOffset(8, 2), BitsOffset(16, 258));
49
50
struct ColorCorrelation {
51
3.44M
  float YtoXRatio(int32_t x_factor) const {
52
3.44M
    return base_correlation_x_ + x_factor * color_scale_;
53
3.44M
  }
54
55
3.44M
  float YtoBRatio(int32_t b_factor) const {
56
3.44M
    return base_correlation_b_ + b_factor * color_scale_;
57
3.44M
  }
58
59
  Status DecodeDC(BitReader* br);
60
61
  // We consider a CfL map to be JPEG-reconstruction-compatible if base
62
  // correlation is 0, no DC correlation is used, and we use the default color
63
  // factor.
64
0
  bool IsJPEGCompatible() const {
65
0
    return base_correlation_x_ == 0 && base_correlation_b_ == 0 &&
66
0
           ytob_dc_ == 0 && ytox_dc_ == 0 &&
67
0
           color_factor_ == kDefaultColorFactor;
68
0
  }
69
70
0
  static int32_t RatioJPEG(int32_t factor) {
71
0
    return factor * (1 << kCFLFixedPointPrecision) / kDefaultColorFactor;
72
0
  }
73
74
3.96k
  void SetColorFactor(uint32_t factor) {
75
3.96k
    color_factor_ = factor;
76
3.96k
    color_scale_ = 1.0f / color_factor_;
77
3.96k
    RecomputeDCFactors();
78
3.96k
  }
79
80
0
  void SetYToBDC(int32_t ytob_dc) {
81
0
    ytob_dc_ = ytob_dc;
82
0
    RecomputeDCFactors();
83
0
  }
84
0
  void SetYToXDC(int32_t ytox_dc) {
85
0
    ytox_dc_ = ytox_dc;
86
0
    RecomputeDCFactors();
87
0
  }
88
89
2.73k
  int32_t GetYToXDC() const { return ytox_dc_; }
90
2.73k
  int32_t GetYToBDC() const { return ytob_dc_; }
91
2.73k
  float GetColorFactor() const { return color_factor_; }
92
2.73k
  float GetBaseCorrelationX() const { return base_correlation_x_; }
93
2.73k
  float GetBaseCorrelationB() const { return base_correlation_b_; }
94
95
17.3k
  const float* DCFactors() const { return dc_factors_; }
96
97
52.9k
  void RecomputeDCFactors() {
98
52.9k
    dc_factors_[0] = YtoXRatio(ytox_dc_);
99
52.9k
    dc_factors_[2] = YtoBRatio(ytob_dc_);
100
52.9k
  }
101
102
 private:
103
  friend struct ColorCorrelationMap;
104
  float dc_factors_[4] = {};
105
  // range of factor: -1.51 to +1.52
106
  uint32_t color_factor_ = kDefaultColorFactor;
107
  float color_scale_ = 1.0f / color_factor_;
108
  float base_correlation_x_ = 0.0f;
109
  float base_correlation_b_ = jxl::cms::kYToBRatio;
110
  int32_t ytox_dc_ = 0;
111
  int32_t ytob_dc_ = 0;
112
};
113
114
struct ColorCorrelationMap {
115
73.2k
  ColorCorrelationMap() = default;
116
117
  // Copy disallowed.
118
  ColorCorrelationMap(const ColorCorrelationMap&) = delete;
119
  ColorCorrelationMap& operator=(const ColorCorrelationMap&) = delete;
120
121
  // Move default.
122
90.1k
  ColorCorrelationMap(ColorCorrelationMap&&) = default;
123
45.0k
  ColorCorrelationMap& operator=(ColorCorrelationMap&&) = default;
124
125
  // xsize/ysize are in pixels
126
  // set XYB=false to do something close to no-op cmap (needed for now since
127
  // cmap is mandatory)
128
  static StatusOr<ColorCorrelationMap> Create(JxlMemoryManager* memory_manager,
129
                                              size_t xsize, size_t ysize,
130
                                              bool XYB = true);
131
132
1.53M
  const ColorCorrelation& base() const { return base_; }
133
7.48k
  Status DecodeDC(BitReader* br) { return base_.DecodeDC(br); }
134
135
  ImageSB ytox_map;
136
  ImageSB ytob_map;
137
138
 private:
139
  ColorCorrelation base_;
140
};
141
142
}  // namespace jxl
143
144
#endif  // LIB_JXL_CHROMA_FROM_LUMA_H_