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_MODULAR_OPTIONS_H_
7 #define LIB_JXL_MODULAR_OPTIONS_H_
8 
9 #include <stdint.h>
10 
11 #include <array>
12 #include <vector>
13 
14 namespace jxl {
15 
16 using PropertyVal = int32_t;
17 using Properties = std::vector<PropertyVal>;
18 
19 enum class Predictor : uint32_t {
20   Zero = 0,
21   Left = 1,
22   Top = 2,
23   Average0 = 3,
24   Select = 4,
25   Gradient = 5,
26   Weighted = 6,
27   TopRight = 7,
28   TopLeft = 8,
29   LeftLeft = 9,
30   Average1 = 10,
31   Average2 = 11,
32   Average3 = 12,
33   Average4 = 13,
34   // The following predictors are encoder-only.
35   Best = 14,  // Best of Gradient and Weighted
36   Variable =
37       15,  // Find the best decision tree for predictors/predictor per row
38 };
39 
PredictorName(Predictor p)40 inline const char* PredictorName(Predictor p) {
41   switch (p) {
42     case Predictor::Zero:
43       return "Zero";
44     case Predictor::Left:
45       return "Left";
46     case Predictor::Top:
47       return "Top";
48     case Predictor::Average0:
49       return "Avg0";
50     case Predictor::Average1:
51       return "Avg1";
52     case Predictor::Average2:
53       return "Avg2";
54     case Predictor::Average3:
55       return "Avg3";
56     case Predictor::Average4:
57       return "Avg4";
58     case Predictor::Select:
59       return "Sel";
60     case Predictor::Gradient:
61       return "Grd";
62     case Predictor::Weighted:
63       return "Wgh";
64     case Predictor::TopLeft:
65       return "TopL";
66     case Predictor::TopRight:
67       return "TopR";
68     case Predictor::LeftLeft:
69       return "LL";
70     default:
71       return "INVALID";
72   };
73 }
74 
PredictorColor(Predictor p)75 inline std::array<uint8_t, 3> PredictorColor(Predictor p) {
76   switch (p) {
77     case Predictor::Zero:
78       return {{0, 0, 0}};
79     case Predictor::Left:
80       return {{255, 0, 0}};
81     case Predictor::Top:
82       return {{0, 255, 0}};
83     case Predictor::Average0:
84       return {{0, 0, 255}};
85     case Predictor::Average4:
86       return {{192, 128, 128}};
87     case Predictor::Select:
88       return {{255, 255, 0}};
89     case Predictor::Gradient:
90       return {{255, 0, 255}};
91     case Predictor::Weighted:
92       return {{0, 255, 255}};
93       // TODO
94     default:
95       return {{255, 255, 255}};
96   };
97 }
98 
99 constexpr size_t kNumModularPredictors = static_cast<size_t>(Predictor::Best);
100 
101 static constexpr ssize_t kNumStaticProperties = 2;  // channel, group_id.
102 
103 using StaticPropRange =
104     std::array<std::array<uint32_t, 2>, kNumStaticProperties>;
105 
106 struct ModularMultiplierInfo {
107   StaticPropRange range;
108   uint32_t multiplier;
109 };
110 
111 struct ModularOptions {
112   /// Used in both encode and decode:
113 
114   // Stop encoding/decoding when reaching a (non-meta) channel that has a
115   // dimension bigger than max_chan_size.
116   size_t max_chan_size = 0xFFFFFF;
117 
118   // Used during decoding for validation of transforms (sqeeezing) scheme.
119   size_t group_dim = 0x1FFFFFFF;
120 
121   /// Encode options:
122   // Fraction of pixels to look at to learn a MA tree
123   // Number of iterations to do to learn a MA tree
124   // (if zero there is no MA context model)
125   float nb_repeats = .5f;
126 
127   // Maximum number of (previous channel) properties to use in the MA trees
128   int max_properties = 0;  // no previous channels
129 
130   // Alternative heuristic tweaks.
131   // Properties default to channel, group, weighted, gradient residual, W-NW,
132   // NW-N, N-NE, N-NN
133   std::vector<uint32_t> splitting_heuristics_properties = {0,  1,  15, 9,
134                                                            10, 11, 12, 13};
135   float splitting_heuristics_node_threshold = 96;
136   size_t max_property_values = 32;
137 
138   // Predictor to use for each channel.
139   Predictor predictor = static_cast<Predictor>(-1);
140 
141   int wp_mode = 0;
142 
143   float fast_decode_multiplier = 1.01f;
144 
145   // Forces the encoder to produce a tree that is compatible with the WP-only
146   // decode path (or with the no-wp path, or the gradient-only path).
147   enum class TreeMode { kGradientOnly, kWPOnly, kNoWP, kDefault };
148   TreeMode wp_tree_mode = TreeMode::kDefault;
149 
150   // Skip fast paths in the encoder.
151   bool skip_encoder_fast_path = false;
152 
153   // Kind of tree to use.
154   // TODO(veluca): add tree kinds for JPEG recompression with CfL enabled,
155   // general AC metadata, different DC qualities, and others.
156   enum class TreeKind {
157     kLearn,
158     kJpegTranscodeACMeta,
159     kFalconACMeta,
160     kACMeta,
161     kWPFixedDC,
162     kGradientFixedDC,
163   };
164   TreeKind tree_kind = TreeKind::kLearn;
165 
166   // Ignore the image and just pretend all tokens are zeroes
167   bool zero_tokens = false;
168 };
169 
170 }  // namespace jxl
171 
172 #endif  // LIB_JXL_MODULAR_OPTIONS_H_
173