1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#ifndef LIB_JXL_ENC_PARAMS_H_
#define LIB_JXL_ENC_PARAMS_H_
// Parameters and flags that govern JXL compression.
#include <stddef.h>
#include <stdint.h>
#include <string>
#include "lib/jxl/base/override.h"
#include "lib/jxl/butteraugli/butteraugli.h"
#include "lib/jxl/frame_header.h"
#include "lib/jxl/modular/options.h"
#include "lib/jxl/modular/transform/transform.h"
namespace jxl {
enum class SpeedTier {
// Turns on FindBestQuantizationHQ loop. Equivalent to "guetzli" mode.
kTortoise = 1,
// Turns on FindBestQuantization butteraugli loop.
kKitten = 2,
// Turns on dots, patches, and spline detection by default, as well as full
// context clustering. Default.
kSquirrel = 3,
// Turns on error diffusion and full AC strategy heuristics. Equivalent to
// "fast" mode.
kWombat = 4,
// Turns on gaborish by default, non-default cmap, initial quant field.
kHare = 5,
// Turns on simple heuristics for AC strategy, quant field, and clustering;
// also enables coefficient reordering.
kCheetah = 6,
// Turns off most encoder features. Does context clustering.
// Modular: uses fixed tree with Weighted predictor.
kFalcon = 7,
// Currently fastest possible setting for VarDCT.
// Modular: uses fixed tree with Gradient predictor.
kThunder = 8,
// VarDCT: same as kThunder.
// Modular: no tree, Gradient predictor, fast histograms
kLightning = 9
};
inline bool ParseSpeedTier(const std::string& s, SpeedTier* out) {
if (s == "lightning") {
*out = SpeedTier::kLightning;
return true;
} else if (s == "thunder") {
*out = SpeedTier::kThunder;
return true;
} else if (s == "falcon") {
*out = SpeedTier::kFalcon;
return true;
} else if (s == "cheetah") {
*out = SpeedTier::kCheetah;
return true;
} else if (s == "hare") {
*out = SpeedTier::kHare;
return true;
} else if (s == "fast" || s == "wombat") {
*out = SpeedTier::kWombat;
return true;
} else if (s == "squirrel") {
*out = SpeedTier::kSquirrel;
return true;
} else if (s == "kitten") {
*out = SpeedTier::kKitten;
return true;
} else if (s == "guetzli" || s == "tortoise") {
*out = SpeedTier::kTortoise;
return true;
}
size_t st = 10 - static_cast<size_t>(strtoull(s.c_str(), nullptr, 0));
if (st <= static_cast<size_t>(SpeedTier::kLightning) &&
st >= static_cast<size_t>(SpeedTier::kTortoise)) {
*out = SpeedTier(st);
return true;
}
return false;
}
inline const char* SpeedTierName(SpeedTier speed_tier) {
switch (speed_tier) {
case SpeedTier::kLightning:
return "lightning";
case SpeedTier::kThunder:
return "thunder";
case SpeedTier::kFalcon:
return "falcon";
case SpeedTier::kCheetah:
return "cheetah";
case SpeedTier::kHare:
return "hare";
case SpeedTier::kWombat:
return "wombat";
case SpeedTier::kSquirrel:
return "squirrel";
case SpeedTier::kKitten:
return "kitten";
case SpeedTier::kTortoise:
return "tortoise";
}
return "INVALID";
}
// NOLINTNEXTLINE(clang-analyzer-optin.performance.Padding)
struct CompressParams {
float butteraugli_distance = 1.0f;
size_t target_size = 0;
float target_bitrate = 0.0f;
// 0.0 means search for the adaptive quantization map that matches the
// butteraugli distance, positive values mean quantize everywhere with that
// value.
float uniform_quant = 0.0f;
float quant_border_bias = 0.0f;
// Try to achieve a maximum pixel-by-pixel error on each channel.
bool max_error_mode = false;
float max_error[3] = {0.0, 0.0, 0.0};
SpeedTier speed_tier = SpeedTier::kSquirrel;
int brotli_effort = -1;
// 0 = default.
// 1 = slightly worse quality.
// 4 = fastest speed, lowest quality
// TODO(veluca): hook this up to the C API.
size_t decoding_speed_tier = 0;
int max_butteraugli_iters = 4;
int max_butteraugli_iters_guetzli_mode = 100;
ColorTransform color_transform = ColorTransform::kXYB;
YCbCrChromaSubsampling chroma_subsampling;
// If true, the "modular mode options" members below are used.
bool modular_mode = false;
// Change group size in modular mode (0=128, 1=256, 2=512, 3=1024).
size_t modular_group_size_shift = 1;
Override preview = Override::kDefault;
Override noise = Override::kDefault;
Override dots = Override::kDefault;
Override patches = Override::kDefault;
Override gaborish = Override::kDefault;
int epf = -1;
// Progressive mode.
bool progressive_mode = false;
// Quantized-progressive mode.
bool qprogressive_mode = false;
// Put center groups first in the bitstream.
bool centerfirst = false;
// Pixel coordinates of the center. First group will contain that center.
size_t center_x = static_cast<size_t>(-1);
size_t center_y = static_cast<size_t>(-1);
int progressive_dc = -1;
// If on: preserve color of invisible pixels (if off: don't care)
// Default: on for lossless, off for lossy
Override keep_invisible = Override::kDefault;
// Progressive-mode saliency.
//
// How many progressive saliency-encoding steps to perform.
// - 1: Encode only DC and lowest-frequency AC. Does not need a saliency-map.
// - 2: Encode only DC+LF, dropping all HF AC data.
// Does not need a saliency-map.
// - 3: Encode DC+LF+{salient HF}, dropping all non-salient HF data.
// - 4: Encode DC+LF+{salient HF}+{other HF}.
// - 5: Encode DC+LF+{quantized HF}+{low HF bits}.
size_t saliency_num_progressive_steps = 3;
// Every saliency-heatmap cell with saliency >= threshold will be considered
// as 'salient'. The default value of 0.0 will consider every AC-block
// as salient, hence not require a saliency-map, and not actually generate
// a 4th progressive step.
float saliency_threshold = 0.0f;
// Saliency-map (owned by caller).
ImageF* saliency_map = nullptr;
// Input and output file name. Will be used to provide pluggable saliency
// extractor with paths.
const char* file_in = nullptr;
const char* file_out = nullptr;
// Currently unused as of 2020-01.
bool clear_metadata = false;
// Prints extra information during/after encoding.
bool verbose = false;
ButteraugliParams ba_params;
// Force usage of CfL when doing JPEG recompression. This can have unexpected
// effects on the decoded pixels, while still being JPEG-compliant and
// allowing reconstruction of the original JPEG.
bool force_cfl_jpeg_recompression = true;
// Set the noise to what it would approximately be if shooting at the nominal
// exposure for a given ISO setting on a 35mm camera.
float photon_noise_iso = 0;
// modular mode options below
ModularOptions options;
int responsive = -1;
// empty for default squeeze
std::vector<SqueezeParams> squeezes;
int colorspace = -1;
// Use Global channel palette if #colors < this percentage of range
float channel_colors_pre_transform_percent = 95.f;
// Use Local channel palette if #colors < this percentage of range
float channel_colors_percent = 80.f;
int palette_colors = 1 << 10; // up to 10-bit palette is probably worthwhile
bool lossy_palette = false;
// Returns whether these params are lossless as defined by SetLossless();
bool IsLossless() const {
// YCbCr is also considered lossless here since it's intended for
// source material that is already YCbCr (we don't do the fwd transform)
return modular_mode && butteraugli_distance == 0.0f &&
color_transform != jxl::ColorTransform::kXYB;
}
// Sets the parameters required to make the codec lossless.
void SetLossless() {
modular_mode = true;
butteraugli_distance = 0.0f;
color_transform = jxl::ColorTransform::kNone;
}
bool use_new_heuristics = false;
// Down/upsample the image before encoding / after decoding by this factor.
// The resampling value can also be set to <= 0 to automatically choose based
// on distance, however EncodeFrame doesn't support this, so it is
// required to call PostInit() to set a valid positive resampling
// value and altered butteraugli score if this is used.
int resampling = -1;
int ec_resampling = -1;
// Skip the downsampling before encoding if this is true.
bool already_downsampled = false;
// Codestream level to conform to.
// -1: don't care
int level = -1;
std::vector<float> manual_noise;
std::vector<float> manual_xyb_factors;
};
static constexpr float kMinButteraugliForDynamicAR = 0.5f;
static constexpr float kMinButteraugliForDots = 3.0f;
static constexpr float kMinButteraugliToSubtractOriginalPatches = 3.0f;
static constexpr float kMinButteraugliDistanceForProgressiveDc = 4.5f;
// Always off
static constexpr float kMinButteraugliForNoise = 99.0f;
// Minimum butteraugli distance the encoder accepts.
static constexpr float kMinButteraugliDistance = 0.01f;
// Tile size for encoder-side processing. Must be equal to color tile dim in the
// current implementation.
static constexpr size_t kEncTileDim = 64;
static constexpr size_t kEncTileDimInBlocks = kEncTileDim / kBlockDim;
} // namespace jxl
#endif // LIB_JXL_ENC_PARAMS_H_
|