/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 | 558k | constexpr float DCTTotalResampleScale(size_t x) { |
374 | 558k | return DCTResampleScales<FROM, TO>::kScales[x]; |
375 | 558k | } Unexecuted instantiation: float jxl::DCTTotalResampleScale<8ul, 1ul>(unsigned long) Unexecuted instantiation: float jxl::DCTTotalResampleScale<16ul, 2ul>(unsigned long) Unexecuted instantiation: float jxl::DCTTotalResampleScale<32ul, 4ul>(unsigned long) Unexecuted instantiation: float jxl::DCTTotalResampleScale<64ul, 8ul>(unsigned long) 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 | 282k | constexpr float DCTTotalResampleScale(size_t x) { | 374 | 282k | return DCTResampleScales<FROM, TO>::kScales[x]; | 375 | 282k | } |
float jxl::DCTTotalResampleScale<1ul, 8ul>(unsigned long) Line | Count | Source | 373 | 143k | constexpr float DCTTotalResampleScale(size_t x) { | 374 | 143k | return DCTResampleScales<FROM, TO>::kScales[x]; | 375 | 143k | } |
float jxl::DCTTotalResampleScale<4ul, 32ul>(unsigned long) Line | Count | Source | 373 | 133k | constexpr float DCTTotalResampleScale(size_t x) { | 374 | 133k | return DCTResampleScales<FROM, TO>::kScales[x]; | 375 | 133k | } |
Unexecuted instantiation: float jxl::DCTTotalResampleScale<8ul, 64ul>(unsigned long) 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_ |