Coverage Report

Created: 2025-06-16 07:00

/src/libjxl/lib/jxl/dct_scales.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_DCT_SCALES_H_
7
#define LIB_JXL_DCT_SCALES_H_
8
9
// Scaling factors.
10
11
#include <stddef.h>
12
13
namespace jxl {
14
15
static constexpr float kSqrt2 = 1.41421356237f;
16
static constexpr float kSqrt0_5 = 0.70710678118f;
17
18
// For n != 0, the n-th basis function of a N-DCT, evaluated in pixel k, has a
19
// value of cos((k+1/2) n/(2N) pi). When downsampling by 2x, we average
20
// the values for pixel k and k+1 to get the value for pixel (k/2), thus we get
21
//
22
// [cos((k+1/2) n/N pi) + cos((k+3/2) n/N pi)]/2 =
23
// cos(n/(2N) pi) cos((k+1) n/N pi) =
24
// cos(n/(2N) pi) cos(((k/2)+1/2) n/(N/2) pi)
25
//
26
// which is exactly the same as the value of pixel k/2 of a N/2-sized DCT,
27
// except for the cos(n/(2N) pi) scaling factor (which does *not*
28
// depend on the pixel). Thus, when using the lower-frequency coefficients of a
29
// DCT-N to compute a DCT-(N/2), they should be scaled by this constant. Scaling
30
// factors for a DCT-(N/4) etc can then be obtained by successive
31
// multiplications. The structs below contain the above-mentioned scaling
32
// factors.
33
//
34
// Python code for the tables below:
35
//
36
// for i in range(N // 8):
37
//    v = math.cos(i / (2 * N) * math.pi)
38
//    v *= math.cos(i / (N) * math.pi)
39
//    v *= math.cos(i / (N / 2) * math.pi)
40
//    print(v, end=", ")
41
42
template <size_t FROM, size_t TO>
43
struct DCTResampleScales;
44
45
template <>
46
struct DCTResampleScales<8, 1> {
47
  static constexpr float kScales[] = {
48
      1.000000000000000000,
49
  };
50
};
51
52
template <>
53
struct DCTResampleScales<16, 2> {
54
  static constexpr float kScales[] = {
55
      1.000000000000000000,
56
      0.901764195028874394,
57
  };
58
};
59
60
template <>
61
struct DCTResampleScales<32, 4> {
62
  static constexpr float kScales[] = {
63
      1.000000000000000000,
64
      0.974886821136879522,
65
      0.901764195028874394,
66
      0.787054918159101335,
67
  };
68
};
69
70
template <>
71
struct DCTResampleScales<64, 8> {
72
  static constexpr float kScales[] = {
73
      1.0000000000000000, 0.9936866130906366, 0.9748868211368796,
74
      0.9440180941651672, 0.9017641950288744, 0.8490574973847023,
75
      0.7870549181591013, 0.7171081282466044,
76
  };
77
};
78
79
template <>
80
struct DCTResampleScales<128, 16> {
81
  static constexpr float kScales[] = {
82
      1.0,
83
      0.9984194528776054,
84
      0.9936866130906366,
85
      0.9858278282666936,
86
      0.9748868211368796,
87
      0.9609244059440204,
88
      0.9440180941651672,
89
      0.9242615922757944,
90
      0.9017641950288744,
91
      0.8766500784429904,
92
      0.8490574973847023,
93
      0.8191378932865928,
94
      0.7870549181591013,
95
      0.7529833816270532,
96
      0.7171081282466044,
97
      0.6796228528314651,
98
  };
99
};
100
101
template <>
102
struct DCTResampleScales<256, 32> {
103
  static constexpr float kScales[] = {
104
      1.0,
105
      0.9996047255830407,
106
      0.9984194528776054,
107
      0.9964458326264695,
108
      0.9936866130906366,
109
      0.9901456355893141,
110
      0.9858278282666936,
111
      0.9807391980963174,
112
      0.9748868211368796,
113
      0.9682788310563117,
114
      0.9609244059440204,
115
      0.9528337534340876,
116
      0.9440180941651672,
117
      0.9344896436056892,
118
      0.9242615922757944,
119
      0.913348084400198,
120
      0.9017641950288744,
121
      0.8895259056651056,
122
      0.8766500784429904,
123
      0.8631544288990163,
124
      0.8490574973847023,
125
      0.8343786191696513,
126
      0.8191378932865928,
127
      0.8033561501721485,
128
      0.7870549181591013,
129
      0.7702563888779096,
130
      0.7529833816270532,
131
      0.7352593067735488,
132
      0.7171081282466044,
133
      0.6985543251889097,
134
      0.6796228528314651,
135
      0.6603391026591464,
136
  };
137
};
138
139
// Inverses of the above.
140
template <>
141
struct DCTResampleScales<1, 8> {
142
  static constexpr float kScales[] = {
143
      1.000000000000000000,
144
  };
145
};
146
147
template <>
148
struct DCTResampleScales<2, 16> {
149
  static constexpr float kScales[] = {
150
      1.000000000000000000,
151
      1.108937353592731823,
152
  };
153
};
154
155
template <>
156
struct DCTResampleScales<4, 32> {
157
  static constexpr float kScales[] = {
158
      1.000000000000000000,
159
      1.025760096781116015,
160
      1.108937353592731823,
161
      1.270559368765487251,
162
  };
163
};
164
165
template <>
166
struct DCTResampleScales<8, 64> {
167
  static constexpr float kScales[] = {
168
      1.0000000000000000, 1.0063534990068217, 1.0257600967811158,
169
      1.0593017296817173, 1.1089373535927318, 1.1777765381970435,
170
      1.2705593687654873, 1.3944898413647777,
171
  };
172
};
173
174
template <>
175
struct DCTResampleScales<16, 128> {
176
  static constexpr float kScales[] = {
177
      1.0,
178
      1.0015830492062623,
179
      1.0063534990068217,
180
      1.0143759095928793,
181
      1.0257600967811158,
182
      1.0406645869480142,
183
      1.0593017296817173,
184
      1.0819447744633812,
185
      1.1089373535927318,
186
      1.1407059950032632,
187
      1.1777765381970435,
188
      1.2207956782315876,
189
      1.2705593687654873,
190
      1.3280505578213306,
191
      1.3944898413647777,
192
      1.4714043176061107,
193
  };
194
};
195
196
template <>
197
struct DCTResampleScales<32, 256> {
198
  static constexpr float kScales[] = {
199
      1.0,
200
      1.0003954307206069,
201
      1.0015830492062623,
202
      1.0035668445360069,
203
      1.0063534990068217,
204
      1.009952439375063,
205
      1.0143759095928793,
206
      1.0196390660647288,
207
      1.0257600967811158,
208
      1.0327603660498115,
209
      1.0406645869480142,
210
      1.049501024072585,
211
      1.0593017296817173,
212
      1.0701028169146336,
213
      1.0819447744633812,
214
      1.0948728278734026,
215
      1.1089373535927318,
216
      1.124194353004584,
217
      1.1407059950032632,
218
      1.158541237256391,
219
      1.1777765381970435,
220
      1.1984966740820495,
221
      1.2207956782315876,
222
      1.244777922949508,
223
      1.2705593687654873,
224
      1.2982690107339132,
225
      1.3280505578213306,
226
      1.3600643892400104,
227
      1.3944898413647777,
228
      1.4315278911623237,
229
      1.4714043176061107,
230
      1.5143734423314616,
231
  };
232
};
233
234
// Constants for DCT implementation. Generated by the following snippet:
235
// for i in range(N // 2):
236
//    print(1.0 / (2 * math.cos((i + 0.5) * math.pi / N)), end=", ")
237
template <size_t N>
238
struct WcMultipliers;
239
240
template <>
241
struct WcMultipliers<4> {
242
  static constexpr float kMultipliers[] = {
243
      0.541196100146197,
244
      1.3065629648763764,
245
  };
246
};
247
248
template <>
249
struct WcMultipliers<8> {
250
  static constexpr float kMultipliers[] = {
251
      0.5097955791041592,
252
      0.6013448869350453,
253
      0.8999762231364156,
254
      2.5629154477415055,
255
  };
256
};
257
258
template <>
259
struct WcMultipliers<16> {
260
  static constexpr float kMultipliers[] = {
261
      0.5024192861881557, 0.5224986149396889, 0.5669440348163577,
262
      0.6468217833599901, 0.7881546234512502, 1.060677685990347,
263
      1.7224470982383342, 5.101148618689155,
264
  };
265
};
266
267
template <>
268
struct WcMultipliers<32> {
269
  static constexpr float kMultipliers[] = {
270
      0.5006029982351963, 0.5054709598975436, 0.5154473099226246,
271
      0.5310425910897841, 0.5531038960344445, 0.5829349682061339,
272
      0.6225041230356648, 0.6748083414550057, 0.7445362710022986,
273
      0.8393496454155268, 0.9725682378619608, 1.1694399334328847,
274
      1.4841646163141662, 2.057781009953411,  3.407608418468719,
275
      10.190008123548033,
276
  };
277
};
278
template <>
279
struct WcMultipliers<64> {
280
  static constexpr float kMultipliers[] = {
281
      0.500150636020651,  0.5013584524464084, 0.5037887256810443,
282
      0.5074711720725553, 0.5124514794082247, 0.5187927131053328,
283
      0.52657731515427,   0.535909816907992,  0.5469204379855088,
284
      0.5597698129470802, 0.57465518403266,   0.5918185358574165,
285
      0.6115573478825099, 0.6342389366884031, 0.6603198078137061,
286
      0.6903721282002123, 0.7251205223771985, 0.7654941649730891,
287
      0.8127020908144905, 0.8683447152233481, 0.9345835970364075,
288
      1.0144082649970547, 1.1120716205797176, 1.233832737976571,
289
      1.3892939586328277, 1.5939722833856311, 1.8746759800084078,
290
      2.282050068005162,  2.924628428158216,  4.084611078129248,
291
      6.796750711673633,  20.373878167231453,
292
  };
293
};
294
template <>
295
struct WcMultipliers<128> {
296
  static constexpr float kMultipliers[] = {
297
      0.5000376519155477, 0.5003390374428216, 0.5009427176380873,
298
      0.5018505174842379, 0.5030651913013697, 0.5045904432216454,
299
      0.5064309549285542, 0.5085924210498143, 0.5110815927066812,
300
      0.5139063298475396, 0.5170756631334912, 0.5205998663018917,
301
      0.524490540114724,  0.5287607092074876, 0.5334249333971333,
302
      0.538499435291984,  0.5440022463817783, 0.549953374183236,
303
      0.5563749934898856, 0.5632916653417023, 0.5707305880121454,
304
      0.5787218851348208, 0.5872989370937893, 0.5964987630244563,
305
      0.606362462272146,  0.6169357260050706, 0.6282694319707711,
306
      0.6404203382416639, 0.6534518953751283, 0.6674352009263413,
307
      0.6824501259764195, 0.6985866506472291, 0.7159464549705746,
308
      0.7346448236478627, 0.7548129391165311, 0.776600658233963,
309
      0.8001798956216941, 0.8257487738627852, 0.8535367510066064,
310
      0.8838110045596234, 0.9168844461846523, 0.9531258743921193,
311
      0.9929729612675466, 1.036949040910389,  1.0856850642580145,
312
      1.1399486751015042, 1.2006832557294167, 1.2690611716991191,
313
      1.346557628206286,  1.4350550884414341, 1.5369941008524954,
314
      1.6555965242641195, 1.7952052190778898, 1.961817848571166,
315
      2.163957818751979,  2.4141600002500763, 2.7316450287739396,
316
      3.147462191781909,  3.7152427383269746, 4.5362909369693565,
317
      5.827688377844654,  8.153848602466814,  13.58429025728446,
318
      40.744688103351834,
319
  };
320
};
321
322
template <>
323
struct WcMultipliers<256> {
324
  static constexpr float kMultipliers[128] = {
325
      0.5000094125358878, 0.500084723455784,  0.5002354020255269,
326
      0.5004615618093246, 0.5007633734146156, 0.5011410648064231,
327
      0.5015949217281668, 0.502125288230386,  0.5027325673091954,
328
      0.5034172216566842, 0.5041797745258774, 0.5050208107132756,
329
      0.5059409776624396, 0.5069409866925212, 0.5080216143561264,
330
      0.509183703931388,  0.5104281670536573, 0.5117559854927805,
331
      0.5131682130825206, 0.5146659778093218, 0.516250484068288,
332
      0.5179230150949777, 0.5196849355823947, 0.5215376944933958,
333
      0.5234828280796439, 0.52552196311921,   0.5276568203859896,
334
      0.5298892183652453, 0.5322210772308335, 0.5346544231010253,
335
      0.537191392591309,  0.5398342376841637, 0.5425853309375497,
336
      0.545447171055775,  0.5484223888484947, 0.551513753605893,
337
      0.554724179920619,  0.5580567349898085, 0.5615146464335654,
338
      0.5651013106696203, 0.5688203018875696, 0.5726753816701664,
339
      0.5766705093136241, 0.5808098529038624, 0.5850978012111273,
340
      0.58953897647151,   0.5941382481306648, 0.5989007476325463,
341
      0.6038318843443582, 0.6089373627182432, 0.614223200800649,
342
      0.6196957502119484, 0.6253617177319102, 0.6312281886412079,
343
      0.6373026519855411, 0.6435930279473415, 0.6501076975307724,
344
      0.6568555347890955, 0.6638459418498757, 0.6710888870233562,
345
      0.6785949463131795, 0.6863753486870501, 0.6944420255086364,
346
      0.7028076645818034, 0.7114857693151208, 0.7204907235796304,
347
      0.7298378629074134, 0.7395435527641373, 0.749625274727372,
348
      0.7601017215162176, 0.7709929019493761, 0.7823202570613161,
349
      0.7941067887834509, 0.8063772028037925, 0.8191580674598145,
350
      0.83247799080191,   0.8463678182968619, 0.860860854031955,
351
      0.8759931087426972, 0.8918035785352535, 0.9083345588266809,
352
      0.9256319988042384, 0.9437459026371479, 0.962730784794803,
353
      0.9826461881778968, 1.0035572754078206, 1.0255355056139732,
354
      1.048659411496106,  1.0730154944316674, 1.0986992590905857,
355
      1.1258164135986009, 1.1544842669978943, 1.184833362908442,
356
      1.217009397314603,  1.2511754798461228, 1.287514812536712,
357
      1.326233878832723,  1.3675662599582539, 1.411777227500661,
358
      1.459169302866857,  1.5100890297227016, 1.5649352798258847,
359
      1.6241695131835794, 1.6883285509131505, 1.7580406092704062,
360
      1.8340456094306077, 1.9172211551275689, 2.0086161135167564,
361
      2.1094945286246385, 2.22139377701127,   2.346202662531156,
362
      2.486267909203593,  2.644541877144861,  2.824791402350551,
363
      3.0318994541759925, 3.2723115884254845, 3.5547153325075804,
364
      3.891107790700307,  4.298537526449054,  4.802076008665048,
365
      5.440166215091329,  6.274908408039339,  7.413566756422303,
366
      9.058751453879703,  11.644627325175037, 16.300023088031555,
367
      27.163977662448232, 81.48784219222516,
368
  };
369
};
370
371
// Apply the DCT algorithm-intrinsic constants to DCTResampleScale.
372
template <size_t FROM, size_t TO>
373
5.70M
constexpr float DCTTotalResampleScale(size_t x) {
374
5.70M
  return DCTResampleScales<FROM, TO>::kScales[x];
375
5.70M
}
float jxl::DCTTotalResampleScale<16ul, 2ul>(unsigned long)
Line
Count
Source
373
716k
constexpr float DCTTotalResampleScale(size_t x) {
374
716k
  return DCTResampleScales<FROM, TO>::kScales[x];
375
716k
}
float jxl::DCTTotalResampleScale<8ul, 1ul>(unsigned long)
Line
Count
Source
373
209k
constexpr float DCTTotalResampleScale(size_t x) {
374
209k
  return DCTResampleScales<FROM, TO>::kScales[x];
375
209k
}
float jxl::DCTTotalResampleScale<32ul, 4ul>(unsigned long)
Line
Count
Source
373
1.00M
constexpr float DCTTotalResampleScale(size_t x) {
374
1.00M
  return DCTResampleScales<FROM, TO>::kScales[x];
375
1.00M
}
float jxl::DCTTotalResampleScale<64ul, 8ul>(unsigned long)
Line
Count
Source
373
333k
constexpr float DCTTotalResampleScale(size_t x) {
374
333k
  return DCTResampleScales<FROM, TO>::kScales[x];
375
333k
}
Unexecuted instantiation: float jxl::DCTTotalResampleScale<128ul, 16ul>(unsigned long)
Unexecuted instantiation: float jxl::DCTTotalResampleScale<256ul, 32ul>(unsigned long)
float jxl::DCTTotalResampleScale<2ul, 16ul>(unsigned long)
Line
Count
Source
373
1.09M
constexpr float DCTTotalResampleScale(size_t x) {
374
1.09M
  return DCTResampleScales<FROM, TO>::kScales[x];
375
1.09M
}
float jxl::DCTTotalResampleScale<1ul, 8ul>(unsigned long)
Line
Count
Source
373
326k
constexpr float DCTTotalResampleScale(size_t x) {
374
326k
  return DCTResampleScales<FROM, TO>::kScales[x];
375
326k
}
float jxl::DCTTotalResampleScale<4ul, 32ul>(unsigned long)
Line
Count
Source
373
1.51M
constexpr float DCTTotalResampleScale(size_t x) {
374
1.51M
  return DCTResampleScales<FROM, TO>::kScales[x];
375
1.51M
}
float jxl::DCTTotalResampleScale<8ul, 64ul>(unsigned long)
Line
Count
Source
373
501k
constexpr float DCTTotalResampleScale(size_t x) {
374
501k
  return DCTResampleScales<FROM, TO>::kScales[x];
375
501k
}
Unexecuted instantiation: float jxl::DCTTotalResampleScale<16ul, 128ul>(unsigned long)
Unexecuted instantiation: float jxl::DCTTotalResampleScale<32ul, 256ul>(unsigned long)
376
377
}  // namespace jxl
378
379
#endif  // LIB_JXL_DCT_SCALES_H_