/work/svt-av1/Source/Lib/Codec/noise_model.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2017, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 2 Clause License and |
5 | | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
6 | | * was not distributed with this source code in the LICENSE file, you can |
7 | | * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open |
8 | | * Media Patent License 1.0 was not distributed with this source code in the |
9 | | * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license. |
10 | | */ |
11 | | |
12 | | #include "EbConfigMacros.h" |
13 | | |
14 | | #if CONFIG_ENABLE_FILM_GRAIN |
15 | | #include <math.h> |
16 | | #include <stdio.h> |
17 | | #include <stdlib.h> |
18 | | #include "noise_model.h" |
19 | | #include "definitions.h" |
20 | | #include "sequence_control_set.h" |
21 | | #include "noise_util.h" |
22 | | #include "mathutils.h" |
23 | | #include "svt_log.h" |
24 | | #include "aom_dsp_rtcd.h" |
25 | | #include "pic_operators.h" |
26 | | |
27 | | static const int32_t k_max_lag = 4; |
28 | | |
29 | | void svt_aom_un_pack2d(uint16_t* in16_bit_buffer, uint32_t in_stride, uint8_t* out8_bit_buffer, uint32_t out8_stride, |
30 | | uint8_t* outn_bit_buffer, uint32_t outn_stride, uint32_t width, uint32_t height); |
31 | | |
32 | | void svt_aom_pack2d_src(uint8_t* in8_bit_buffer, uint32_t in8_stride, uint8_t* inn_bit_buffer, uint32_t inn_stride, |
33 | | uint16_t* out16_bit_buffer, uint32_t out_stride, uint32_t width, uint32_t height); |
34 | | void svt_aom_compressed_pack_sb(uint8_t* in8_bit_buffer, uint32_t in8_stride, uint8_t* inn_bit_buffer, |
35 | | uint32_t inn_stride, uint16_t* out16_bit_buffer, uint32_t out_stride, uint32_t width, |
36 | | uint32_t height); |
37 | | // Defines a function that can be used to obtain the mean of a block for the |
38 | | // provided data type (uint8_t, or uint16_t) |
39 | | #define GET_BLOCK_MEAN(INT_TYPE, suffix) \ |
40 | | static double get_block_mean_##suffix( \ |
41 | | const INT_TYPE* data, int32_t w, int32_t h, int32_t stride, int32_t x_o, int32_t y_o, int32_t block_size) { \ |
42 | | const int32_t max_h = AOMMIN(h - y_o, block_size); \ |
43 | | const int32_t max_w = AOMMIN(w - x_o, block_size); \ |
44 | | double block_mean = 0; \ |
45 | | for (int32_t y = 0; y < max_h; ++y) { \ |
46 | | for (int32_t x = 0; x < max_w; ++x) { \ |
47 | | block_mean += data[(y_o + y) * stride + x_o + x]; \ |
48 | | } \ |
49 | | } \ |
50 | | return block_mean / (max_w * max_h); \ |
51 | | } |
52 | | |
53 | | GET_BLOCK_MEAN(uint8_t, lowbd); |
54 | | GET_BLOCK_MEAN(uint16_t, highbd); |
55 | | |
56 | | static INLINE double get_block_mean(const uint8_t* data, int32_t w, int32_t h, int32_t stride, int32_t x_o, int32_t y_o, |
57 | | int32_t block_size, int32_t use_highbd) { |
58 | | if (use_highbd) { |
59 | | return get_block_mean_highbd((const uint16_t*)data, w, h, stride, x_o, y_o, block_size); |
60 | | } |
61 | | return get_block_mean_lowbd(data, w, h, stride, x_o, y_o, block_size); |
62 | | } |
63 | | |
64 | | // Defines a function that can be used to obtain the variance of a block |
65 | | // for the provided data type (uint8_t, or uint16_t) |
66 | | #define GET_NOISE_VAR(INT_TYPE, suffix) \ |
67 | | static double get_noise_var_##suffix(const INT_TYPE* data, \ |
68 | | const INT_TYPE* denoised, \ |
69 | | int32_t stride, \ |
70 | | int32_t w, \ |
71 | | int32_t h, \ |
72 | | int32_t x_o, \ |
73 | | int32_t y_o, \ |
74 | | int32_t block_size_x, \ |
75 | | int32_t block_size_y) { \ |
76 | | const int32_t max_h = AOMMIN(h - y_o, block_size_y); \ |
77 | | const int32_t max_w = AOMMIN(w - x_o, block_size_x); \ |
78 | | double noise_var = 0; \ |
79 | | double noise_mean = 0; \ |
80 | | for (int32_t y = 0; y < max_h; ++y) { \ |
81 | | for (int32_t x = 0; x < max_w; ++x) { \ |
82 | | double noise = (double)data[(y_o + y) * stride + x_o + x] - denoised[(y_o + y) * stride + x_o + x]; \ |
83 | | noise_mean += noise; \ |
84 | | noise_var += noise * noise; \ |
85 | | } \ |
86 | | } \ |
87 | | noise_mean /= (max_w * max_h); \ |
88 | | return noise_var / (max_w * max_h) - noise_mean * noise_mean; \ |
89 | | } |
90 | | |
91 | | GET_NOISE_VAR(uint8_t, lowbd); |
92 | | GET_NOISE_VAR(uint16_t, highbd); |
93 | | |
94 | | static INLINE double get_noise_var(const uint8_t* data, const uint8_t* denoised, int32_t w, int32_t h, int32_t stride, |
95 | | int32_t x_o, int32_t y_o, int32_t block_size_x, int32_t block_size_y, |
96 | | int32_t use_highbd) { |
97 | | if (use_highbd) { |
98 | | return get_noise_var_highbd( |
99 | | (const uint16_t*)data, (const uint16_t*)denoised, w, h, stride, x_o, y_o, block_size_x, block_size_y); |
100 | | } |
101 | | return get_noise_var_lowbd(data, denoised, w, h, stride, x_o, y_o, block_size_x, block_size_y); |
102 | | } |
103 | | |
104 | | static void equation_system_free(AomEquationSystem* eqns) { |
105 | | if (!eqns) { |
106 | | return; |
107 | | } |
108 | | free(eqns->A); |
109 | | eqns->A = NULL; |
110 | | free(eqns->b); |
111 | | eqns->b = NULL; |
112 | | free(eqns->x); |
113 | | eqns->x = NULL; |
114 | | eqns->n = 0; |
115 | | } |
116 | | |
117 | | static void equation_system_clear(AomEquationSystem* eqns) { |
118 | | const int32_t n = eqns->n; |
119 | | memset(eqns->A, 0, sizeof(*eqns->A) * n * n); |
120 | | memset(eqns->x, 0, sizeof(*eqns->x) * n); |
121 | | memset(eqns->b, 0, sizeof(*eqns->b) * n); |
122 | | } |
123 | | |
124 | | static void equation_system_copy(AomEquationSystem* dst, const AomEquationSystem* src) { |
125 | | const int32_t n = dst->n; |
126 | | if (svt_memcpy != NULL) { |
127 | | svt_memcpy(dst->A, src->A, sizeof(*dst->A) * n * n); |
128 | | svt_memcpy(dst->x, src->x, sizeof(*dst->x) * n); |
129 | | svt_memcpy(dst->b, src->b, sizeof(*dst->b) * n); |
130 | | } else { |
131 | | svt_memcpy_c(dst->A, src->A, sizeof(*dst->A) * n * n); |
132 | | svt_memcpy_c(dst->x, src->x, sizeof(*dst->x) * n); |
133 | | svt_memcpy_c(dst->b, src->b, sizeof(*dst->b) * n); |
134 | | } |
135 | | } |
136 | | |
137 | | static int32_t equation_system_init(AomEquationSystem* eqns, int32_t n) { |
138 | | eqns->A = (double*)malloc(sizeof(*eqns->A) * n * n); |
139 | | eqns->b = (double*)malloc(sizeof(*eqns->b) * n); |
140 | | eqns->x = (double*)malloc(sizeof(*eqns->x) * n); |
141 | | eqns->n = n; |
142 | | if (!eqns->A || !eqns->b || !eqns->x) { |
143 | | SVT_ERROR("Failed to allocate system of equations of size %d\n", n); |
144 | | equation_system_free(eqns); |
145 | | return 0; |
146 | | } |
147 | | equation_system_clear(eqns); |
148 | | return 1; |
149 | | } |
150 | | |
151 | | static int32_t equation_system_solve(AomEquationSystem* eqns) { |
152 | | const int32_t n = eqns->n; |
153 | | double* b = (double*)malloc(sizeof(*b) * n); |
154 | | double* A = (double*)malloc(sizeof(*A) * n * n); |
155 | | int32_t ret = 0; |
156 | | if (A == NULL || b == NULL) { |
157 | | SVT_ERROR("Unable to allocate temp values of size %dx%d\n", n, n); |
158 | | free(b); |
159 | | free(A); |
160 | | return 0; |
161 | | } |
162 | | if (svt_memcpy != NULL) { |
163 | | svt_memcpy(A, eqns->A, sizeof(*eqns->A) * n * n); |
164 | | svt_memcpy(b, eqns->b, sizeof(*eqns->b) * n); |
165 | | } else { |
166 | | svt_memcpy_c(A, eqns->A, sizeof(*eqns->A) * n * n); |
167 | | svt_memcpy_c(b, eqns->b, sizeof(*eqns->b) * n); |
168 | | } |
169 | | ret = linsolve(n, A, eqns->n, b, eqns->x); |
170 | | free(b); |
171 | | free(A); |
172 | | |
173 | | if (ret == 0) { |
174 | | return 0; |
175 | | } |
176 | | return 1; |
177 | | } |
178 | | |
179 | | static void noise_strength_solver_clear(AomNoiseStrengthSolver* solver) { |
180 | | equation_system_clear(&solver->eqns); |
181 | | solver->num_equations = 0; |
182 | | solver->total = 0; |
183 | | } |
184 | | |
185 | 0 | static void noise_strength_solver_copy(AomNoiseStrengthSolver* dest, AomNoiseStrengthSolver* src) { |
186 | 0 | equation_system_copy(&dest->eqns, &src->eqns); |
187 | 0 | dest->num_equations = src->num_equations; |
188 | 0 | dest->total = src->total; |
189 | 0 | } |
190 | | |
191 | | // Return the number of coefficients required for the given parameters |
192 | | static int32_t num_coeffs(const AomNoiseModelParams params) { |
193 | | const int32_t n = 2 * params.lag + 1; |
194 | | switch (params.shape) { |
195 | | case AOM_NOISE_SHAPE_DIAMOND: |
196 | | return params.lag * (params.lag + 1); |
197 | | case AOM_NOISE_SHAPE_SQUARE: |
198 | | return (n * n) / 2; |
199 | | } |
200 | | return 0; |
201 | | } |
202 | | |
203 | | static int32_t noise_state_init(AomNoiseState* state, int32_t n, int32_t bit_depth) { |
204 | | const int32_t k_num_bins = 20; |
205 | | if (!equation_system_init(&state->eqns, n)) { |
206 | | SVT_ERROR("Failed initialization noise state with size %d\n", n); |
207 | | return 0; |
208 | | } |
209 | | state->ar_gain = 1.0; |
210 | | state->num_observations = 0; |
211 | | return svt_aom_noise_strength_solver_init(&state->strength_solver, k_num_bins, bit_depth); |
212 | | } |
213 | | |
214 | | static void set_chroma_coefficient_fallback_soln(AomEquationSystem* eqns) { |
215 | | const double k_tolerance = 1e-6; |
216 | | const int32_t last = eqns->n - 1; |
217 | | // Set all of the AR coefficients to zero, but try to solve for correlation |
218 | | // with the luma channel |
219 | | memset(eqns->x, 0, sizeof(*eqns->x) * eqns->n); |
220 | | if (fabs(eqns->A[last * eqns->n + last]) > k_tolerance) { |
221 | | eqns->x[last] = eqns->b[last] / eqns->A[last * eqns->n + last]; |
222 | | } |
223 | | } |
224 | | |
225 | 0 | int32_t svt_aom_noise_strength_lut_init(AomNoiseStrengthLut* lut, int32_t num_points) { |
226 | 0 | if (!lut) { |
227 | 0 | return 0; |
228 | 0 | } |
229 | 0 | lut->points = (double (*)[2])malloc(num_points * sizeof(*lut->points)); |
230 | 0 | if (!lut->points) { |
231 | 0 | return 0; |
232 | 0 | } |
233 | 0 | lut->num_points = num_points; |
234 | 0 | memset(lut->points, 0, sizeof(*lut->points) * num_points); |
235 | 0 | return 1; |
236 | 0 | } |
237 | | |
238 | 0 | void svt_aom_noise_strength_lut_free(AomNoiseStrengthLut* lut) { |
239 | 0 | if (!lut) { |
240 | 0 | return; |
241 | 0 | } |
242 | 0 | free(lut->points); |
243 | 0 | lut->points = NULL; |
244 | 0 | lut->num_points = 0; |
245 | 0 | } |
246 | | |
247 | | static double noise_strength_solver_get_bin_index(const AomNoiseStrengthSolver* solver, double value) { |
248 | | const double val = fclamp(value, solver->min_intensity, solver->max_intensity); |
249 | | const double range = solver->max_intensity - solver->min_intensity; |
250 | | return (solver->num_bins - 1) * (val - solver->min_intensity) / range; |
251 | | } |
252 | | |
253 | | static double noise_strength_solver_get_value(const AomNoiseStrengthSolver* solver, double x) { |
254 | | const double bin = noise_strength_solver_get_bin_index(solver, x); |
255 | | const int32_t bin_i0 = (int32_t)floor(bin); |
256 | | const int32_t bin_i1 = AOMMIN(solver->num_bins - 1, bin_i0 + 1); |
257 | | const double a = bin - bin_i0; |
258 | | return (1.0 - a) * solver->eqns.x[bin_i0] + a * solver->eqns.x[bin_i1]; |
259 | | } |
260 | | |
261 | | void svt_aom_noise_strength_solver_add_measurement(AomNoiseStrengthSolver* solver, double block_mean, |
262 | 0 | double noise_std) { |
263 | 0 | const double bin = noise_strength_solver_get_bin_index(solver, block_mean); |
264 | 0 | const int32_t bin_i0 = (int32_t)floor(bin); |
265 | 0 | const int32_t bin_i1 = AOMMIN(solver->num_bins - 1, bin_i0 + 1); |
266 | 0 | const double a = bin - bin_i0; |
267 | 0 | const int32_t n = solver->num_bins; |
268 | 0 | solver->eqns.A[bin_i0 * n + bin_i0] += (1.0 - a) * (1.0 - a); |
269 | 0 | solver->eqns.A[bin_i1 * n + bin_i0] += a * (1.0 - a); |
270 | 0 | solver->eqns.A[bin_i1 * n + bin_i1] += a * a; |
271 | 0 | solver->eqns.A[bin_i0 * n + bin_i1] += a * (1.0 - a); |
272 | 0 | solver->eqns.b[bin_i0] += (1.0 - a) * noise_std; |
273 | 0 | solver->eqns.b[bin_i1] += a * noise_std; |
274 | 0 | solver->total += noise_std; |
275 | 0 | solver->num_equations++; |
276 | 0 | } |
277 | | |
278 | 0 | int32_t svt_aom_noise_strength_solver_solve(AomNoiseStrengthSolver* solver) { |
279 | | // Add regularization proportional to the number of constraints |
280 | 0 | const int32_t n = solver->num_bins; |
281 | 0 | const double k_alpha = 2.0 * (double)(solver->num_equations) / n; |
282 | 0 | int32_t result = 0; |
283 | 0 | double mean = 0; |
284 | | |
285 | | // Do this in a non-destructive manner so it is not confusing to the caller |
286 | 0 | double* old_a = solver->eqns.A; |
287 | 0 | double* A = (double*)malloc(sizeof(*A) * n * n); |
288 | 0 | if (!A) { |
289 | 0 | SVT_ERROR("Unable to allocate copy of A\n"); |
290 | 0 | return 0; |
291 | 0 | } |
292 | 0 | if (svt_memcpy != NULL) { |
293 | 0 | svt_memcpy(A, old_a, sizeof(*A) * n * n); |
294 | 0 | } else { |
295 | 0 | svt_memcpy_c(A, old_a, sizeof(*A) * n * n); |
296 | 0 | } |
297 | |
|
298 | 0 | for (int32_t i = 0; i < n; ++i) { |
299 | 0 | const int32_t i_lo = AOMMAX(0, i - 1); |
300 | 0 | const int32_t i_hi = AOMMIN(n - 1, i + 1); |
301 | 0 | A[i * n + i_lo] -= k_alpha; |
302 | 0 | A[i * n + i] += 2 * k_alpha; |
303 | 0 | A[i * n + i_hi] -= k_alpha; |
304 | 0 | } |
305 | | |
306 | | // Small regularization to give average noise strength |
307 | 0 | mean = solver->total / solver->num_equations; |
308 | 0 | for (int32_t i = 0; i < n; ++i) { |
309 | 0 | A[i * n + i] += 1.0 / 8192.; |
310 | 0 | solver->eqns.b[i] += mean / 8192.; |
311 | 0 | } |
312 | 0 | solver->eqns.A = A; |
313 | 0 | result = equation_system_solve(&solver->eqns); |
314 | 0 | solver->eqns.A = old_a; |
315 | |
|
316 | 0 | free(A); |
317 | 0 | return result; |
318 | 0 | } |
319 | | |
320 | 0 | int32_t svt_aom_noise_strength_solver_init(AomNoiseStrengthSolver* solver, int32_t num_bins, int32_t bit_depth) { |
321 | 0 | if (!solver) { |
322 | 0 | return 0; |
323 | 0 | } |
324 | 0 | memset(solver, 0, sizeof(*solver)); |
325 | 0 | solver->num_bins = num_bins; |
326 | 0 | solver->min_intensity = 0; |
327 | 0 | solver->max_intensity = (1 << bit_depth) - 1; |
328 | 0 | solver->total = 0; |
329 | 0 | solver->num_equations = 0; |
330 | 0 | return equation_system_init(&solver->eqns, num_bins); |
331 | 0 | } |
332 | | |
333 | 0 | double svt_aom_noise_strength_solver_get_center(const AomNoiseStrengthSolver* solver, int32_t i) { |
334 | 0 | const double range = solver->max_intensity - solver->min_intensity; |
335 | 0 | const int32_t n = solver->num_bins; |
336 | 0 | return ((double)i) / (n - 1) * range + solver->min_intensity; |
337 | 0 | } |
338 | | |
339 | | // Computes the residual if a point were to be removed from the lut. This is |
340 | | // calculated as the area between the output of the solver and the line segment |
341 | | // that would be formed between [x_{i - 1}, x_{i + 1}). |
342 | | static void update_piecewise_linear_residual(const AomNoiseStrengthSolver* solver, const AomNoiseStrengthLut* lut, |
343 | | double* residual, int32_t start, int32_t end) { |
344 | | const double dx = 255. / solver->num_bins; |
345 | | for (int32_t i = AOMMAX(start, 1); i < AOMMIN(end, lut->num_points - 1); ++i) { |
346 | | const int32_t lower = AOMMAX( |
347 | | 0, (int32_t)floor(noise_strength_solver_get_bin_index(solver, lut->points[i - 1][0]))); |
348 | | const int32_t upper = AOMMIN(solver->num_bins - 1, |
349 | | (int32_t)ceil(noise_strength_solver_get_bin_index(solver, lut->points[i + 1][0]))); |
350 | | double r = 0; |
351 | | for (int32_t j = lower; j <= upper; ++j) { |
352 | | const double x = svt_aom_noise_strength_solver_get_center(solver, j); |
353 | | if (x < lut->points[i - 1][0]) { |
354 | | continue; |
355 | | } |
356 | | if (x >= lut->points[i + 1][0]) { |
357 | | continue; |
358 | | } |
359 | | const double y = solver->eqns.x[j]; |
360 | | const double a = (x - lut->points[i - 1][0]) / (lut->points[i + 1][0] - lut->points[i - 1][0]); |
361 | | const double estimate_y = lut->points[i - 1][1] * (1.0 - a) + lut->points[i + 1][1] * a; |
362 | | r += fabs(y - estimate_y); |
363 | | } |
364 | | residual[i] = r * dx; |
365 | | } |
366 | | } |
367 | | |
368 | | int32_t svt_aom_noise_strength_solver_fit_piecewise(const AomNoiseStrengthSolver* solver, int32_t max_output_points, |
369 | 0 | AomNoiseStrengthLut* lut) { |
370 | | // The tolerance is normalized to be give consistent results between |
371 | | // different bit-depths. |
372 | 0 | const double k_tolerance = solver->max_intensity * 0.00625 / 255.0; |
373 | 0 | if (!svt_aom_noise_strength_lut_init(lut, solver->num_bins)) { |
374 | 0 | SVT_ERROR("Failed to init lut\n"); |
375 | 0 | return 0; |
376 | 0 | } |
377 | 0 | for (int32_t i = 0; i < solver->num_bins; ++i) { |
378 | 0 | lut->points[i][0] = svt_aom_noise_strength_solver_get_center(solver, i); |
379 | 0 | lut->points[i][1] = solver->eqns.x[i]; |
380 | 0 | } |
381 | 0 | if (max_output_points < 0) { |
382 | 0 | max_output_points = solver->num_bins; |
383 | 0 | } |
384 | 0 | double* residual = malloc(solver->num_bins * sizeof(*residual)); |
385 | 0 | ASSERT(residual != NULL); |
386 | 0 | memset(residual, 0, sizeof(*residual) * solver->num_bins); |
387 | |
|
388 | 0 | update_piecewise_linear_residual(solver, lut, residual, 0, solver->num_bins); |
389 | | |
390 | | // Greedily remove points if there are too many or if it doesn't hurt local |
391 | | // approximation (never remove the end points) |
392 | 0 | while (lut->num_points > 2) { |
393 | 0 | int32_t min_index = 1; |
394 | 0 | for (int32_t j = 1; j < lut->num_points - 1; ++j) { |
395 | 0 | if (residual[j] < residual[min_index]) { |
396 | 0 | min_index = j; |
397 | 0 | } |
398 | 0 | } |
399 | 0 | const double dx = lut->points[min_index + 1][0] - lut->points[min_index - 1][0]; |
400 | 0 | const double avg_residual = residual[min_index] / dx; |
401 | 0 | if (lut->num_points <= max_output_points && avg_residual > k_tolerance) { |
402 | 0 | break; |
403 | 0 | } |
404 | 0 | const int32_t num_remaining = lut->num_points - min_index - 1; |
405 | 0 | memmove(lut->points + min_index, lut->points + min_index + 1, sizeof(lut->points[0]) * num_remaining); |
406 | 0 | lut->num_points--; |
407 | |
|
408 | 0 | update_piecewise_linear_residual(solver, lut, residual, min_index - 1, min_index + 1); |
409 | 0 | } |
410 | 0 | free(residual); |
411 | 0 | return 1; |
412 | 0 | } |
413 | | |
414 | | int32_t svt_aom_flat_block_finder_init(AomFlatBlockFinder* block_finder, int32_t block_size, int32_t bit_depth, |
415 | 0 | int32_t use_highbd) { |
416 | 0 | const int32_t n = block_size * block_size; |
417 | 0 | AomEquationSystem eqns; |
418 | 0 | if (!equation_system_init(&eqns, kLowPolyNumParams)) { |
419 | 0 | SVT_ERROR("Failed to init equation system for block_size=%d\n", block_size); |
420 | 0 | return 0; |
421 | 0 | } |
422 | | |
423 | 0 | double* at_a_inv = (double*)malloc(kLowPolyNumParams * kLowPolyNumParams * sizeof(*at_a_inv)); |
424 | 0 | double* A = (double*)malloc(kLowPolyNumParams * n * sizeof(*A)); |
425 | 0 | if (at_a_inv == NULL || A == NULL) { |
426 | 0 | SVT_ERROR("Failed to alloc A or at_a_inv for block_size=%d\n", block_size); |
427 | 0 | free(at_a_inv); |
428 | 0 | free(A); |
429 | 0 | equation_system_free(&eqns); |
430 | 0 | return 0; |
431 | 0 | } |
432 | | |
433 | 0 | block_finder->A = A; |
434 | 0 | block_finder->at_a_inv = at_a_inv; |
435 | 0 | block_finder->block_size = block_size; |
436 | 0 | block_finder->normalization = (1 << bit_depth) - 1; |
437 | 0 | block_finder->use_highbd = use_highbd; |
438 | |
|
439 | 0 | for (int32_t y = 0; y < block_size; ++y) { |
440 | 0 | const double yd = ((double)y - block_size / 2.) / (block_size / 2.); |
441 | 0 | for (int32_t x = 0; x < block_size; ++x) { |
442 | 0 | const double xd = ((double)x - block_size / 2.) / (block_size / 2.); |
443 | 0 | const double coords[3] = {yd, xd, 1}; |
444 | 0 | const int32_t row = y * block_size + x; |
445 | 0 | A[kLowPolyNumParams * row + 0] = yd; |
446 | 0 | A[kLowPolyNumParams * row + 1] = xd; |
447 | 0 | A[kLowPolyNumParams * row + 2] = 1; |
448 | |
|
449 | 0 | for (int i = 0; i < kLowPolyNumParams; ++i) { |
450 | 0 | for (int j = 0; j < kLowPolyNumParams; ++j) { |
451 | 0 | eqns.A[kLowPolyNumParams * i + j] += coords[i] * coords[j]; |
452 | 0 | } |
453 | 0 | } |
454 | 0 | } |
455 | 0 | } |
456 | | |
457 | | // Lazy inverse using existing equation solver. |
458 | 0 | for (int i = 0; i < kLowPolyNumParams; ++i) { |
459 | 0 | memset(eqns.b, 0, sizeof(*eqns.b) * kLowPolyNumParams); |
460 | 0 | eqns.b[i] = 1; |
461 | 0 | equation_system_solve(&eqns); |
462 | |
|
463 | 0 | for (int j = 0; j < kLowPolyNumParams; ++j) { |
464 | 0 | at_a_inv[j * kLowPolyNumParams + i] = eqns.x[j]; |
465 | 0 | } |
466 | 0 | } |
467 | 0 | equation_system_free(&eqns); |
468 | 0 | return 1; |
469 | 0 | } |
470 | | |
471 | 0 | void svt_aom_flat_block_finder_free(AomFlatBlockFinder* block_finder) { |
472 | 0 | if (!block_finder) { |
473 | 0 | return; |
474 | 0 | } |
475 | 0 | free(block_finder->A); |
476 | 0 | free(block_finder->at_a_inv); |
477 | 0 | memset(block_finder, 0, sizeof(*block_finder)); |
478 | 0 | } |
479 | | |
480 | | void svt_aom_flat_block_finder_extract_block_c(const AomFlatBlockFinder* block_finder, const uint8_t* const data, |
481 | | int32_t w, int32_t h, int32_t stride, int32_t offsx, int32_t offsy, |
482 | 0 | double* plane, double* block) { |
483 | 0 | const int32_t block_size = block_finder->block_size; |
484 | 0 | const int32_t n = block_size * block_size; |
485 | 0 | const double* A = block_finder->A; |
486 | 0 | const double* at_a_inv = block_finder->at_a_inv; |
487 | 0 | const double recp_norm = 1 / block_finder->normalization; |
488 | 0 | double plane_coords[kLowPolyNumParams]; |
489 | 0 | double at_a_inv__b[kLowPolyNumParams]; |
490 | 0 | int32_t xi, yi, i; |
491 | |
|
492 | 0 | if (block_finder->use_highbd) { |
493 | 0 | const uint16_t* const data16 = (const uint16_t* const)data; |
494 | 0 | for (yi = 0; yi < block_size; ++yi) { |
495 | 0 | const int32_t y = clamp(offsy + yi, 0, h - 1); |
496 | 0 | for (xi = 0; xi < block_size; ++xi) { |
497 | 0 | const int32_t x = clamp(offsx + xi, 0, w - 1); |
498 | 0 | block[yi * block_size + xi] = ((double)data16[y * stride + x]) * recp_norm; |
499 | 0 | } |
500 | 0 | } |
501 | 0 | } else { |
502 | 0 | for (yi = 0; yi < block_size; ++yi) { |
503 | 0 | const int32_t y = clamp(offsy + yi, 0, h - 1); |
504 | 0 | for (xi = 0; xi < block_size; ++xi) { |
505 | 0 | const int32_t x = clamp(offsx + xi, 0, w - 1); |
506 | 0 | block[yi * block_size + xi] = ((double)data[y * stride + x]) * recp_norm; |
507 | 0 | } |
508 | 0 | } |
509 | 0 | } |
510 | 0 | #if (kLowPolyNumParams == 3) |
511 | 0 | multiply_mat_1_n_3(block, A, at_a_inv__b, n); |
512 | 0 | multiply_mat_3_3_1(at_a_inv, at_a_inv__b, plane_coords); |
513 | 0 | multiply_mat_n_3_1(A, plane_coords, plane, n); |
514 | | #else |
515 | | multiply_mat(block, A, at_a_inv__b, 1, n, kLowPolyNumParams); |
516 | | multiply_mat(at_a_inv, at_a_inv__b, plane_coords, kLowPolyNumParams, kLowPolyNumParams, 1); |
517 | | multiply_mat(A, plane_coords, plane, n, kLowPolyNumParams, 1); |
518 | | #endif |
519 | |
|
520 | 0 | for (i = 0; i < n; ++i) { |
521 | 0 | block[i] -= plane[i]; |
522 | 0 | } |
523 | 0 | } |
524 | | |
525 | | typedef struct { |
526 | | int32_t index; |
527 | | float score; |
528 | | } IndexAndscore; |
529 | | |
530 | | static int compare_scores(const void* a, const void* b) { |
531 | | const float diff = ((IndexAndscore*)a)->score - ((IndexAndscore*)b)->score; |
532 | | return diff < 0 ? -1 : diff > 0; |
533 | | } |
534 | | |
535 | | int32_t svt_aom_flat_block_finder_run(const AomFlatBlockFinder* block_finder, const uint8_t* const data, int32_t w, |
536 | 0 | int32_t h, int32_t stride, uint8_t* flat_blocks) { |
537 | | // The gradient-based features used in this code are based on: |
538 | | // A. Kokaram, D. Kelly, H. Denman and A. Crawford, "Measuring noise |
539 | | // correlation for improved video denoising," 2012 19th, ICIP. |
540 | | // The thresholds are more lenient to allow for correct grain modeling |
541 | | // if extreme cases. |
542 | 0 | const int32_t block_size = block_finder->block_size; |
543 | 0 | const int32_t n = block_size * block_size; |
544 | 0 | const double k_trace_threshold = 0.15 / (32 * 32); |
545 | 0 | const double k_ratio_threshold = 1.25; |
546 | 0 | const double k_norm_threshold = 0.08 / (32 * 32); |
547 | 0 | const double k_var_threshold = 0.005 / (double)n; |
548 | 0 | const int32_t num_blocks_w = (w + block_size - 1) / block_size; |
549 | 0 | const int32_t num_blocks_h = (h + block_size - 1) / block_size; |
550 | 0 | int32_t num_flat = 0; |
551 | 0 | double* plane = (double*)malloc(n * sizeof(*plane)); |
552 | 0 | double* block = (double*)malloc(n * sizeof(*block)); |
553 | 0 | IndexAndscore* scores = (IndexAndscore*)malloc(num_blocks_w * num_blocks_h * sizeof(*scores)); |
554 | 0 | if (plane == NULL || block == NULL || scores == NULL) { |
555 | 0 | SVT_ERROR("Failed to allocate memory for block of size %d\n", n); |
556 | 0 | free(plane); |
557 | 0 | free(block); |
558 | 0 | free(scores); |
559 | 0 | return -1; |
560 | 0 | } |
561 | | |
562 | | #ifdef NOISE_MODEL_LOG_SCORE |
563 | | SVT_ERROR("score = ["); |
564 | | #endif |
565 | 0 | for (int32_t by = 0; by < num_blocks_h; ++by) { |
566 | 0 | for (int32_t bx = 0; bx < num_blocks_w; ++bx) { |
567 | | // Compute gradient covariance matrix. |
568 | 0 | double g_xx = 0, g_xy = 0, g_yy = 0; |
569 | 0 | double var = 0; |
570 | 0 | double mean = 0; |
571 | 0 | svt_aom_flat_block_finder_extract_block( |
572 | 0 | block_finder, data, w, h, stride, bx * block_size, by * block_size, plane, block); |
573 | |
|
574 | 0 | for (int32_t yi = 1; yi < block_size - 1; ++yi) { |
575 | 0 | for (int32_t xi = 1; xi < block_size - 1; ++xi) { |
576 | 0 | const double gx = (block[yi * block_size + xi + 1] - block[yi * block_size + xi - 1]) / 2; |
577 | 0 | const double gy = (block[yi * block_size + xi + block_size] - |
578 | 0 | block[yi * block_size + xi - block_size]) / |
579 | 0 | 2; |
580 | 0 | g_xx += gx * gx; |
581 | 0 | g_xy += gx * gy; |
582 | 0 | g_yy += gy * gy; |
583 | |
|
584 | 0 | mean += block[yi * block_size + xi]; |
585 | 0 | var += block[yi * block_size + xi] * block[yi * block_size + xi]; |
586 | 0 | } |
587 | 0 | } |
588 | 0 | mean /= (block_size - 2) * (block_size - 2); |
589 | | |
590 | | // Normalize gradients by BlockSize. |
591 | 0 | g_xx /= ((block_size - 2) * (block_size - 2)); |
592 | 0 | g_xy /= ((block_size - 2) * (block_size - 2)); |
593 | 0 | g_yy /= ((block_size - 2) * (block_size - 2)); |
594 | 0 | var = var / ((block_size - 2) * (block_size - 2)) - mean * mean; |
595 | |
|
596 | 0 | { |
597 | 0 | const double trace = g_xx + g_yy; |
598 | 0 | const double det = g_xx * g_yy - g_xy * g_xy; |
599 | 0 | const double e1 = (trace + sqrt(trace * trace - 4 * det)) / 2.; |
600 | 0 | const double e2 = (trace - sqrt(trace * trace - 4 * det)) / 2.; |
601 | 0 | const double norm = e1; // Spectral norm |
602 | 0 | const double ratio = (e1 / AOMMAX(e2, 1e-6)); |
603 | 0 | const int32_t is_flat = (trace < k_trace_threshold) && (ratio < k_ratio_threshold) && |
604 | 0 | (norm < k_norm_threshold) && (var > k_var_threshold); |
605 | | // The following weights are used to combine the above features to give |
606 | | // a sigmoid score for flatness. If the input was normalized to [0,100] |
607 | | // the magnitude of these values would be close to 1 (e.g., weights |
608 | | // corresponding to variance would be a factor of 10000x smaller). |
609 | | // The weights are given in the following order: |
610 | | // [{var}, {ratio}, {trace}, {norm}, offset] |
611 | | // with one of the most discriminative being simply the variance. |
612 | 0 | const double weights[5] = {-6682, -0.2056, 13087, -12434, 2.5694}; |
613 | 0 | const float score = (float)(1.0 / |
614 | 0 | (1 + |
615 | 0 | exp(-(weights[0] * var + weights[1] * ratio + weights[2] * trace + |
616 | 0 | weights[3] * norm + weights[4])))); |
617 | 0 | flat_blocks[by * num_blocks_w + bx] = is_flat ? 255 : 0; |
618 | 0 | scores[by * num_blocks_w + bx].score = var > k_var_threshold ? score : 0; |
619 | 0 | scores[by * num_blocks_w + bx].index = by * num_blocks_w + bx; |
620 | | #ifdef NOISE_MODEL_LOG_SCORE |
621 | | SVT_ERROR("%g %g %g %g %g %d ", score, var, ratio, trace, norm, is_flat); |
622 | | #endif |
623 | 0 | num_flat += is_flat; |
624 | 0 | } |
625 | 0 | } |
626 | | #ifdef NOISE_MODEL_LOG_SCORE |
627 | | SVT_ERROR("\n"); |
628 | | #endif |
629 | 0 | } |
630 | | #ifdef NOISE_MODEL_LOG_SCORE |
631 | | SVT_ERROR("];\n"); |
632 | | #endif |
633 | | // Find the top-scored blocks (most likely to be flat) and set the flat blocks |
634 | | // be the union of the thresholded results and the top 10th percentile of the |
635 | | // scored results. |
636 | 0 | qsort(scores, num_blocks_w * num_blocks_h, sizeof(*scores), &compare_scores); |
637 | 0 | const int32_t top_nth_percentile = num_blocks_w * num_blocks_h * 90 / 100; |
638 | 0 | const float score_threshold = scores[top_nth_percentile].score; |
639 | 0 | for (int32_t i = 0; i < num_blocks_w * num_blocks_h; ++i) { |
640 | 0 | if (scores[i].score >= score_threshold) { |
641 | 0 | num_flat += flat_blocks[scores[i].index] == 0; |
642 | 0 | flat_blocks[scores[i].index] |= 1; |
643 | 0 | } |
644 | 0 | } |
645 | 0 | free(block); |
646 | 0 | free(plane); |
647 | 0 | free(scores); |
648 | 0 | return num_flat; |
649 | 0 | } |
650 | | |
651 | 0 | int32_t svt_aom_noise_model_init(AomNoiseModel* model, const AomNoiseModelParams params) { |
652 | 0 | const int32_t n = num_coeffs(params); |
653 | 0 | const int32_t lag = params.lag; |
654 | 0 | const int32_t bit_depth = params.bit_depth; |
655 | 0 | int32_t i = 0; |
656 | |
|
657 | 0 | memset(model, 0, sizeof(*model)); |
658 | 0 | if (params.lag < 1) { |
659 | 0 | SVT_ERROR("Invalid noise param: lag = %d must be >= 1\n", params.lag); |
660 | 0 | return 0; |
661 | 0 | } |
662 | 0 | if (params.lag > k_max_lag) { |
663 | 0 | SVT_ERROR("Invalid noise param: lag = %d must be <= %d\n", params.lag, k_max_lag); |
664 | 0 | return 0; |
665 | 0 | } |
666 | 0 | if (svt_memcpy != NULL) { |
667 | 0 | svt_memcpy(&model->params, ¶ms, sizeof(params)); |
668 | 0 | } else { |
669 | 0 | svt_memcpy_c(&model->params, ¶ms, sizeof(params)); |
670 | 0 | } |
671 | |
|
672 | 0 | for (int c = 0; c < 3; ++c) { |
673 | 0 | if (!noise_state_init(&model->combined_state[c], n + (c > 0), bit_depth)) { |
674 | 0 | SVT_ERROR("Failed to allocate noise state for channel %d\n", c); |
675 | 0 | svt_aom_noise_model_free(model); |
676 | 0 | return 0; |
677 | 0 | } |
678 | 0 | if (!noise_state_init(&model->latest_state[c], n + (c > 0), bit_depth)) { |
679 | 0 | SVT_ERROR("Failed to allocate noise state for channel %d\n", c); |
680 | 0 | svt_aom_noise_model_free(model); |
681 | 0 | return 0; |
682 | 0 | } |
683 | 0 | } |
684 | 0 | model->n = n; |
685 | 0 | model->coords = (int32_t (*)[2])malloc(sizeof(*model->coords) * n); |
686 | 0 | if (!model->coords) { |
687 | 0 | SVT_ERROR("Failed to allocate memory for coords\n"); |
688 | 0 | svt_aom_noise_model_free(model); |
689 | 0 | return 0; |
690 | 0 | } |
691 | 0 | for (int32_t y = -lag; y <= 0; ++y) { |
692 | 0 | const int32_t max_x = y == 0 ? -1 : lag; |
693 | 0 | for (int32_t x = -lag; x <= max_x; ++x) { |
694 | 0 | switch (params.shape) { |
695 | 0 | case AOM_NOISE_SHAPE_DIAMOND: |
696 | 0 | if (abs(x) <= y + lag) { |
697 | 0 | model->coords[i][0] = x; |
698 | 0 | model->coords[i][1] = y; |
699 | 0 | ++i; |
700 | 0 | } |
701 | 0 | break; |
702 | 0 | case AOM_NOISE_SHAPE_SQUARE: |
703 | 0 | model->coords[i][0] = x; |
704 | 0 | model->coords[i][1] = y; |
705 | 0 | ++i; |
706 | 0 | break; |
707 | 0 | default: |
708 | 0 | SVT_ERROR("Invalid shape\n"); |
709 | 0 | svt_aom_noise_model_free(model); |
710 | 0 | return 0; |
711 | 0 | } |
712 | 0 | } |
713 | 0 | } |
714 | 0 | assert(i == n); |
715 | 0 | return 1; |
716 | 0 | } |
717 | | |
718 | 0 | void svt_aom_noise_model_free(AomNoiseModel* model) { |
719 | 0 | int32_t c = 0; |
720 | 0 | if (!model) { |
721 | 0 | return; |
722 | 0 | } |
723 | | |
724 | 0 | free(model->coords); |
725 | 0 | for (c = 0; c < 3; ++c) { |
726 | 0 | equation_system_free(&model->latest_state[c].eqns); |
727 | 0 | equation_system_free(&model->combined_state[c].eqns); |
728 | |
|
729 | 0 | equation_system_free(&model->latest_state[c].strength_solver.eqns); |
730 | 0 | equation_system_free(&model->combined_state[c].strength_solver.eqns); |
731 | 0 | } |
732 | 0 | memset(model, 0, sizeof(*model)); |
733 | 0 | } |
734 | | |
735 | | // Extracts the neighborhood defined by coords around point (x, y) from |
736 | | // the difference between the data and denoised images. Also extracts the |
737 | | // entry (possibly downsampled) for (x, y) in the alt_data (e.g., luma). |
738 | | #define EXTRACT_AR_ROW(INT_TYPE, suffix) \ |
739 | | static double extract_ar_row_##suffix(int32_t (*coords)[2], \ |
740 | | int32_t num_coords, \ |
741 | | const INT_TYPE* const data, \ |
742 | | const INT_TYPE* const denoised, \ |
743 | | int32_t stride, \ |
744 | | const int32_t sub_log2[2], \ |
745 | | const INT_TYPE* const alt_data, \ |
746 | | const INT_TYPE* const alt_denoised, \ |
747 | | int32_t alt_stride, \ |
748 | | int32_t x, \ |
749 | | int32_t y, \ |
750 | | double* buffer) { \ |
751 | | for (int32_t i = 0; i < num_coords; ++i) { \ |
752 | | const int32_t x_i = x + coords[i][0], y_i = y + coords[i][1]; \ |
753 | | buffer[i] = (double)data[y_i * stride + x_i] - denoised[y_i * stride + x_i]; \ |
754 | | } \ |
755 | | const double val = (double)data[y * stride + x] - denoised[y * stride + x]; \ |
756 | | \ |
757 | | if (alt_data && alt_denoised) { \ |
758 | | double avg_data = 0, avg_denoised = 0; \ |
759 | | int32_t num_samples = 0; \ |
760 | | for (int32_t dy_i = 0; dy_i < (1 << sub_log2[1]); dy_i++) { \ |
761 | | const int32_t y_up = (y << sub_log2[1]) + dy_i; \ |
762 | | for (int32_t dx_i = 0; dx_i < (1 << sub_log2[0]); dx_i++) { \ |
763 | | const int32_t x_up = (x << sub_log2[0]) + dx_i; \ |
764 | | avg_data += alt_data[y_up * alt_stride + x_up]; \ |
765 | | avg_denoised += alt_denoised[y_up * alt_stride + x_up]; \ |
766 | | num_samples++; \ |
767 | | } \ |
768 | | } \ |
769 | | assert(num_samples > 0); \ |
770 | | buffer[num_coords] = (avg_data - avg_denoised) / num_samples; \ |
771 | | } \ |
772 | | return val; \ |
773 | | } |
774 | | |
775 | | EXTRACT_AR_ROW(uint8_t, lowbd); |
776 | | EXTRACT_AR_ROW(uint16_t, highbd); |
777 | | |
778 | | void svt_av1_add_block_observations_internal_c(uint32_t n, const double val, const double recp_sqr_norm, double* buffer, |
779 | 0 | double* buffer_norm, double* b, double* A) { |
780 | 0 | uint32_t i; |
781 | 0 | for (i = 0; i + 8 - 1 < n; i += 8) { |
782 | 0 | buffer_norm[i + 0] = buffer[i + 0] * recp_sqr_norm; |
783 | 0 | buffer_norm[i + 1] = buffer[i + 1] * recp_sqr_norm; |
784 | 0 | buffer_norm[i + 2] = buffer[i + 2] * recp_sqr_norm; |
785 | 0 | buffer_norm[i + 3] = buffer[i + 3] * recp_sqr_norm; |
786 | 0 | buffer_norm[i + 4] = buffer[i + 4] * recp_sqr_norm; |
787 | 0 | buffer_norm[i + 5] = buffer[i + 5] * recp_sqr_norm; |
788 | 0 | buffer_norm[i + 6] = buffer[i + 6] * recp_sqr_norm; |
789 | 0 | buffer_norm[i + 7] = buffer[i + 7] * recp_sqr_norm; |
790 | 0 | b[i + 0] += buffer_norm[i + 0] * val; |
791 | 0 | b[i + 1] += buffer_norm[i + 1] * val; |
792 | 0 | b[i + 2] += buffer_norm[i + 2] * val; |
793 | 0 | b[i + 3] += buffer_norm[i + 3] * val; |
794 | 0 | b[i + 4] += buffer_norm[i + 4] * val; |
795 | 0 | b[i + 5] += buffer_norm[i + 5] * val; |
796 | 0 | b[i + 6] += buffer_norm[i + 6] * val; |
797 | 0 | b[i + 7] += buffer_norm[i + 7] * val; |
798 | 0 | } |
799 | 0 | for (; i < n; ++i) { |
800 | 0 | buffer_norm[i] = buffer[i] * recp_sqr_norm; |
801 | 0 | b[i] += buffer_norm[i] * val; |
802 | 0 | } |
803 | |
|
804 | 0 | for (i = 0; i < n; ++i) { |
805 | 0 | uint32_t j = 0; |
806 | 0 | const double buffer_norm_i = buffer_norm[i]; |
807 | |
|
808 | 0 | for (j = 0; j + 8 - 1 < n; j += 8) { |
809 | 0 | A[i * n + j + 0] += (buffer_norm_i * buffer[j + 0]); |
810 | 0 | A[i * n + j + 1] += (buffer_norm_i * buffer[j + 1]); |
811 | 0 | A[i * n + j + 2] += (buffer_norm_i * buffer[j + 2]); |
812 | 0 | A[i * n + j + 3] += (buffer_norm_i * buffer[j + 3]); |
813 | 0 | A[i * n + j + 4] += (buffer_norm_i * buffer[j + 4]); |
814 | 0 | A[i * n + j + 5] += (buffer_norm_i * buffer[j + 5]); |
815 | 0 | A[i * n + j + 6] += (buffer_norm_i * buffer[j + 6]); |
816 | 0 | A[i * n + j + 7] += (buffer_norm_i * buffer[j + 7]); |
817 | 0 | } |
818 | 0 | for (; j < n; ++j) { |
819 | 0 | A[i * n + j] += (buffer_norm_i * buffer[j]); |
820 | 0 | } |
821 | 0 | } |
822 | 0 | } |
823 | | |
824 | | static int32_t add_block_observations(AomNoiseModel* noise_model, int32_t c, const uint8_t* const data, |
825 | | const uint8_t* const denoised, int32_t w, int32_t h, int32_t stride, |
826 | | int32_t sub_log2[2], const uint8_t* const alt_data, |
827 | | const uint8_t* const alt_denoised, int32_t alt_stride, |
828 | | const uint8_t* const flat_blocks, int32_t block_size, int32_t num_blocks_w, |
829 | | int32_t num_blocks_h) { |
830 | | const int32_t lag = noise_model->params.lag; |
831 | | const int32_t num_coords = noise_model->n; |
832 | | const double normalization = (1 << noise_model->params.bit_depth) - 1; |
833 | | const double recp_sqr_norm = 1 / (normalization * normalization); |
834 | | double* A = noise_model->latest_state[c].eqns.A; |
835 | | double* b = noise_model->latest_state[c].eqns.b; |
836 | | const int32_t n = noise_model->latest_state[c].eqns.n; |
837 | | double* buffer; |
838 | | double* buffer_norm; |
839 | | |
840 | | EB_MALLOC_ALIGNED(buffer, sizeof(*buffer) * (num_coords + 1)); |
841 | | |
842 | | if (!buffer) { |
843 | | SVT_ERROR("Unable to allocate buffer of size %d\n", sizeof(*buffer) * (num_coords + 1)); |
844 | | return 0; |
845 | | } |
846 | | |
847 | | EB_MALLOC_ALIGNED(buffer_norm, sizeof(*buffer_norm) * (n)); |
848 | | |
849 | | if (!buffer_norm) { |
850 | | EB_FREE_ALIGNED(buffer); |
851 | | SVT_ERROR("Unable to allocate buffer of size %d\n", sizeof(*buffer_norm) * (n)); |
852 | | return 0; |
853 | | } |
854 | | |
855 | | for (int32_t by = 0; by < num_blocks_h; ++by) { |
856 | | const int32_t y_o = by * (block_size >> sub_log2[1]); |
857 | | for (int32_t bx = 0; bx < num_blocks_w; ++bx) { |
858 | | const int32_t x_o = bx * (block_size >> sub_log2[0]); |
859 | | if (!flat_blocks[by * num_blocks_w + bx]) { |
860 | | continue; |
861 | | } |
862 | | int32_t y_start = (by > 0 && flat_blocks[(by - 1) * num_blocks_w + bx]) ? 0 : lag; |
863 | | int32_t x_start = (bx > 0 && flat_blocks[by * num_blocks_w + bx - 1]) ? 0 : lag; |
864 | | int32_t y_end = AOMMIN((h >> sub_log2[1]) - by * (block_size >> sub_log2[1]), block_size >> sub_log2[1]); |
865 | | int32_t x_end = AOMMIN((w >> sub_log2[0]) - bx * (block_size >> sub_log2[0]) - lag, |
866 | | (bx + 1 < num_blocks_w && flat_blocks[by * num_blocks_w + bx + 1]) |
867 | | ? (block_size >> sub_log2[0]) |
868 | | : ((block_size >> sub_log2[0]) - lag)); |
869 | | for (int32_t y = y_start; y < y_end; ++y) { |
870 | | for (int32_t x = x_start; x < x_end; ++x) { |
871 | | const double val = noise_model->params.use_highbd |
872 | | ? extract_ar_row_highbd(noise_model->coords, |
873 | | num_coords, |
874 | | (const uint16_t* const)data, |
875 | | (const uint16_t* const)denoised, |
876 | | stride, |
877 | | sub_log2, |
878 | | (const uint16_t* const)alt_data, |
879 | | (const uint16_t* const)alt_denoised, |
880 | | alt_stride, |
881 | | x + x_o, |
882 | | y + y_o, |
883 | | buffer) |
884 | | : extract_ar_row_lowbd(noise_model->coords, |
885 | | num_coords, |
886 | | data, |
887 | | denoised, |
888 | | stride, |
889 | | sub_log2, |
890 | | alt_data, |
891 | | alt_denoised, |
892 | | alt_stride, |
893 | | x + x_o, |
894 | | y + y_o, |
895 | | buffer); |
896 | | |
897 | | svt_av1_add_block_observations_internal(n, val, recp_sqr_norm, buffer, buffer_norm, b, A); |
898 | | } |
899 | | } |
900 | | //There is situation when x_start is greater than x_end, |
901 | | //use max() to cap negative result and do not increment num_observations |
902 | | noise_model->latest_state[c].num_observations += AOMMAX((y_end - y_start), 0) * |
903 | | AOMMAX((x_end - x_start), 0); |
904 | | } |
905 | | } |
906 | | EB_FREE_ALIGNED(buffer); |
907 | | EB_FREE_ALIGNED(buffer_norm); |
908 | | return 1; |
909 | | } |
910 | | |
911 | | static void add_noise_std_observations(AomNoiseModel* noise_model, int32_t c, const double* coeffs, |
912 | | const uint8_t* const data, const uint8_t* const denoised, int32_t w, int32_t h, |
913 | | int32_t stride, const int32_t sub_log2[2], const uint8_t* const alt_data, |
914 | | int32_t alt_stride, const uint8_t* const flat_blocks, int32_t block_size, |
915 | | int32_t num_blocks_w, int32_t num_blocks_h) { |
916 | | const int32_t num_coords = noise_model->n; |
917 | | AomNoiseStrengthSolver* noise_strength_solver = &noise_model->latest_state[c].strength_solver; |
918 | | |
919 | | const AomNoiseStrengthSolver* noise_strength_luma = &noise_model->latest_state[0].strength_solver; |
920 | | const double luma_gain = noise_model->latest_state[0].ar_gain; |
921 | | const double noise_gain = noise_model->latest_state[c].ar_gain; |
922 | | for (int32_t by = 0; by < num_blocks_h; ++by) { |
923 | | const int32_t y_o = by * (block_size >> sub_log2[1]); |
924 | | for (int32_t bx = 0; bx < num_blocks_w; ++bx) { |
925 | | const int32_t x_o = bx * (block_size >> sub_log2[0]); |
926 | | if (!flat_blocks[by * num_blocks_w + bx]) { |
927 | | continue; |
928 | | } |
929 | | const int32_t num_samples_h = AOMMIN((h >> sub_log2[1]) - by * (block_size >> sub_log2[1]), |
930 | | block_size >> sub_log2[1]); |
931 | | const int32_t num_samples_w = AOMMIN((w >> sub_log2[0]) - bx * (block_size >> sub_log2[0]), |
932 | | (block_size >> sub_log2[0])); |
933 | | // Make sure that we have a reasonable amount of samples to consider the |
934 | | // block |
935 | | if (num_samples_w * num_samples_h > block_size) { |
936 | | const double block_mean = get_block_mean(alt_data ? alt_data : data, |
937 | | w, |
938 | | h, |
939 | | alt_data ? alt_stride : stride, |
940 | | x_o << sub_log2[0], |
941 | | y_o << sub_log2[1], |
942 | | block_size, |
943 | | noise_model->params.use_highbd); |
944 | | const double noise_var = get_noise_var(data, |
945 | | denoised, |
946 | | stride, |
947 | | w >> sub_log2[0], |
948 | | h >> sub_log2[1], |
949 | | x_o, |
950 | | y_o, |
951 | | block_size >> sub_log2[0], |
952 | | block_size >> sub_log2[1], |
953 | | noise_model->params.use_highbd); |
954 | | // We want to remove the part of the noise that came from being |
955 | | // correlated with luma. Note that the noise solver for luma must |
956 | | // have already been run. |
957 | | const double luma_strength = c > 0 |
958 | | ? luma_gain * noise_strength_solver_get_value(noise_strength_luma, block_mean) |
959 | | : 0; |
960 | | const double corr = c > 0 ? coeffs[num_coords] : 0; |
961 | | // Chroma noise: |
962 | | // N(0, noise_var) = N(0, uncorr_var) + corr * N(0, luma_strength^2) |
963 | | // The uncorrelated component: |
964 | | // uncorr_var = noise_var - (corr * luma_strength)^2 |
965 | | // But don't allow fully correlated noise (hence the max), since the |
966 | | // synthesis cannot model it. |
967 | | const double uncorr_std = sqrt(AOMMAX(noise_var / 16, noise_var - pow(corr * luma_strength, 2))); |
968 | | // After we've removed correlation with luma, undo the gain that will |
969 | | // come from running the IIR filter. |
970 | | const double adjusted_strength = uncorr_std / noise_gain; |
971 | | svt_aom_noise_strength_solver_add_measurement(noise_strength_solver, block_mean, adjusted_strength); |
972 | | } |
973 | | } |
974 | | } |
975 | | } |
976 | | |
977 | | static int32_t ar_equation_system_solve(AomNoiseState* state, int32_t is_chroma) { |
978 | | const int32_t ret = equation_system_solve(&state->eqns); |
979 | | state->ar_gain = 1.0; |
980 | | if (!ret) { |
981 | | return ret; |
982 | | } |
983 | | |
984 | | // Update the AR gain from the equation system as it will be used to fit |
985 | | // the noise strength as a function of intensity. In the Yule-Walker |
986 | | // equations, the diagonal should be the variance of the correlated noise. |
987 | | // In the case of the least squares estimate, there will be some variability |
988 | | // in the diagonal. So use the mean of the diagonal as the estimate of |
989 | | // overall variance (this works for least squares or Yule-Walker formulation). |
990 | | double var = 0; |
991 | | const int32_t n = state->eqns.n; |
992 | | for (int32_t i = 0; i < (state->eqns.n - is_chroma); ++i) { |
993 | | var += state->eqns.A[i * n + i] / state->num_observations; |
994 | | } |
995 | | var /= (n - is_chroma); |
996 | | |
997 | | // Keep track of E(Y^2) = <b, x> + E(X^2) |
998 | | // In the case that we are using chroma and have an estimate of correlation |
999 | | // with luma we adjust that estimate slightly to remove the correlated bits by |
1000 | | // subtracting out the last column of a scaled by our correlation estimate |
1001 | | // from b. E(y^2) = <b - A(:, end)*x(end), x> |
1002 | | double sum_covar = 0; |
1003 | | for (int32_t i = 0; i < state->eqns.n - is_chroma; ++i) { |
1004 | | double bi = state->eqns.b[i]; |
1005 | | if (is_chroma) { |
1006 | | bi -= state->eqns.A[i * n + (n - 1)] * state->eqns.x[n - 1]; |
1007 | | } |
1008 | | sum_covar += (bi * state->eqns.x[i]) / state->num_observations; |
1009 | | } |
1010 | | // Now, get an estimate of the variance of uncorrelated noise signal and use |
1011 | | // it to determine the gain of the AR filter. |
1012 | | const double noise_var = AOMMAX(var - sum_covar, 1e-6); |
1013 | | state->ar_gain = AOMMAX(1, sqrt(AOMMAX(var / noise_var, 1e-6))); |
1014 | | return ret; |
1015 | | } |
1016 | | |
1017 | | /*!\brief Updates the noise model with a new frame observation. |
1018 | | * |
1019 | | * Updates the noise model with measurements from the given input frame and a |
1020 | | * denoised variant of it. Noise is sampled from flat blocks using the flat |
1021 | | * block map. |
1022 | | * |
1023 | | * Returns a noise_status indicating if the update was successful. If the |
1024 | | * Update was successful, the combined_state is updated with measurements from |
1025 | | * the provided frame. If status is OK or DIFFERENT_NOISE_TYPE, the latest noise |
1026 | | * state will be updated with measurements from the provided frame. |
1027 | | * |
1028 | | * \param[in,out] noise_model The noise model to be updated |
1029 | | * \param[in] data Raw frame data |
1030 | | * \param[in] denoised Denoised frame data. |
1031 | | * \param[in] w Frame width |
1032 | | * \param[in] h Frame height |
1033 | | * \param[in] strides Stride of the planes |
1034 | | * \param[in] chroma_sub_log2 Chroma subsampling for planes != 0. |
1035 | | * \param[in] flat_blocks A map to blocks that have been determined flat |
1036 | | * \param[in] block_size The size of blocks. |
1037 | | */ |
1038 | | static AomNoiseStatus noise_model_update(AomNoiseModel* const noise_model, const uint8_t* const data[3], |
1039 | | const uint8_t* const denoised[3], int32_t w, int32_t h, |
1040 | | const int32_t stride[3], int32_t chroma_sub_log2[2], |
1041 | 0 | const uint8_t* const flat_blocks, int32_t block_size) { |
1042 | 0 | const int32_t num_blocks_w = (w + block_size - 1) / block_size; |
1043 | 0 | const int32_t num_blocks_h = (h + block_size - 1) / block_size; |
1044 | | // int32_t y_model_different = 0; |
1045 | 0 | int32_t num_blocks = 0; |
1046 | 0 | int32_t i = 0, channel = 0; |
1047 | |
|
1048 | 0 | if (block_size <= 1) { |
1049 | 0 | SVT_ERROR("BlockSize = %d must be > 1\n", block_size); |
1050 | 0 | return AOM_NOISE_STATUS_INVALID_ARGUMENT; |
1051 | 0 | } |
1052 | | |
1053 | 0 | if (block_size < noise_model->params.lag * 2 + 1) { |
1054 | 0 | SVT_ERROR("BlockSize = %d must be >= %d\n", block_size, noise_model->params.lag * 2 + 1); |
1055 | 0 | return AOM_NOISE_STATUS_INVALID_ARGUMENT; |
1056 | 0 | } |
1057 | | |
1058 | | // Clear the latest equation system |
1059 | 0 | for (i = 0; i < 3; ++i) { |
1060 | 0 | equation_system_clear(&noise_model->latest_state[i].eqns); |
1061 | 0 | noise_model->latest_state[i].num_observations = 0; |
1062 | 0 | noise_strength_solver_clear(&noise_model->latest_state[i].strength_solver); |
1063 | 0 | } |
1064 | | |
1065 | | // Check that we have enough flat blocks |
1066 | 0 | for (i = 0; i < num_blocks_h * num_blocks_w; ++i) { |
1067 | 0 | if (flat_blocks[i]) { |
1068 | 0 | num_blocks++; |
1069 | 0 | } |
1070 | 0 | } |
1071 | |
|
1072 | 0 | if (num_blocks <= 1) { |
1073 | 0 | SVT_ERROR("Not enough flat blocks to update noise estimate\n"); |
1074 | 0 | return AOM_NOISE_STATUS_INSUFFICIENT_FLAT_BLOCKS; |
1075 | 0 | } |
1076 | | |
1077 | 0 | for (channel = 0; channel < 3; ++channel) { |
1078 | 0 | int32_t no_subsampling[2] = {0, 0}; |
1079 | 0 | const uint8_t* alt_data = channel > 0 ? data[0] : 0; |
1080 | 0 | const uint8_t* alt_denoised = channel > 0 ? denoised[0] : 0; |
1081 | 0 | int32_t* sub = channel > 0 ? chroma_sub_log2 : no_subsampling; |
1082 | 0 | const int32_t is_chroma = channel != 0; |
1083 | 0 | if (!data[channel] || !denoised[channel]) { |
1084 | 0 | break; |
1085 | 0 | } |
1086 | 0 | if (!add_block_observations(noise_model, |
1087 | 0 | channel, |
1088 | 0 | data[channel], |
1089 | 0 | denoised[channel], |
1090 | 0 | w, |
1091 | 0 | h, |
1092 | 0 | stride[channel], |
1093 | 0 | sub, |
1094 | 0 | alt_data, |
1095 | 0 | alt_denoised, |
1096 | 0 | stride[0], |
1097 | 0 | flat_blocks, |
1098 | 0 | block_size, |
1099 | 0 | num_blocks_w, |
1100 | 0 | num_blocks_h)) { |
1101 | 0 | SVT_ERROR("Adding block observation failed\n"); |
1102 | 0 | return AOM_NOISE_STATUS_INTERNAL_ERROR; |
1103 | 0 | } |
1104 | | |
1105 | 0 | if (!ar_equation_system_solve(&noise_model->latest_state[channel], is_chroma)) { |
1106 | 0 | if (is_chroma) { |
1107 | 0 | set_chroma_coefficient_fallback_soln(&noise_model->latest_state[channel].eqns); |
1108 | 0 | } else { |
1109 | | //SVT_INFO("Solving latest noise equation system failed %d!\n", channel); |
1110 | 0 | return AOM_NOISE_STATUS_INSUFFICIENT_NOISE_PIXELS; |
1111 | 0 | } |
1112 | 0 | } |
1113 | | |
1114 | 0 | add_noise_std_observations(noise_model, |
1115 | 0 | channel, |
1116 | 0 | noise_model->latest_state[channel].eqns.x, |
1117 | 0 | data[channel], |
1118 | 0 | denoised[channel], |
1119 | 0 | w, |
1120 | 0 | h, |
1121 | 0 | stride[channel], |
1122 | 0 | sub, |
1123 | 0 | alt_data, |
1124 | 0 | stride[0], |
1125 | 0 | flat_blocks, |
1126 | 0 | block_size, |
1127 | 0 | num_blocks_w, |
1128 | 0 | num_blocks_h); |
1129 | |
|
1130 | 0 | if (!svt_aom_noise_strength_solver_solve(&noise_model->latest_state[channel].strength_solver)) { |
1131 | 0 | SVT_ERROR("Solving latest noise strength failed!\n"); |
1132 | 0 | return AOM_NOISE_STATUS_INTERNAL_ERROR; |
1133 | 0 | } |
1134 | | |
1135 | | // Check noise characteristics and return if error. |
1136 | | // if (channel == 0 && |
1137 | | // noise_model->combined_state[channel].strength_solver.num_equations > |
1138 | | // 0 && |
1139 | | // is_noise_model_different(noise_model)) { |
1140 | | // y_model_different = 1; |
1141 | | // } |
1142 | | |
1143 | 0 | noise_model->combined_state[channel].num_observations = noise_model->latest_state[channel].num_observations; |
1144 | 0 | equation_system_copy(&noise_model->combined_state[channel].eqns, &noise_model->latest_state[channel].eqns); |
1145 | 0 | if (!ar_equation_system_solve(&noise_model->combined_state[channel], is_chroma)) { |
1146 | 0 | if (is_chroma) { |
1147 | 0 | set_chroma_coefficient_fallback_soln(&noise_model->combined_state[channel].eqns); |
1148 | 0 | } else { |
1149 | 0 | SVT_ERROR("Solving combined noise equation system failed %d!\n", channel); |
1150 | 0 | return AOM_NOISE_STATUS_INTERNAL_ERROR; |
1151 | 0 | } |
1152 | 0 | } |
1153 | | |
1154 | 0 | noise_strength_solver_copy(&noise_model->combined_state[channel].strength_solver, |
1155 | 0 | &noise_model->latest_state[channel].strength_solver); |
1156 | |
|
1157 | 0 | if (!svt_aom_noise_strength_solver_solve(&noise_model->combined_state[channel].strength_solver)) { |
1158 | 0 | SVT_ERROR("Solving combined noise strength failed!\n"); |
1159 | 0 | return AOM_NOISE_STATUS_INTERNAL_ERROR; |
1160 | 0 | } |
1161 | 0 | } |
1162 | | |
1163 | 0 | return AOM_NOISE_STATUS_OK; |
1164 | 0 | } |
1165 | | |
1166 | 0 | void svt_aom_noise_model_save_latest(AomNoiseModel* noise_model) { |
1167 | 0 | for (int32_t c = 0; c < 3; c++) { |
1168 | 0 | equation_system_copy(&noise_model->combined_state[c].eqns, &noise_model->latest_state[c].eqns); |
1169 | 0 | equation_system_copy(&noise_model->combined_state[c].strength_solver.eqns, |
1170 | 0 | &noise_model->latest_state[c].strength_solver.eqns); |
1171 | 0 | noise_model->combined_state[c].strength_solver.num_equations = |
1172 | 0 | noise_model->latest_state[c].strength_solver.num_equations; |
1173 | 0 | noise_model->combined_state[c].num_observations = noise_model->latest_state[c].num_observations; |
1174 | 0 | noise_model->combined_state[c].ar_gain = noise_model->latest_state[c].ar_gain; |
1175 | 0 | } |
1176 | 0 | } |
1177 | | |
1178 | 0 | int32_t svt_aom_noise_model_get_grain_parameters(AomNoiseModel* const noise_model, AomFilmGrain* film_grain) { |
1179 | 0 | if (noise_model->params.lag > 3) { |
1180 | 0 | SVT_ERROR("params.lag = %d > 3\n", noise_model->params.lag); |
1181 | 0 | return 0; |
1182 | 0 | } |
1183 | 0 | uint16_t random_seed = film_grain->random_seed; |
1184 | 0 | memset(film_grain, 0, sizeof(*film_grain)); |
1185 | 0 | film_grain->random_seed = random_seed; |
1186 | |
|
1187 | 0 | film_grain->apply_grain = 1; |
1188 | 0 | film_grain->update_parameters = 1; |
1189 | 0 | film_grain->ignore_ref = 0; |
1190 | |
|
1191 | 0 | film_grain->ar_coeff_lag = noise_model->params.lag; |
1192 | | |
1193 | | // Convert the scaling functions to 8 bit values |
1194 | 0 | AomNoiseStrengthLut scaling_points[3] = {{.points = NULL, .num_points = 0}}; |
1195 | 0 | svt_aom_noise_strength_solver_fit_piecewise( |
1196 | 0 | &noise_model->combined_state[0].strength_solver, 14, scaling_points + 0); |
1197 | 0 | svt_aom_noise_strength_solver_fit_piecewise( |
1198 | 0 | &noise_model->combined_state[1].strength_solver, 10, scaling_points + 1); |
1199 | 0 | svt_aom_noise_strength_solver_fit_piecewise( |
1200 | 0 | &noise_model->combined_state[2].strength_solver, 10, scaling_points + 2); |
1201 | | |
1202 | | // Both the domain and the range of the scaling functions in the film_grain |
1203 | | // are normalized to 8-bit (e.g., they are implicitly scaled during grain |
1204 | | // synthesis). |
1205 | 0 | const double strength_divisor = 1 << (noise_model->params.bit_depth - 8); |
1206 | 0 | double max_scaling_value = 1e-4; |
1207 | 0 | for (int32_t c = 0; c < 3; ++c) { |
1208 | 0 | for (int32_t i = 0; i < scaling_points[c].num_points; ++i) { |
1209 | 0 | scaling_points[c].points[i][0] = AOMMIN(255, scaling_points[c].points[i][0] / strength_divisor); |
1210 | 0 | scaling_points[c].points[i][1] = AOMMIN(255, scaling_points[c].points[i][1] / strength_divisor); |
1211 | 0 | max_scaling_value = AOMMAX(scaling_points[c].points[i][1], max_scaling_value); |
1212 | 0 | } |
1213 | 0 | } |
1214 | | |
1215 | | // Scaling_shift values are in the range [8,11] |
1216 | 0 | const int32_t max_scaling_value_log2 = clamp((int32_t)floor(log2(max_scaling_value) + 1), 2, 5); |
1217 | 0 | film_grain->scaling_shift = 5 + (8 - max_scaling_value_log2); |
1218 | |
|
1219 | 0 | const double scale_factor = 1 << (8 - max_scaling_value_log2); |
1220 | 0 | film_grain->num_y_points = scaling_points[0].num_points; |
1221 | 0 | film_grain->num_cb_points = scaling_points[1].num_points; |
1222 | 0 | film_grain->num_cr_points = scaling_points[2].num_points; |
1223 | |
|
1224 | 0 | int32_t (*film_grain_scaling[3])[2] = { |
1225 | 0 | film_grain->scaling_points_y, |
1226 | 0 | film_grain->scaling_points_cb, |
1227 | 0 | film_grain->scaling_points_cr, |
1228 | 0 | }; |
1229 | 0 | for (int32_t c = 0; c < 3; c++) { |
1230 | 0 | for (int32_t i = 0; i < scaling_points[c].num_points; ++i) { |
1231 | 0 | film_grain_scaling[c][i][0] = (int32_t)(scaling_points[c].points[i][0] + 0.5); |
1232 | 0 | film_grain_scaling[c][i][1] = clamp((int32_t)(scale_factor * scaling_points[c].points[i][1] + 0.5), 0, 255); |
1233 | 0 | } |
1234 | 0 | } |
1235 | 0 | svt_aom_noise_strength_lut_free(scaling_points + 0); |
1236 | 0 | svt_aom_noise_strength_lut_free(scaling_points + 1); |
1237 | 0 | svt_aom_noise_strength_lut_free(scaling_points + 2); |
1238 | | |
1239 | | // Convert the ar_coeffs into 8-bit values |
1240 | 0 | const int32_t n_coeff = noise_model->combined_state[0].eqns.n; |
1241 | 0 | double max_coeff = 1e-4, min_coeff = -1e-4; |
1242 | 0 | double y_corr[2] = {0, 0}; |
1243 | 0 | double avg_luma_strength = 0; |
1244 | 0 | for (int32_t c = 0; c < 3; c++) { |
1245 | 0 | AomEquationSystem* eqns = &noise_model->combined_state[c].eqns; |
1246 | 0 | for (int32_t i = 0; i < n_coeff; ++i) { |
1247 | 0 | max_coeff = AOMMAX(max_coeff, eqns->x[i]); |
1248 | 0 | min_coeff = AOMMIN(min_coeff, eqns->x[i]); |
1249 | 0 | } |
1250 | | // Since the correlation between luma/chroma was computed in an already |
1251 | | // scaled space, we adjust it in the un-scaled space. |
1252 | 0 | AomNoiseStrengthSolver* solver = &noise_model->combined_state[c].strength_solver; |
1253 | | // Compute a weighted average of the strength for the channel. |
1254 | 0 | double average_strength = 0, total_weight = 0; |
1255 | 0 | for (int32_t i = 0; i < solver->eqns.n; ++i) { |
1256 | 0 | double w = 0; |
1257 | 0 | for (int32_t j = 0; j < solver->eqns.n; ++j) { |
1258 | 0 | w += solver->eqns.A[i * solver->eqns.n + j]; |
1259 | 0 | } |
1260 | 0 | w = sqrt(w); |
1261 | 0 | average_strength += solver->eqns.x[i] * w; |
1262 | 0 | total_weight += w; |
1263 | 0 | } |
1264 | 0 | if (total_weight == 0) { |
1265 | 0 | average_strength = 1; |
1266 | 0 | } else { |
1267 | 0 | average_strength /= total_weight; |
1268 | 0 | } |
1269 | 0 | if (c == 0) { |
1270 | 0 | avg_luma_strength = average_strength; |
1271 | 0 | } else { |
1272 | 0 | y_corr[c - 1] = avg_luma_strength * eqns->x[n_coeff] / average_strength; |
1273 | 0 | max_coeff = AOMMAX(max_coeff, y_corr[c - 1]); |
1274 | 0 | min_coeff = AOMMIN(min_coeff, y_corr[c - 1]); |
1275 | 0 | } |
1276 | 0 | } |
1277 | | // Shift value: AR coeffs range (values 6-9) |
1278 | | // 6: [-2, 2), 7: [-1, 1), 8: [-0.5, 0.5), 9: [-0.25, 0.25) |
1279 | 0 | film_grain->ar_coeff_shift = clamp(7 - (int32_t)AOMMAX(1 + floor(log2(max_coeff)), ceil(log2(-min_coeff))), 6, 9); |
1280 | 0 | double scale_ar_coeff = 1 << film_grain->ar_coeff_shift; |
1281 | 0 | int32_t* ar_coeffs[3] = { |
1282 | 0 | film_grain->ar_coeffs_y, |
1283 | 0 | film_grain->ar_coeffs_cb, |
1284 | 0 | film_grain->ar_coeffs_cr, |
1285 | 0 | }; |
1286 | 0 | for (int32_t c = 0; c < 3; ++c) { |
1287 | 0 | AomEquationSystem* eqns = &noise_model->combined_state[c].eqns; |
1288 | 0 | for (int32_t i = 0; i < n_coeff; ++i) { |
1289 | 0 | ar_coeffs[c][i] = clamp((int32_t)round(scale_ar_coeff * eqns->x[i]), -128, 127); |
1290 | 0 | } |
1291 | 0 | if (c > 0) { |
1292 | 0 | ar_coeffs[c][n_coeff] = clamp((int32_t)round(scale_ar_coeff * y_corr[c - 1]), -128, 127); |
1293 | 0 | } |
1294 | 0 | } |
1295 | | |
1296 | | // At the moment, the noise modeling code assumes that the chroma scaling |
1297 | | // functions are a function of luma. |
1298 | 0 | film_grain->cb_mult = 128; // 8 bits |
1299 | 0 | film_grain->cb_luma_mult = 192; // 8 bits |
1300 | 0 | film_grain->cb_offset = 256; // 9 bits |
1301 | |
|
1302 | 0 | film_grain->cr_mult = 128; // 8 bits |
1303 | 0 | film_grain->cr_luma_mult = 192; // 8 bits |
1304 | 0 | film_grain->cr_offset = 256; // 9 bits |
1305 | |
|
1306 | 0 | film_grain->chroma_scaling_from_luma = 0; |
1307 | 0 | film_grain->grain_scale_shift = 0; |
1308 | 0 | film_grain->overlap_flag = 1; |
1309 | 0 | return 1; |
1310 | 0 | } |
1311 | | |
1312 | 0 | void svt_av1_pointwise_multiply_c(const float* a, float* b, float* c, double* b_d, double* c_d, int32_t n) { |
1313 | 0 | for (int32_t i = 0; i < n; i++) { |
1314 | 0 | b[i] = a[i] * (float)b_d[i]; |
1315 | 0 | c[i] = a[i] * (float)c_d[i]; |
1316 | 0 | } |
1317 | 0 | } |
1318 | | |
1319 | | //window_function[y * block_size + x] = (float)(cos((.5 + y) * PI / block_size - PI / 2) * cos((.5 + x) * PI / block_size - PI / 2)); |
1320 | | static const float window_function_half_cos_window_2[4] = { |
1321 | | 0.500000f, |
1322 | | 0.500000f, |
1323 | | 0.500000f, |
1324 | | 0.500000f, |
1325 | | }; |
1326 | | static const float window_function_half_cos_window_4[16] = { |
1327 | | 0.14644662f, |
1328 | | 0.35355338f, |
1329 | | 0.35355338f, |
1330 | | 0.14644662f, |
1331 | | 0.35355338f, |
1332 | | 0.85355341f, |
1333 | | 0.85355341f, |
1334 | | 0.35355338f, |
1335 | | 0.35355338f, |
1336 | | 0.85355341f, |
1337 | | 0.85355341f, |
1338 | | 0.35355338f, |
1339 | | 0.14644662f, |
1340 | | 0.35355338f, |
1341 | | 0.35355338f, |
1342 | | 0.14644662f, |
1343 | | }; |
1344 | | static const float window_function_half_cos_window_8[64] = { |
1345 | | 0.03806023f, 0.10838638f, 0.16221167f, 0.19134171f, 0.19134171f, 0.16221167f, 0.10838638f, 0.03806023f, |
1346 | | 0.10838638f, 0.30865827f, 0.46193975f, 0.54489511f, 0.54489511f, 0.46193975f, 0.30865827f, 0.10838638f, |
1347 | | 0.16221167f, 0.46193975f, 0.69134170f, 0.81549317f, 0.81549317f, 0.69134170f, 0.46193975f, 0.16221167f, |
1348 | | 0.19134171f, 0.54489511f, 0.81549317f, 0.96193975f, 0.96193975f, 0.81549317f, 0.54489511f, 0.19134171f, |
1349 | | 0.19134171f, 0.54489511f, 0.81549317f, 0.96193975f, 0.96193975f, 0.81549317f, 0.54489511f, 0.19134171f, |
1350 | | 0.16221167f, 0.46193975f, 0.69134170f, 0.81549317f, 0.81549317f, 0.69134170f, 0.46193975f, 0.16221167f, |
1351 | | 0.10838638f, 0.30865827f, 0.46193975f, 0.54489511f, 0.54489511f, 0.46193975f, 0.30865827f, 0.10838638f, |
1352 | | 0.03806023f, 0.10838638f, 0.16221167f, 0.19134171f, 0.19134171f, 0.16221167f, 0.10838638f, 0.03806023f, |
1353 | | }; |
1354 | | static const float window_function_half_cos_window_16[256] = { |
1355 | | 0.00960736f, 0.02845287f, 0.04620496f, 0.06218142f, 0.07576828f, 0.08644340f, 0.09379656f, 0.09754516f, 0.09754516f, |
1356 | | 0.09379656f, 0.08644340f, 0.07576828f, 0.06218142f, 0.04620496f, 0.02845287f, 0.00960736f, 0.02845287f, 0.08426519f, |
1357 | | 0.13683926f, 0.18415464f, 0.22439308f, 0.25600824f, 0.27778512f, 0.28888687f, 0.28888687f, 0.27778512f, 0.25600824f, |
1358 | | 0.22439308f, 0.18415464f, 0.13683926f, 0.08426519f, 0.02845287f, 0.04620496f, 0.13683926f, 0.22221488f, 0.29905093f, |
1359 | | 0.36439461f, 0.41573480f, 0.45109856f, 0.46912682f, 0.46912682f, 0.45109856f, 0.41573480f, 0.36439461f, 0.29905093f, |
1360 | | 0.22221488f, 0.13683926f, 0.04620496f, 0.06218142f, 0.18415464f, 0.29905093f, 0.40245485f, 0.49039263f, 0.55948490f, |
1361 | | 0.60707653f, 0.63133854f, 0.63133854f, 0.60707653f, 0.55948490f, 0.49039263f, 0.40245485f, 0.29905093f, 0.18415464f, |
1362 | | 0.06218142f, 0.07576828f, 0.22439308f, 0.36439461f, 0.49039263f, 0.59754515f, 0.68173438f, 0.73972487f, 0.76928818f, |
1363 | | 0.76928818f, 0.73972487f, 0.68173438f, 0.59754515f, 0.49039263f, 0.36439461f, 0.22439308f, 0.07576828f, 0.08644340f, |
1364 | | 0.25600824f, 0.41573480f, 0.55948490f, 0.68173438f, 0.77778512f, 0.84394604f, 0.87767458f, 0.87767458f, 0.84394604f, |
1365 | | 0.77778512f, 0.68173438f, 0.55948490f, 0.41573480f, 0.25600824f, 0.08644340f, 0.09379656f, 0.27778512f, 0.45109856f, |
1366 | | 0.60707653f, 0.73972487f, 0.84394604f, 0.91573483f, 0.95233238f, 0.95233238f, 0.91573483f, 0.84394604f, 0.73972487f, |
1367 | | 0.60707653f, 0.45109856f, 0.27778512f, 0.09379656f, 0.09754516f, 0.28888687f, 0.46912682f, 0.63133854f, 0.76928818f, |
1368 | | 0.87767458f, 0.95233238f, 0.99039263f, 0.99039263f, 0.95233238f, 0.87767458f, 0.76928818f, 0.63133854f, 0.46912682f, |
1369 | | 0.28888687f, 0.09754516f, 0.09754516f, 0.28888687f, 0.46912682f, 0.63133854f, 0.76928818f, 0.87767458f, 0.95233238f, |
1370 | | 0.99039263f, 0.99039263f, 0.95233238f, 0.87767458f, 0.76928818f, 0.63133854f, 0.46912682f, 0.28888687f, 0.09754516f, |
1371 | | 0.09379656f, 0.27778512f, 0.45109856f, 0.60707653f, 0.73972487f, 0.84394604f, 0.91573483f, 0.95233238f, 0.95233238f, |
1372 | | 0.91573483f, 0.84394604f, 0.73972487f, 0.60707653f, 0.45109856f, 0.27778512f, 0.09379656f, 0.08644340f, 0.25600824f, |
1373 | | 0.41573480f, 0.55948490f, 0.68173438f, 0.77778512f, 0.84394604f, 0.87767458f, 0.87767458f, 0.84394604f, 0.77778512f, |
1374 | | 0.68173438f, 0.55948490f, 0.41573480f, 0.25600824f, 0.08644340f, 0.07576828f, 0.22439308f, 0.36439461f, 0.49039263f, |
1375 | | 0.59754515f, 0.68173438f, 0.73972487f, 0.76928818f, 0.76928818f, 0.73972487f, 0.68173438f, 0.59754515f, 0.49039263f, |
1376 | | 0.36439461f, 0.22439308f, 0.07576828f, 0.06218142f, 0.18415464f, 0.29905093f, 0.40245485f, 0.49039263f, 0.55948490f, |
1377 | | 0.60707653f, 0.63133854f, 0.63133854f, 0.60707653f, 0.55948490f, 0.49039263f, 0.40245485f, 0.29905093f, 0.18415464f, |
1378 | | 0.06218142f, 0.04620496f, 0.13683926f, 0.22221488f, 0.29905093f, 0.36439461f, 0.41573480f, 0.45109856f, 0.46912682f, |
1379 | | 0.46912682f, 0.45109856f, 0.41573480f, 0.36439461f, 0.29905093f, 0.22221488f, 0.13683926f, 0.04620496f, 0.02845287f, |
1380 | | 0.08426519f, 0.13683926f, 0.18415464f, 0.22439308f, 0.25600824f, 0.27778512f, 0.28888687f, 0.28888687f, 0.27778512f, |
1381 | | 0.25600824f, 0.22439308f, 0.18415464f, 0.13683926f, 0.08426519f, 0.02845287f, 0.00960736f, 0.02845287f, 0.04620496f, |
1382 | | 0.06218142f, 0.07576828f, 0.08644340f, 0.09379656f, 0.09754516f, 0.09754516f, 0.09379656f, 0.08644340f, 0.07576828f, |
1383 | | 0.06218142f, 0.04620496f, 0.02845287f, 0.00960736f, |
1384 | | }; |
1385 | | static const float window_function_half_cos_window_32[1024] = { |
1386 | | 0.00240764f, 0.00719972f, 0.01192247f, 0.01653040f, 0.02097913f, 0.02522583f, 0.02922958f, 0.03295184f, 0.03635675f, |
1387 | | 0.03941153f, 0.04208675f, 0.04435665f, 0.04619938f, 0.04759718f, 0.04853659f, 0.04900857f, 0.04900857f, 0.04853659f, |
1388 | | 0.04759718f, 0.04619938f, 0.04435665f, 0.04208675f, 0.03941153f, 0.03635675f, 0.03295184f, 0.02922958f, 0.02522583f, |
1389 | | 0.02097913f, 0.01653040f, 0.01192247f, 0.00719972f, 0.00240764f, 0.00719972f, 0.02152983f, 0.03565260f, 0.04943201f, |
1390 | | 0.06273536f, 0.07543454f, 0.08740724f, 0.09853817f, 0.10872011f, 0.11785502f, 0.12585492f, 0.13264278f, 0.13815321f, |
1391 | | 0.14233315f, 0.14514233f, 0.14655373f, 0.14655373f, 0.14514233f, 0.14233315f, 0.13815321f, 0.13264278f, 0.12585492f, |
1392 | | 0.11785502f, 0.10872011f, 0.09853817f, 0.08740724f, 0.07543454f, 0.06273536f, 0.04943201f, 0.03565260f, 0.02152983f, |
1393 | | 0.00719972f, 0.01192247f, 0.03565260f, 0.05903937f, 0.08185755f, 0.10388742f, 0.12491678f, 0.14474313f, 0.16317551f, |
1394 | | 0.18003644f, 0.19516350f, 0.20841105f, 0.21965148f, 0.22877654f, 0.23569837f, 0.24035029f, 0.24268749f, 0.24268749f, |
1395 | | 0.24035029f, 0.23569837f, 0.22877654f, 0.21965148f, 0.20841105f, 0.19516350f, 0.18003644f, 0.16317551f, 0.14474313f, |
1396 | | 0.12491678f, 0.10388742f, 0.08185755f, 0.05903937f, 0.03565260f, 0.01192247f, 0.01653040f, 0.04943201f, 0.08185755f, |
1397 | | 0.11349478f, 0.14403898f, 0.17319600f, 0.20068505f, 0.22624139f, 0.24961892f, 0.27059248f, 0.28896007f, 0.30454481f, |
1398 | | 0.31719664f, 0.32679370f, 0.33324352f, 0.33648404f, 0.33648404f, 0.33324352f, 0.32679370f, 0.31719664f, 0.30454481f, |
1399 | | 0.28896007f, 0.27059248f, 0.24961892f, 0.22624139f, 0.20068505f, 0.17319600f, 0.14403898f, 0.11349478f, 0.08185755f, |
1400 | | 0.04943201f, 0.01653040f, 0.02097913f, 0.06273536f, 0.10388742f, 0.14403898f, 0.18280336f, 0.21980725f, 0.25469428f, |
1401 | | 0.28712845f, 0.31679744f, 0.34341547f, 0.36672625f, 0.38650522f, 0.40256196f, 0.41474181f, 0.42292747f, 0.42704007f, |
1402 | | 0.42704007f, 0.42292747f, 0.41474181f, 0.40256196f, 0.38650522f, 0.36672625f, 0.34341547f, 0.31679744f, 0.28712845f, |
1403 | | 0.25469428f, 0.21980725f, 0.18280336f, 0.14403898f, 0.10388742f, 0.06273536f, 0.02097913f, 0.02522583f, 0.07543454f, |
1404 | | 0.12491678f, 0.17319600f, 0.21980725f, 0.26430163f, 0.30625066f, 0.34525031f, 0.38092500f, 0.41293120f, 0.44096065f, |
1405 | | 0.46474338f, 0.48405039f, 0.49869573f, 0.50853837f, 0.51348346f, 0.51348346f, 0.50853837f, 0.49869573f, 0.48405039f, |
1406 | | 0.46474338f, 0.44096065f, 0.41293120f, 0.38092500f, 0.34525031f, 0.30625066f, 0.26430163f, 0.21980725f, 0.17319600f, |
1407 | | 0.12491678f, 0.07543454f, 0.02522583f, 0.02922958f, 0.08740724f, 0.14474313f, 0.20068505f, 0.25469428f, 0.30625066f, |
1408 | | 0.35485765f, 0.40004721f, 0.44138408f, 0.47847018f, 0.51094836f, 0.53850579f, 0.56087714f, 0.57784694f, 0.58925176f, |
1409 | | 0.59498173f, 0.59498173f, 0.58925176f, 0.57784694f, 0.56087714f, 0.53850579f, 0.51094836f, 0.47847018f, 0.44138408f, |
1410 | | 0.40004721f, 0.35485765f, 0.30625066f, 0.25469428f, 0.20068505f, 0.14474313f, 0.08740724f, 0.02922958f, 0.03295184f, |
1411 | | 0.09853817f, 0.16317551f, 0.22624139f, 0.28712845f, 0.34525031f, 0.40004721f, 0.45099142f, 0.49759236f, 0.53940123f, |
1412 | | 0.57601535f, 0.60708213f, 0.63230234f, 0.65143317f, 0.66429037f, 0.67075002f, 0.67075002f, 0.66429037f, 0.65143317f, |
1413 | | 0.63230234f, 0.60708213f, 0.57601535f, 0.53940123f, 0.49759236f, 0.45099142f, 0.40004721f, 0.34525031f, 0.28712845f, |
1414 | | 0.22624139f, 0.16317551f, 0.09853817f, 0.03295184f, 0.03635675f, 0.10872011f, 0.18003644f, 0.24961892f, 0.31679744f, |
1415 | | 0.38092500f, 0.44138408f, 0.49759236f, 0.54900855f, 0.59513754f, 0.63553500f, 0.66981190f, 0.69763815f, 0.71874577f, |
1416 | | 0.73293144f, 0.74005860f, 0.74005860f, 0.73293144f, 0.71874577f, 0.69763815f, 0.66981190f, 0.63553500f, 0.59513754f, |
1417 | | 0.54900855f, 0.49759236f, 0.44138408f, 0.38092500f, 0.31679744f, 0.24961892f, 0.18003644f, 0.10872011f, 0.03635675f, |
1418 | | 0.03941153f, 0.11785502f, 0.19516350f, 0.27059248f, 0.34341547f, 0.41293120f, 0.47847018f, 0.53940123f, 0.59513754f, |
1419 | | 0.64514232f, 0.68893409f, 0.72609103f, 0.75625527f, 0.77913642f, 0.79451400f, 0.80224001f, 0.80224001f, 0.79451400f, |
1420 | | 0.77913642f, 0.75625527f, 0.72609103f, 0.68893409f, 0.64514232f, 0.59513754f, 0.53940123f, 0.47847018f, 0.41293120f, |
1421 | | 0.34341547f, 0.27059248f, 0.19516350f, 0.11785502f, 0.03941153f, 0.04208675f, 0.12585492f, 0.20841105f, 0.28896007f, |
1422 | | 0.36672625f, 0.44096065f, 0.51094836f, 0.57601535f, 0.63553500f, 0.68893409f, 0.73569834f, 0.77537745f, 0.80758929f, |
1423 | | 0.83202356f, 0.84844500f, 0.85669541f, 0.85669541f, 0.84844500f, 0.83202356f, 0.80758929f, 0.77537745f, 0.73569834f, |
1424 | | 0.68893409f, 0.63553500f, 0.57601535f, 0.51094836f, 0.44096065f, 0.36672625f, 0.28896007f, 0.20841105f, 0.12585492f, |
1425 | | 0.04208675f, 0.04435665f, 0.13264278f, 0.21965148f, 0.30454481f, 0.38650522f, 0.46474338f, 0.53850579f, 0.60708213f, |
1426 | | 0.66981190f, 0.72609103f, 0.77537745f, 0.81719667f, 0.85114574f, 0.87689787f, 0.89420497f, 0.90290040f, 0.90290040f, |
1427 | | 0.89420497f, 0.87689787f, 0.85114574f, 0.81719667f, 0.77537745f, 0.72609103f, 0.66981190f, 0.60708213f, 0.53850579f, |
1428 | | 0.46474338f, 0.38650522f, 0.30454481f, 0.21965148f, 0.13264278f, 0.04435665f, 0.04619938f, 0.13815321f, 0.22877654f, |
1429 | | 0.31719664f, 0.40256196f, 0.48405039f, 0.56087714f, 0.63230234f, 0.69763815f, 0.75625527f, 0.80758929f, 0.85114574f, |
1430 | | 0.88650525f, 0.91332716f, 0.93135327f, 0.94040996f, 0.94040996f, 0.93135327f, 0.91332716f, 0.88650525f, 0.85114574f, |
1431 | | 0.80758929f, 0.75625527f, 0.69763815f, 0.63230234f, 0.56087714f, 0.48405039f, 0.40256196f, 0.31719664f, 0.22877654f, |
1432 | | 0.13815321f, 0.04619938f, 0.04759718f, 0.14233315f, 0.23569837f, 0.32679370f, 0.41474181f, 0.49869573f, 0.57784694f, |
1433 | | 0.65143317f, 0.71874577f, 0.77913642f, 0.83202356f, 0.87689787f, 0.91332716f, 0.94096065f, 0.95953214f, 0.96886283f, |
1434 | | 0.96886283f, 0.95953214f, 0.94096065f, 0.91332716f, 0.87689787f, 0.83202356f, 0.77913642f, 0.71874577f, 0.65143317f, |
1435 | | 0.57784694f, 0.49869573f, 0.41474181f, 0.32679370f, 0.23569837f, 0.14233315f, 0.04759718f, 0.04853659f, 0.14514233f, |
1436 | | 0.24035029f, 0.33324352f, 0.42292747f, 0.50853837f, 0.58925176f, 0.66429037f, 0.73293144f, 0.79451400f, 0.84844500f, |
1437 | | 0.89420497f, 0.93135327f, 0.95953214f, 0.97847015f, 0.98798501f, 0.98798501f, 0.97847015f, 0.95953214f, 0.93135327f, |
1438 | | 0.89420497f, 0.84844500f, 0.79451400f, 0.73293144f, 0.66429037f, 0.58925176f, 0.50853837f, 0.42292747f, 0.33324352f, |
1439 | | 0.24035029f, 0.14514233f, 0.04853659f, 0.04900857f, 0.14655373f, 0.24268749f, 0.33648404f, 0.42704007f, 0.51348346f, |
1440 | | 0.59498173f, 0.67075002f, 0.74005860f, 0.80224001f, 0.85669541f, 0.90290040f, 0.94040996f, 0.96886283f, 0.98798501f, |
1441 | | 0.99759239f, 0.99759239f, 0.98798501f, 0.96886283f, 0.94040996f, 0.90290040f, 0.85669541f, 0.80224001f, 0.74005860f, |
1442 | | 0.67075002f, 0.59498173f, 0.51348346f, 0.42704007f, 0.33648404f, 0.24268749f, 0.14655373f, 0.04900857f, 0.04900857f, |
1443 | | 0.14655373f, 0.24268749f, 0.33648404f, 0.42704007f, 0.51348346f, 0.59498173f, 0.67075002f, 0.74005860f, 0.80224001f, |
1444 | | 0.85669541f, 0.90290040f, 0.94040996f, 0.96886283f, 0.98798501f, 0.99759239f, 0.99759239f, 0.98798501f, 0.96886283f, |
1445 | | 0.94040996f, 0.90290040f, 0.85669541f, 0.80224001f, 0.74005860f, 0.67075002f, 0.59498173f, 0.51348346f, 0.42704007f, |
1446 | | 0.33648404f, 0.24268749f, 0.14655373f, 0.04900857f, 0.04853659f, 0.14514233f, 0.24035029f, 0.33324352f, 0.42292747f, |
1447 | | 0.50853837f, 0.58925176f, 0.66429037f, 0.73293144f, 0.79451400f, 0.84844500f, 0.89420497f, 0.93135327f, 0.95953214f, |
1448 | | 0.97847015f, 0.98798501f, 0.98798501f, 0.97847015f, 0.95953214f, 0.93135327f, 0.89420497f, 0.84844500f, 0.79451400f, |
1449 | | 0.73293144f, 0.66429037f, 0.58925176f, 0.50853837f, 0.42292747f, 0.33324352f, 0.24035029f, 0.14514233f, 0.04853659f, |
1450 | | 0.04759718f, 0.14233315f, 0.23569837f, 0.32679370f, 0.41474181f, 0.49869573f, 0.57784694f, 0.65143317f, 0.71874577f, |
1451 | | 0.77913642f, 0.83202356f, 0.87689787f, 0.91332716f, 0.94096065f, 0.95953214f, 0.96886283f, 0.96886283f, 0.95953214f, |
1452 | | 0.94096065f, 0.91332716f, 0.87689787f, 0.83202356f, 0.77913642f, 0.71874577f, 0.65143317f, 0.57784694f, 0.49869573f, |
1453 | | 0.41474181f, 0.32679370f, 0.23569837f, 0.14233315f, 0.04759718f, 0.04619938f, 0.13815321f, 0.22877654f, 0.31719664f, |
1454 | | 0.40256196f, 0.48405039f, 0.56087714f, 0.63230234f, 0.69763815f, 0.75625527f, 0.80758929f, 0.85114574f, 0.88650525f, |
1455 | | 0.91332716f, 0.93135327f, 0.94040996f, 0.94040996f, 0.93135327f, 0.91332716f, 0.88650525f, 0.85114574f, 0.80758929f, |
1456 | | 0.75625527f, 0.69763815f, 0.63230234f, 0.56087714f, 0.48405039f, 0.40256196f, 0.31719664f, 0.22877654f, 0.13815321f, |
1457 | | 0.04619938f, 0.04435665f, 0.13264278f, 0.21965148f, 0.30454481f, 0.38650522f, 0.46474338f, 0.53850579f, 0.60708213f, |
1458 | | 0.66981190f, 0.72609103f, 0.77537745f, 0.81719667f, 0.85114574f, 0.87689787f, 0.89420497f, 0.90290040f, 0.90290040f, |
1459 | | 0.89420497f, 0.87689787f, 0.85114574f, 0.81719667f, 0.77537745f, 0.72609103f, 0.66981190f, 0.60708213f, 0.53850579f, |
1460 | | 0.46474338f, 0.38650522f, 0.30454481f, 0.21965148f, 0.13264278f, 0.04435665f, 0.04208675f, 0.12585492f, 0.20841105f, |
1461 | | 0.28896007f, 0.36672625f, 0.44096065f, 0.51094836f, 0.57601535f, 0.63553500f, 0.68893409f, 0.73569834f, 0.77537745f, |
1462 | | 0.80758929f, 0.83202356f, 0.84844500f, 0.85669541f, 0.85669541f, 0.84844500f, 0.83202356f, 0.80758929f, 0.77537745f, |
1463 | | 0.73569834f, 0.68893409f, 0.63553500f, 0.57601535f, 0.51094836f, 0.44096065f, 0.36672625f, 0.28896007f, 0.20841105f, |
1464 | | 0.12585492f, 0.04208675f, 0.03941153f, 0.11785502f, 0.19516350f, 0.27059248f, 0.34341547f, 0.41293120f, 0.47847018f, |
1465 | | 0.53940123f, 0.59513754f, 0.64514232f, 0.68893409f, 0.72609103f, 0.75625527f, 0.77913642f, 0.79451400f, 0.80224001f, |
1466 | | 0.80224001f, 0.79451400f, 0.77913642f, 0.75625527f, 0.72609103f, 0.68893409f, 0.64514232f, 0.59513754f, 0.53940123f, |
1467 | | 0.47847018f, 0.41293120f, 0.34341547f, 0.27059248f, 0.19516350f, 0.11785502f, 0.03941153f, 0.03635675f, 0.10872011f, |
1468 | | 0.18003644f, 0.24961892f, 0.31679744f, 0.38092500f, 0.44138408f, 0.49759236f, 0.54900855f, 0.59513754f, 0.63553500f, |
1469 | | 0.66981190f, 0.69763815f, 0.71874577f, 0.73293144f, 0.74005860f, 0.74005860f, 0.73293144f, 0.71874577f, 0.69763815f, |
1470 | | 0.66981190f, 0.63553500f, 0.59513754f, 0.54900855f, 0.49759236f, 0.44138408f, 0.38092500f, 0.31679744f, 0.24961892f, |
1471 | | 0.18003644f, 0.10872011f, 0.03635675f, 0.03295184f, 0.09853817f, 0.16317551f, 0.22624139f, 0.28712845f, 0.34525031f, |
1472 | | 0.40004721f, 0.45099142f, 0.49759236f, 0.53940123f, 0.57601535f, 0.60708213f, 0.63230234f, 0.65143317f, 0.66429037f, |
1473 | | 0.67075002f, 0.67075002f, 0.66429037f, 0.65143317f, 0.63230234f, 0.60708213f, 0.57601535f, 0.53940123f, 0.49759236f, |
1474 | | 0.45099142f, 0.40004721f, 0.34525031f, 0.28712845f, 0.22624139f, 0.16317551f, 0.09853817f, 0.03295184f, 0.02922958f, |
1475 | | 0.08740724f, 0.14474313f, 0.20068505f, 0.25469428f, 0.30625066f, 0.35485765f, 0.40004721f, 0.44138408f, 0.47847018f, |
1476 | | 0.51094836f, 0.53850579f, 0.56087714f, 0.57784694f, 0.58925176f, 0.59498173f, 0.59498173f, 0.58925176f, 0.57784694f, |
1477 | | 0.56087714f, 0.53850579f, 0.51094836f, 0.47847018f, 0.44138408f, 0.40004721f, 0.35485765f, 0.30625066f, 0.25469428f, |
1478 | | 0.20068505f, 0.14474313f, 0.08740724f, 0.02922958f, 0.02522583f, 0.07543454f, 0.12491678f, 0.17319600f, 0.21980725f, |
1479 | | 0.26430163f, 0.30625066f, 0.34525031f, 0.38092500f, 0.41293120f, 0.44096065f, 0.46474338f, 0.48405039f, 0.49869573f, |
1480 | | 0.50853837f, 0.51348346f, 0.51348346f, 0.50853837f, 0.49869573f, 0.48405039f, 0.46474338f, 0.44096065f, 0.41293120f, |
1481 | | 0.38092500f, 0.34525031f, 0.30625066f, 0.26430163f, 0.21980725f, 0.17319600f, 0.12491678f, 0.07543454f, 0.02522583f, |
1482 | | 0.02097913f, 0.06273536f, 0.10388742f, 0.14403898f, 0.18280336f, 0.21980725f, 0.25469428f, 0.28712845f, 0.31679744f, |
1483 | | 0.34341547f, 0.36672625f, 0.38650522f, 0.40256196f, 0.41474181f, 0.42292747f, 0.42704007f, 0.42704007f, 0.42292747f, |
1484 | | 0.41474181f, 0.40256196f, 0.38650522f, 0.36672625f, 0.34341547f, 0.31679744f, 0.28712845f, 0.25469428f, 0.21980725f, |
1485 | | 0.18280336f, 0.14403898f, 0.10388742f, 0.06273536f, 0.02097913f, 0.01653040f, 0.04943201f, 0.08185755f, 0.11349478f, |
1486 | | 0.14403898f, 0.17319600f, 0.20068505f, 0.22624139f, 0.24961892f, 0.27059248f, 0.28896007f, 0.30454481f, 0.31719664f, |
1487 | | 0.32679370f, 0.33324352f, 0.33648404f, 0.33648404f, 0.33324352f, 0.32679370f, 0.31719664f, 0.30454481f, 0.28896007f, |
1488 | | 0.27059248f, 0.24961892f, 0.22624139f, 0.20068505f, 0.17319600f, 0.14403898f, 0.11349478f, 0.08185755f, 0.04943201f, |
1489 | | 0.01653040f, 0.01192247f, 0.03565260f, 0.05903937f, 0.08185755f, 0.10388742f, 0.12491678f, 0.14474313f, 0.16317551f, |
1490 | | 0.18003644f, 0.19516350f, 0.20841105f, 0.21965148f, 0.22877654f, 0.23569837f, 0.24035029f, 0.24268749f, 0.24268749f, |
1491 | | 0.24035029f, 0.23569837f, 0.22877654f, 0.21965148f, 0.20841105f, 0.19516350f, 0.18003644f, 0.16317551f, 0.14474313f, |
1492 | | 0.12491678f, 0.10388742f, 0.08185755f, 0.05903937f, 0.03565260f, 0.01192247f, 0.00719972f, 0.02152983f, 0.03565260f, |
1493 | | 0.04943201f, 0.06273536f, 0.07543454f, 0.08740724f, 0.09853817f, 0.10872011f, 0.11785502f, 0.12585492f, 0.13264278f, |
1494 | | 0.13815321f, 0.14233315f, 0.14514233f, 0.14655373f, 0.14655373f, 0.14514233f, 0.14233315f, 0.13815321f, 0.13264278f, |
1495 | | 0.12585492f, 0.11785502f, 0.10872011f, 0.09853817f, 0.08740724f, 0.07543454f, 0.06273536f, 0.04943201f, 0.03565260f, |
1496 | | 0.02152983f, 0.00719972f, 0.00240764f, 0.00719972f, 0.01192247f, 0.01653040f, 0.02097913f, 0.02522583f, 0.02922958f, |
1497 | | 0.03295184f, 0.03635675f, 0.03941153f, 0.04208675f, 0.04435665f, 0.04619938f, 0.04759718f, 0.04853659f, 0.04900857f, |
1498 | | 0.04900857f, 0.04853659f, 0.04759718f, 0.04619938f, 0.04435665f, 0.04208675f, 0.03941153f, 0.03635675f, 0.03295184f, |
1499 | | 0.02922958f, 0.02522583f, 0.02097913f, 0.01653040f, 0.01192247f, 0.00719972f, 0.00240764f, |
1500 | | }; |
1501 | | static const float window_function_half_cos_window_64[4096] = { |
1502 | | 0.00060227f, 0.00180536f, 0.00300411f, 0.00419561f, 0.00537701f, 0.00654546f, 0.00769814f, 0.00883227f, 0.00994512f, |
1503 | | 0.01103401f, 0.01209633f, 0.01312950f, 0.01413104f, 0.01509854f, 0.01602966f, 0.01692217f, 0.01777391f, 0.01858284f, |
1504 | | 0.01934699f, 0.02006454f, 0.02073374f, 0.02135300f, 0.02192082f, 0.02243583f, 0.02289679f, 0.02330259f, 0.02365225f, |
1505 | | 0.02394493f, 0.02417992f, 0.02435667f, 0.02447473f, 0.02453384f, 0.02453384f, 0.02447473f, 0.02435667f, 0.02417992f, |
1506 | | 0.02394493f, 0.02365225f, 0.02330259f, 0.02289679f, 0.02243583f, 0.02192082f, 0.02135300f, 0.02073374f, 0.02006454f, |
1507 | | 0.01934699f, 0.01858284f, 0.01777391f, 0.01692217f, 0.01602966f, 0.01509854f, 0.01413104f, 0.01312950f, 0.01209633f, |
1508 | | 0.01103401f, 0.00994512f, 0.00883227f, 0.00769814f, 0.00654546f, 0.00537701f, 0.00419561f, 0.00300411f, 0.00180536f, |
1509 | | 0.00060227f, 0.00180536f, 0.00541175f, 0.00900509f, 0.01257674f, 0.01611809f, 0.01962061f, 0.02307586f, 0.02647552f, |
1510 | | 0.02981140f, 0.03307546f, 0.03625984f, 0.03935686f, 0.04235908f, 0.04525924f, 0.04805037f, 0.05072575f, 0.05327892f, |
1511 | | 0.05570374f, 0.05799436f, 0.06014527f, 0.06215128f, 0.06400757f, 0.06570966f, 0.06725344f, 0.06863521f, 0.06985163f, |
1512 | | 0.07089976f, 0.07177710f, 0.07248152f, 0.07301132f, 0.07336523f, 0.07354241f, 0.07354241f, 0.07336523f, 0.07301132f, |
1513 | | 0.07248152f, 0.07177710f, 0.07089976f, 0.06985163f, 0.06863521f, 0.06725344f, 0.06570966f, 0.06400757f, 0.06215128f, |
1514 | | 0.06014527f, 0.05799436f, 0.05570374f, 0.05327892f, 0.05072575f, 0.04805037f, 0.04525924f, 0.04235908f, 0.03935686f, |
1515 | | 0.03625984f, 0.03307546f, 0.02981140f, 0.02647552f, 0.02307586f, 0.01962061f, 0.01611809f, 0.01257674f, 0.00900509f, |
1516 | | 0.00541175f, 0.00180536f, 0.00300411f, 0.00900509f, 0.01498437f, 0.02092756f, 0.02682033f, 0.03264849f, 0.03839799f, |
1517 | | 0.04405500f, 0.04960586f, 0.05503723f, 0.06033600f, 0.06548942f, 0.07048507f, 0.07531092f, 0.07995533f, 0.08440712f, |
1518 | | 0.08865558f, 0.09269045f, 0.09650202f, 0.10008111f, 0.10341910f, 0.10650793f, 0.10934019f, 0.11190903f, 0.11420828f, |
1519 | | 0.11623239f, 0.11797648f, 0.11943635f, 0.12060850f, 0.12149009f, 0.12207900f, 0.12237380f, 0.12237380f, 0.12207900f, |
1520 | | 0.12149009f, 0.12060850f, 0.11943635f, 0.11797648f, 0.11623239f, 0.11420828f, 0.11190903f, 0.10934019f, 0.10650793f, |
1521 | | 0.10341910f, 0.10008111f, 0.09650202f, 0.09269045f, 0.08865558f, 0.08440712f, 0.07995533f, 0.07531092f, 0.07048507f, |
1522 | | 0.06548942f, 0.06033600f, 0.05503723f, 0.04960586f, 0.04405500f, 0.03839799f, 0.03264849f, 0.02682033f, 0.02092756f, |
1523 | | 0.01498437f, 0.00900509f, 0.00300411f, 0.00419561f, 0.01257674f, 0.02092756f, 0.02922797f, 0.03745796f, 0.04559772f, |
1524 | | 0.05362762f, 0.06152834f, 0.06928082f, 0.07686640f, 0.08426680f, 0.09146421f, 0.09844126f, 0.10518116f, 0.11166766f, |
1525 | | 0.11788516f, 0.12381865f, 0.12945385f, 0.13477719f, 0.13977584f, 0.14443776f, 0.14875172f, 0.15270731f, 0.15629503f, |
1526 | | 0.15950622f, 0.16233313f, 0.16476898f, 0.16680788f, 0.16844493f, 0.16967617f, 0.17049865f, 0.17091040f, 0.17091040f, |
1527 | | 0.17049865f, 0.16967617f, 0.16844493f, 0.16680788f, 0.16476898f, 0.16233313f, 0.15950622f, 0.15629503f, 0.15270731f, |
1528 | | 0.14875172f, 0.14443776f, 0.13977584f, 0.13477719f, 0.12945385f, 0.12381865f, 0.11788516f, 0.11166766f, 0.10518116f, |
1529 | | 0.09844126f, 0.09146421f, 0.08426680f, 0.07686640f, 0.06928082f, 0.06152834f, 0.05362762f, 0.04559772f, 0.03745796f, |
1530 | | 0.02922797f, 0.02092756f, 0.01257674f, 0.00419561f, 0.00537701f, 0.01611809f, 0.02682033f, 0.03745796f, 0.04800535f, |
1531 | | 0.05843709f, 0.06872806f, 0.07885345f, 0.08878887f, 0.09851040f, 0.10799461f, 0.11721864f, 0.12616029f, 0.13479801f, |
1532 | | 0.14311098f, 0.15107919f, 0.15868343f, 0.16590540f, 0.17272767f, 0.17913385f, 0.18510847f, 0.19063714f, 0.19570655f, |
1533 | | 0.20030449f, 0.20441988f, 0.20804280f, 0.21116453f, 0.21377754f, 0.21587555f, 0.21745349f, 0.21850757f, 0.21903525f, |
1534 | | 0.21903525f, 0.21850757f, 0.21745349f, 0.21587555f, 0.21377754f, 0.21116453f, 0.20804280f, 0.20441988f, 0.20030449f, |
1535 | | 0.19570655f, 0.19063714f, 0.18510847f, 0.17913385f, 0.17272767f, 0.16590540f, 0.15868343f, 0.15107919f, 0.14311098f, |
1536 | | 0.13479801f, 0.12616029f, 0.11721864f, 0.10799461f, 0.09851040f, 0.08878887f, 0.07885345f, 0.06872806f, 0.05843709f, |
1537 | | 0.04800535f, 0.03745796f, 0.02682033f, 0.01611809f, 0.00537701f, 0.00654546f, 0.01962061f, 0.03264849f, 0.04559772f, |
1538 | | 0.05843709f, 0.07113569f, 0.08366292f, 0.09598859f, 0.10808302f, 0.11991708f, 0.13146223f, 0.14269069f, 0.15357539f, |
1539 | | 0.16409011f, 0.17420954f, 0.18390927f, 0.19316594f, 0.20195726f, 0.21026205f, 0.21806030f, 0.22533323f, 0.23206329f, |
1540 | | 0.23823431f, 0.24383141f, 0.24884108f, 0.25325128f, 0.25705138f, 0.26023221f, 0.26278612f, 0.26470694f, 0.26599008f, |
1541 | | 0.26663244f, 0.26663244f, 0.26599008f, 0.26470694f, 0.26278612f, 0.26023221f, 0.25705138f, 0.25325128f, 0.24884108f, |
1542 | | 0.24383141f, 0.23823431f, 0.23206329f, 0.22533323f, 0.21806030f, 0.21026205f, 0.20195726f, 0.19316594f, 0.18390927f, |
1543 | | 0.17420954f, 0.16409011f, 0.15357539f, 0.14269069f, 0.13146223f, 0.11991708f, 0.10808302f, 0.09598859f, 0.08366292f, |
1544 | | 0.07113569f, 0.05843709f, 0.04559772f, 0.03264849f, 0.01962061f, 0.00654546f, 0.00769814f, 0.02307586f, 0.03839799f, |
1545 | | 0.05362762f, 0.06872806f, 0.08366292f, 0.09839623f, 0.11289250f, 0.12711680f, 0.14103487f, 0.15461317f, 0.16781898f, |
1546 | | 0.18062052f, 0.19298692f, 0.20488839f, 0.21629629f, 0.22718309f, 0.23752259f, 0.24728988f, 0.25646144f, 0.26501513f, |
1547 | | 0.27293041f, 0.28018814f, 0.28677091f, 0.29266280f, 0.29784966f, 0.30231896f, 0.30605996f, 0.30906361f, 0.31132272f, |
1548 | | 0.31283182f, 0.31358728f, 0.31358728f, 0.31283182f, 0.31132272f, 0.30906361f, 0.30605996f, 0.30231896f, 0.29784966f, |
1549 | | 0.29266280f, 0.28677091f, 0.28018814f, 0.27293041f, 0.26501513f, 0.25646144f, 0.24728988f, 0.23752259f, 0.22718309f, |
1550 | | 0.21629629f, 0.20488839f, 0.19298692f, 0.18062052f, 0.16781898f, 0.15461317f, 0.14103487f, 0.12711680f, 0.11289250f, |
1551 | | 0.09839623f, 0.08366292f, 0.06872806f, 0.05362762f, 0.03839799f, 0.02307586f, 0.00769814f, 0.00883227f, 0.02647552f, |
1552 | | 0.04405500f, 0.06152834f, 0.07885345f, 0.09598859f, 0.11289250f, 0.12952444f, 0.14584434f, 0.16181289f, 0.17739162f, |
1553 | | 0.19254299f, 0.20723051f, 0.22141880f, 0.23507367f, 0.24816222f, 0.26065293f, 0.27251571f, 0.28372195f, 0.29424471f, |
1554 | | 0.30405861f, 0.31313998f, 0.32146698f, 0.32901955f, 0.33577949f, 0.34173048f, 0.34685823f, 0.35115036f, 0.35459653f, |
1555 | | 0.35718846f, 0.35891989f, 0.35978663f, 0.35978663f, 0.35891989f, 0.35718846f, 0.35459653f, 0.35115036f, 0.34685823f, |
1556 | | 0.34173048f, 0.33577949f, 0.32901955f, 0.32146698f, 0.31313998f, 0.30405861f, 0.29424471f, 0.28372195f, 0.27251571f, |
1557 | | 0.26065293f, 0.24816222f, 0.23507367f, 0.22141880f, 0.20723051f, 0.19254299f, 0.17739162f, 0.16181289f, 0.14584434f, |
1558 | | 0.12952444f, 0.11289250f, 0.09598859f, 0.07885345f, 0.06152834f, 0.04405500f, 0.02647552f, 0.00883227f, 0.00994512f, |
1559 | | 0.02981140f, 0.04960586f, 0.06928082f, 0.08878887f, 0.10808302f, 0.12711680f, 0.14584434f, 0.16422053f, 0.18220109f, |
1560 | | 0.19974270f, 0.21680313f, 0.23334126f, 0.24931726f, 0.26469263f, 0.27943033f, 0.29349485f, 0.30685231f, 0.31947055f, |
1561 | | 0.33131915f, 0.34236956f, 0.35259521f, 0.36197138f, 0.37047556f, 0.37808722f, 0.38478804f, 0.39056188f, 0.39539480f, |
1562 | | 0.39927521f, 0.40219373f, 0.40414330f, 0.40511927f, 0.40511927f, 0.40414330f, 0.40219373f, 0.39927521f, 0.39539480f, |
1563 | | 0.39056188f, 0.38478804f, 0.37808722f, 0.37047556f, 0.36197138f, 0.35259521f, 0.34236956f, 0.33131915f, 0.31947055f, |
1564 | | 0.30685231f, 0.29349485f, 0.27943033f, 0.26469263f, 0.24931726f, 0.23334126f, 0.21680313f, 0.19974270f, 0.18220109f, |
1565 | | 0.16422053f, 0.14584434f, 0.12711680f, 0.10808302f, 0.08878887f, 0.06928082f, 0.04960586f, 0.02981140f, 0.00994512f, |
1566 | | 0.01103401f, 0.03307546f, 0.05503723f, 0.07686640f, 0.09851040f, 0.11991708f, 0.14103487f, 0.16181289f, 0.18220109f, |
1567 | | 0.20215034f, 0.22161262f, 0.24054100f, 0.25888988f, 0.27661508f, 0.29367390f, 0.31002524f, 0.32562968f, 0.34044969f, |
1568 | | 0.35444948f, 0.36759540f, 0.37985572f, 0.39120096f, 0.40160376f, 0.41103905f, 0.41948414f, 0.42691863f, 0.43332464f, |
1569 | | 0.43868673f, 0.44299200f, 0.44623005f, 0.44839308f, 0.44947591f, 0.44947591f, 0.44839308f, 0.44623005f, 0.44299200f, |
1570 | | 0.43868673f, 0.43332464f, 0.42691863f, 0.41948414f, 0.41103905f, 0.40160376f, 0.39120096f, 0.37985572f, 0.36759540f, |
1571 | | 0.35444948f, 0.34044969f, 0.32562968f, 0.31002524f, 0.29367390f, 0.27661508f, 0.25888988f, 0.24054100f, 0.22161262f, |
1572 | | 0.20215034f, 0.18220109f, 0.16181289f, 0.14103487f, 0.11991708f, 0.09851040f, 0.07686640f, 0.05503723f, 0.03307546f, |
1573 | | 0.01103401f, 0.01209633f, 0.03625984f, 0.06033600f, 0.08426680f, 0.10799461f, 0.13146223f, 0.15461317f, 0.17739162f, |
1574 | | 0.19974270f, 0.22161262f, 0.24294862f, 0.26369935f, 0.28381482f, 0.30324653f, 0.32194772f, 0.33987328f, 0.35698009f, |
1575 | | 0.37322688f, 0.38857454f, 0.40298608f, 0.41642681f, 0.42886430f, 0.44026864f, 0.45061234f, 0.45987046f, 0.46802074f, |
1576 | | 0.47504348f, 0.48092180f, 0.48564157f, 0.48919138f, 0.49156266f, 0.49274975f, 0.49274975f, 0.49156266f, 0.48919138f, |
1577 | | 0.48564157f, 0.48092180f, 0.47504348f, 0.46802074f, 0.45987046f, 0.45061234f, 0.44026864f, 0.42886430f, 0.41642681f, |
1578 | | 0.40298608f, 0.38857454f, 0.37322688f, 0.35698009f, 0.33987328f, 0.32194772f, 0.30324653f, 0.28381482f, 0.26369935f, |
1579 | | 0.24294862f, 0.22161262f, 0.19974270f, 0.17739162f, 0.15461317f, 0.13146223f, 0.10799461f, 0.08426680f, 0.06033600f, |
1580 | | 0.03625984f, 0.01209633f, 0.01312950f, 0.03935686f, 0.06548942f, 0.09146421f, 0.11721864f, 0.14269069f, 0.16781898f, |
1581 | | 0.19254299f, 0.21680313f, 0.24054100f, 0.26369935f, 0.28622246f, 0.30805603f, 0.32914743f, 0.34944591f, 0.36890256f, |
1582 | | 0.38747045f, 0.40510494f, 0.42176345f, 0.43740594f, 0.45199466f, 0.46549448f, 0.47787288f, 0.48910004f, 0.49914894f, |
1583 | | 0.50799531f, 0.51561791f, 0.52199835f, 0.52712119f, 0.53097421f, 0.53354800f, 0.53483647f, 0.53483647f, 0.53354800f, |
1584 | | 0.53097421f, 0.52712119f, 0.52199835f, 0.51561791f, 0.50799531f, 0.49914894f, 0.48910004f, 0.47787288f, 0.46549448f, |
1585 | | 0.45199466f, 0.43740594f, 0.42176345f, 0.40510494f, 0.38747045f, 0.36890256f, 0.34944591f, 0.32914743f, 0.30805603f, |
1586 | | 0.28622246f, 0.26369935f, 0.24054100f, 0.21680313f, 0.19254299f, 0.16781898f, 0.14269069f, 0.11721864f, 0.09146421f, |
1587 | | 0.06548942f, 0.03935686f, 0.01312950f, 0.01413104f, 0.04235908f, 0.07048507f, 0.09844126f, 0.12616029f, 0.15357539f, |
1588 | | 0.18062052f, 0.20723051f, 0.23334126f, 0.25888988f, 0.28381482f, 0.30805603f, 0.33155507f, 0.35425538f, 0.37610227f, |
1589 | | 0.39704308f, 0.41702741f, 0.43600705f, 0.45393634f, 0.47077203f, 0.48647359f, 0.50100321f, 0.51432586f, 0.52640945f, |
1590 | | 0.53722489f, 0.54674608f, 0.55495018f, 0.56181729f, 0.56733096f, 0.57147783f, 0.57424802f, 0.57563478f, 0.57563478f, |
1591 | | 0.57424802f, 0.57147783f, 0.56733096f, 0.56181729f, 0.55495018f, 0.54674608f, 0.53722489f, 0.52640945f, 0.51432586f, |
1592 | | 0.50100321f, 0.48647359f, 0.47077203f, 0.45393634f, 0.43600705f, 0.41702741f, 0.39704308f, 0.37610227f, 0.35425538f, |
1593 | | 0.33155507f, 0.30805603f, 0.28381482f, 0.25888988f, 0.23334126f, 0.20723051f, 0.18062052f, 0.15357539f, 0.12616029f, |
1594 | | 0.09844126f, 0.07048507f, 0.04235908f, 0.01413104f, 0.01509854f, 0.04525924f, 0.07531092f, 0.10518116f, 0.13479801f, |
1595 | | 0.16409011f, 0.19298692f, 0.22141880f, 0.24931726f, 0.27661508f, 0.30324653f, 0.32914743f, 0.35425538f, 0.37850991f, |
1596 | | 0.40185258f, 0.42422712f, 0.44557968f, 0.46585882f, 0.48501563f, 0.50300401f, 0.51978058f, 0.53530502f, 0.54953980f, |
1597 | | 0.56245071f, 0.57400662f, 0.58417976f, 0.59294546f, 0.60028279f, 0.60617393f, 0.61060476f, 0.61356461f, 0.61504632f, |
1598 | | 0.61504632f, 0.61356461f, 0.61060476f, 0.60617393f, 0.60028279f, 0.59294546f, 0.58417976f, 0.57400662f, 0.56245071f, |
1599 | | 0.54953980f, 0.53530502f, 0.51978058f, 0.50300401f, 0.48501563f, 0.46585882f, 0.44557968f, 0.42422712f, 0.40185258f, |
1600 | | 0.37850991f, 0.35425538f, 0.32914743f, 0.30324653f, 0.27661508f, 0.24931726f, 0.22141880f, 0.19298692f, 0.16409011f, |
1601 | | 0.13479801f, 0.10518116f, 0.07531092f, 0.04525924f, 0.01509854f, 0.01602966f, 0.04805037f, 0.07995533f, 0.11166766f, |
1602 | | 0.14311098f, 0.17420954f, 0.20488839f, 0.23507367f, 0.26469263f, 0.29367390f, 0.32194772f, 0.34944591f, 0.37610227f, |
1603 | | 0.40185258f, 0.42663476f, 0.45038915f, 0.47305852f, 0.49458826f, 0.51492649f, 0.53402418f, 0.55183542f, 0.56831717f, |
1604 | | 0.58342987f, 0.59713697f, 0.60940558f, 0.62020600f, 0.62951237f, 0.63730216f, 0.64355659f, 0.64826065f, 0.65140307f, |
1605 | | 0.65297610f, 0.65297610f, 0.65140307f, 0.64826065f, 0.64355659f, 0.63730216f, 0.62951237f, 0.62020600f, 0.60940558f, |
1606 | | 0.59713697f, 0.58342987f, 0.56831717f, 0.55183542f, 0.53402418f, 0.51492649f, 0.49458826f, 0.47305852f, 0.45038915f, |
1607 | | 0.42663476f, 0.40185258f, 0.37610227f, 0.34944591f, 0.32194772f, 0.29367390f, 0.26469263f, 0.23507367f, 0.20488839f, |
1608 | | 0.17420954f, 0.14311098f, 0.11166766f, 0.07995533f, 0.04805037f, 0.01602966f, 0.01692217f, 0.05072575f, 0.08440712f, |
1609 | | 0.11788516f, 0.15107919f, 0.18390927f, 0.21629629f, 0.24816222f, 0.27943033f, 0.31002524f, 0.33987328f, 0.36890256f, |
1610 | | 0.39704308f, 0.42422712f, 0.45038915f, 0.47546616f, 0.49939772f, 0.52212620f, 0.54359680f, 0.56375790f, 0.58256078f, |
1611 | | 0.59996027f, 0.61591434f, 0.63038468f, 0.64333636f, 0.65473819f, 0.66456270f, 0.67278618f, 0.67938888f, 0.68435490f, |
1612 | | 0.68767220f, 0.68933284f, 0.68933284f, 0.68767220f, 0.68435490f, 0.67938888f, 0.67278618f, 0.66456270f, 0.65473819f, |
1613 | | 0.64333636f, 0.63038468f, 0.61591434f, 0.59996027f, 0.58256078f, 0.56375790f, 0.54359680f, 0.52212620f, 0.49939772f, |
1614 | | 0.47546616f, 0.45038915f, 0.42422712f, 0.39704308f, 0.36890256f, 0.33987328f, 0.31002524f, 0.27943033f, 0.24816222f, |
1615 | | 0.21629629f, 0.18390927f, 0.15107919f, 0.11788516f, 0.08440712f, 0.05072575f, 0.01692217f, 0.01777391f, 0.05327892f, |
1616 | | 0.08865558f, 0.12381865f, 0.15868343f, 0.19316594f, 0.22718309f, 0.26065293f, 0.29349485f, 0.32562968f, 0.35698009f, |
1617 | | 0.38747045f, 0.41702741f, 0.44557968f, 0.47305852f, 0.49939772f, 0.52453381f, 0.54840630f, 0.57095760f, 0.59213340f, |
1618 | | 0.61188275f, 0.63015795f, 0.64691508f, 0.66211373f, 0.67571729f, 0.68769300f, 0.69801199f, 0.70664942f, 0.71358448f, |
1619 | | 0.71880043f, 0.72228467f, 0.72402894f, 0.72402894f, 0.72228467f, 0.71880043f, 0.71358448f, 0.70664942f, 0.69801199f, |
1620 | | 0.68769300f, 0.67571729f, 0.66211373f, 0.64691508f, 0.63015795f, 0.61188275f, 0.59213340f, 0.57095760f, 0.54840630f, |
1621 | | 0.52453381f, 0.49939772f, 0.47305852f, 0.44557968f, 0.41702741f, 0.38747045f, 0.35698009f, 0.32562968f, 0.29349485f, |
1622 | | 0.26065293f, 0.22718309f, 0.19316594f, 0.15868343f, 0.12381865f, 0.08865558f, 0.05327892f, 0.01777391f, 0.01858284f, |
1623 | | 0.05570374f, 0.09269045f, 0.12945385f, 0.16590540f, 0.20195726f, 0.23752259f, 0.27251571f, 0.30685231f, 0.34044969f, |
1624 | | 0.37322688f, 0.40510494f, 0.43600705f, 0.46585882f, 0.49458826f, 0.52212620f, 0.54840630f, 0.57336521f, 0.59694290f, |
1625 | | 0.61908245f, 0.63973057f, 0.65883756f, 0.67635733f, 0.69224769f, 0.70647043f, 0.71899116f, 0.72977978f, 0.73881030f, |
1626 | | 0.74606097f, 0.75151426f, 0.75515717f, 0.75698078f, 0.75698078f, 0.75515717f, 0.75151426f, 0.74606097f, 0.73881030f, |
1627 | | 0.72977978f, 0.71899116f, 0.70647043f, 0.69224769f, 0.67635733f, 0.65883756f, 0.63973057f, 0.61908245f, 0.59694290f, |
1628 | | 0.57336521f, 0.54840630f, 0.52212620f, 0.49458826f, 0.46585882f, 0.43600705f, 0.40510494f, 0.37322688f, 0.34044969f, |
1629 | | 0.30685231f, 0.27251571f, 0.23752259f, 0.20195726f, 0.16590540f, 0.12945385f, 0.09269045f, 0.05570374f, 0.01858284f, |
1630 | | 0.01934699f, 0.05799436f, 0.09650202f, 0.13477719f, 0.17272767f, 0.21026205f, 0.24728988f, 0.28372195f, 0.31947055f, |
1631 | | 0.35444948f, 0.38857454f, 0.42176345f, 0.45393634f, 0.48501563f, 0.51492649f, 0.54359680f, 0.57095760f, 0.59694290f, |
1632 | | 0.62149006f, 0.64454007f, 0.66603726f, 0.68592995f, 0.70417017f, 0.72071397f, 0.73552155f, 0.74855715f, 0.75978941f, |
1633 | | 0.76919127f, 0.77674013f, 0.78241771f, 0.78621036f, 0.78810900f, 0.78810900f, 0.78621036f, 0.78241771f, 0.77674013f, |
1634 | | 0.76919127f, 0.75978941f, 0.74855715f, 0.73552155f, 0.72071397f, 0.70417017f, 0.68592995f, 0.66603726f, 0.64454007f, |
1635 | | 0.62149006f, 0.59694290f, 0.57095760f, 0.54359680f, 0.51492649f, 0.48501563f, 0.45393634f, 0.42176345f, 0.38857454f, |
1636 | | 0.35444948f, 0.31947055f, 0.28372195f, 0.24728988f, 0.21026205f, 0.17272767f, 0.13477719f, 0.09650202f, 0.05799436f, |
1637 | | 0.01934699f, 0.02006454f, 0.06014527f, 0.10008111f, 0.13977584f, 0.17913385f, 0.21806030f, 0.25646144f, 0.29424471f, |
1638 | | 0.33131915f, 0.36759540f, 0.40298608f, 0.43740594f, 0.47077203f, 0.50300401f, 0.53402418f, 0.56375790f, 0.59213340f, |
1639 | | 0.61908245f, 0.64454007f, 0.66844493f, 0.69073945f, 0.71136993f, 0.73028660f, 0.74744403f, 0.76280075f, 0.77631980f, |
1640 | | 0.78796870f, 0.79771924f, 0.80554801f, 0.81143618f, 0.81536955f, 0.81733859f, 0.81733859f, 0.81536955f, 0.81143618f, |
1641 | | 0.80554801f, 0.79771924f, 0.78796870f, 0.77631980f, 0.76280075f, 0.74744403f, 0.73028660f, 0.71136993f, 0.69073945f, |
1642 | | 0.66844493f, 0.64454007f, 0.61908245f, 0.59213340f, 0.56375790f, 0.53402418f, 0.50300401f, 0.47077203f, 0.43740594f, |
1643 | | 0.40298608f, 0.36759540f, 0.33131915f, 0.29424471f, 0.25646144f, 0.21806030f, 0.17913385f, 0.13977584f, 0.10008111f, |
1644 | | 0.06014527f, 0.02006454f, 0.02073374f, 0.06215128f, 0.10341910f, 0.14443776f, 0.18510847f, 0.22533323f, 0.26501513f, |
1645 | | 0.30405861f, 0.34236956f, 0.37985572f, 0.41642681f, 0.45199466f, 0.48647359f, 0.51978058f, 0.55183542f, 0.58256078f, |
1646 | | 0.61188275f, 0.63973057f, 0.66603726f, 0.69073945f, 0.71377754f, 0.73509610f, 0.75464374f, 0.77237338f, 0.78824228f, |
1647 | | 0.80221230f, 0.81424963f, 0.82432544f, 0.83241534f, 0.83849984f, 0.84256440f, 0.84459913f, 0.84459913f, 0.84256440f, |
1648 | | 0.83849984f, 0.83241534f, 0.82432544f, 0.81424963f, 0.80221230f, 0.78824228f, 0.77237338f, 0.75464374f, 0.73509610f, |
1649 | | 0.71377754f, 0.69073945f, 0.66603726f, 0.63973057f, 0.61188275f, 0.58256078f, 0.55183542f, 0.51978058f, 0.48647359f, |
1650 | | 0.45199466f, 0.41642681f, 0.37985572f, 0.34236956f, 0.30405861f, 0.26501513f, 0.22533323f, 0.18510847f, 0.14443776f, |
1651 | | 0.10341910f, 0.06215128f, 0.02073374f, 0.02135300f, 0.06400757f, 0.10650793f, 0.14875172f, 0.19063714f, 0.23206329f, |
1652 | | 0.27293041f, 0.31313998f, 0.35259521f, 0.39120096f, 0.42886430f, 0.46549448f, 0.50100321f, 0.53530502f, 0.56831717f, |
1653 | | 0.59996027f, 0.63015795f, 0.65883756f, 0.68592995f, 0.71136993f, 0.73509610f, 0.75705135f, 0.77718282f, 0.79544204f, |
1654 | | 0.81178492f, 0.82617211f, 0.83856905f, 0.84894574f, 0.85727727f, 0.86354351f, 0.86772943f, 0.86982495f, 0.86982495f, |
1655 | | 0.86772943f, 0.86354351f, 0.85727727f, 0.84894574f, 0.83856905f, 0.82617211f, 0.81178492f, 0.79544204f, 0.77718282f, |
1656 | | 0.75705135f, 0.73509610f, 0.71136993f, 0.68592995f, 0.65883756f, 0.63015795f, 0.59996027f, 0.56831717f, 0.53530502f, |
1657 | | 0.50100321f, 0.46549448f, 0.42886430f, 0.39120096f, 0.35259521f, 0.31313998f, 0.27293041f, 0.23206329f, 0.19063714f, |
1658 | | 0.14875172f, 0.10650793f, 0.06400757f, 0.02135300f, 0.02192082f, 0.06570966f, 0.10934019f, 0.15270731f, 0.19570655f, |
1659 | | 0.23823431f, 0.28018814f, 0.32146698f, 0.36197138f, 0.40160376f, 0.44026864f, 0.47787288f, 0.51432586f, 0.54953980f, |
1660 | | 0.58342987f, 0.61591434f, 0.64691508f, 0.67635733f, 0.70417017f, 0.73028660f, 0.75464374f, 0.77718282f, 0.79784966f, |
1661 | | 0.81659436f, 0.83337182f, 0.84814167f, 0.86086822f, 0.87152088f, 0.88007390f, 0.88650686f, 0.89080405f, 0.89295530f, |
1662 | | 0.89295530f, 0.89080405f, 0.88650686f, 0.88007390f, 0.87152088f, 0.86086822f, 0.84814167f, 0.83337182f, 0.81659436f, |
1663 | | 0.79784966f, 0.77718282f, 0.75464374f, 0.73028660f, 0.70417017f, 0.67635733f, 0.64691508f, 0.61591434f, 0.58342987f, |
1664 | | 0.54953980f, 0.51432586f, 0.47787288f, 0.44026864f, 0.40160376f, 0.36197138f, 0.32146698f, 0.28018814f, 0.23823431f, |
1665 | | 0.19570655f, 0.15270731f, 0.10934019f, 0.06570966f, 0.02192082f, 0.02243583f, 0.06725344f, 0.11190903f, 0.15629503f, |
1666 | | 0.20030449f, 0.24383141f, 0.28677091f, 0.32901955f, 0.37047556f, 0.41103905f, 0.45061234f, 0.48910004f, 0.52640945f, |
1667 | | 0.56245071f, 0.59713697f, 0.63038468f, 0.66211373f, 0.69224769f, 0.72071397f, 0.74744403f, 0.77237338f, 0.79544204f, |
1668 | | 0.81659436f, 0.83577949f, 0.85295111f, 0.86806792f, 0.88109350f, 0.89199638f, 0.90075046f, 0.90733445f, 0.91173267f, |
1669 | | 0.91393441f, 0.91393441f, 0.91173267f, 0.90733445f, 0.90075046f, 0.89199638f, 0.88109350f, 0.86806792f, 0.85295111f, |
1670 | | 0.83577949f, 0.81659436f, 0.79544204f, 0.77237338f, 0.74744403f, 0.72071397f, 0.69224769f, 0.66211373f, 0.63038468f, |
1671 | | 0.59713697f, 0.56245071f, 0.52640945f, 0.48910004f, 0.45061234f, 0.41103905f, 0.37047556f, 0.32901955f, 0.28677091f, |
1672 | | 0.24383141f, 0.20030449f, 0.15629503f, 0.11190903f, 0.06725344f, 0.02243583f, 0.02289679f, 0.06863521f, 0.11420828f, |
1673 | | 0.15950622f, 0.20441988f, 0.24884108f, 0.29266280f, 0.33577949f, 0.37808722f, 0.41948414f, 0.45987046f, 0.49914894f, |
1674 | | 0.53722489f, 0.57400662f, 0.60940558f, 0.64333636f, 0.67571729f, 0.70647043f, 0.73552155f, 0.76280075f, 0.78824228f, |
1675 | | 0.81178492f, 0.83337182f, 0.85295111f, 0.87047559f, 0.88590294f, 0.89919615f, 0.91032308f, 0.91925693f, 0.92597628f, |
1676 | | 0.93046480f, 0.93271178f, 0.93271178f, 0.93046480f, 0.92597628f, 0.91925693f, 0.91032308f, 0.89919615f, 0.88590294f, |
1677 | | 0.87047559f, 0.85295111f, 0.83337182f, 0.81178492f, 0.78824228f, 0.76280075f, 0.73552155f, 0.70647043f, 0.67571729f, |
1678 | | 0.64333636f, 0.60940558f, 0.57400662f, 0.53722489f, 0.49914894f, 0.45987046f, 0.41948414f, 0.37808722f, 0.33577949f, |
1679 | | 0.29266280f, 0.24884108f, 0.20441988f, 0.15950622f, 0.11420828f, 0.06863521f, 0.02289679f, 0.02330259f, 0.06985163f, |
1680 | | 0.11623239f, 0.16233313f, 0.20804280f, 0.25325128f, 0.29784966f, 0.34173048f, 0.38478804f, 0.42691863f, 0.46802074f, |
1681 | | 0.50799531f, 0.54674608f, 0.58417976f, 0.62020600f, 0.65473819f, 0.68769300f, 0.71899116f, 0.74855715f, 0.77631980f, |
1682 | | 0.80221230f, 0.82617211f, 0.84814167f, 0.86806792f, 0.88590294f, 0.90160376f, 0.91513252f, 0.92645669f, 0.93554890f, |
1683 | | 0.94238728f, 0.94695538f, 0.94924217f, 0.94924217f, 0.94695538f, 0.94238728f, 0.93554890f, 0.92645669f, 0.91513252f, |
1684 | | 0.90160376f, 0.88590294f, 0.86806792f, 0.84814167f, 0.82617211f, 0.80221230f, 0.77631980f, 0.74855715f, 0.71899116f, |
1685 | | 0.68769300f, 0.65473819f, 0.62020600f, 0.58417976f, 0.54674608f, 0.50799531f, 0.46802074f, 0.42691863f, 0.38478804f, |
1686 | | 0.34173048f, 0.29784966f, 0.25325128f, 0.20804280f, 0.16233313f, 0.11623239f, 0.06985163f, 0.02330259f, 0.02365225f, |
1687 | | 0.07089976f, 0.11797648f, 0.16476898f, 0.21116453f, 0.25705138f, 0.30231896f, 0.34685823f, 0.39056188f, 0.43332464f, |
1688 | | 0.47504348f, 0.51561791f, 0.55495018f, 0.59294546f, 0.62951237f, 0.66456270f, 0.69801199f, 0.72977978f, 0.75978941f, |
1689 | | 0.78796870f, 0.81424963f, 0.83856905f, 0.86086822f, 0.88109350f, 0.89919615f, 0.91513252f, 0.92886430f, 0.94035834f, |
1690 | | 0.94958699f, 0.95652801f, 0.96116465f, 0.96348578f, 0.96348578f, 0.96116465f, 0.95652801f, 0.94958699f, 0.94035834f, |
1691 | | 0.92886430f, 0.91513252f, 0.89919615f, 0.88109350f, 0.86086822f, 0.83856905f, 0.81424963f, 0.78796870f, 0.75978941f, |
1692 | | 0.72977978f, 0.69801199f, 0.66456270f, 0.62951237f, 0.59294546f, 0.55495018f, 0.51561791f, 0.47504348f, 0.43332464f, |
1693 | | 0.39056188f, 0.34685823f, 0.30231896f, 0.25705138f, 0.21116453f, 0.16476898f, 0.11797648f, 0.07089976f, 0.02365225f, |
1694 | | 0.02394493f, 0.07177710f, 0.11943635f, 0.16680788f, 0.21377754f, 0.26023221f, 0.30605996f, 0.35115036f, 0.39539480f, |
1695 | | 0.43868673f, 0.48092180f, 0.52199835f, 0.56181729f, 0.60028279f, 0.63730216f, 0.67278618f, 0.70664942f, 0.73881030f, |
1696 | | 0.76919127f, 0.79771924f, 0.82432544f, 0.84894574f, 0.87152088f, 0.89199638f, 0.91032308f, 0.92645669f, 0.94035834f, |
1697 | | 0.95199466f, 0.96133751f, 0.96836442f, 0.97305840f, 0.97540826f, 0.97540826f, 0.97305840f, 0.96836442f, 0.96133751f, |
1698 | | 0.95199466f, 0.94035834f, 0.92645669f, 0.91032308f, 0.89199638f, 0.87152088f, 0.84894574f, 0.82432544f, 0.79771924f, |
1699 | | 0.76919127f, 0.73881030f, 0.70664942f, 0.67278618f, 0.63730216f, 0.60028279f, 0.56181729f, 0.52199835f, 0.48092180f, |
1700 | | 0.43868673f, 0.39539480f, 0.35115036f, 0.30605996f, 0.26023221f, 0.21377754f, 0.16680788f, 0.11943635f, 0.07177710f, |
1701 | | 0.02394493f, 0.02417992f, 0.07248152f, 0.12060850f, 0.16844493f, 0.21587555f, 0.26278612f, 0.30906361f, 0.35459653f, |
1702 | | 0.39927521f, 0.44299200f, 0.48564157f, 0.52712119f, 0.56733096f, 0.60617393f, 0.64355659f, 0.67938888f, 0.71358448f, |
1703 | | 0.74606097f, 0.77674013f, 0.80554801f, 0.83241534f, 0.85727727f, 0.88007390f, 0.90075046f, 0.91925693f, 0.93554890f, |
1704 | | 0.94958699f, 0.96133751f, 0.97077203f, 0.97786790f, 0.98260796f, 0.98498088f, 0.98498088f, 0.98260796f, 0.97786790f, |
1705 | | 0.97077203f, 0.96133751f, 0.94958699f, 0.93554890f, 0.91925693f, 0.90075046f, 0.88007390f, 0.85727727f, 0.83241534f, |
1706 | | 0.80554801f, 0.77674013f, 0.74606097f, 0.71358448f, 0.67938888f, 0.64355659f, 0.60617393f, 0.56733096f, 0.52712119f, |
1707 | | 0.48564157f, 0.44299200f, 0.39927521f, 0.35459653f, 0.30906361f, 0.26278612f, 0.21587555f, 0.16844493f, 0.12060850f, |
1708 | | 0.07248152f, 0.02417992f, 0.02435667f, 0.07301132f, 0.12149009f, 0.16967617f, 0.21745349f, 0.26470694f, 0.31132272f, |
1709 | | 0.35718846f, 0.40219373f, 0.44623005f, 0.48919138f, 0.53097421f, 0.57147783f, 0.61060476f, 0.64826065f, 0.68435490f, |
1710 | | 0.71880043f, 0.75151426f, 0.78241771f, 0.81143618f, 0.83849984f, 0.86354351f, 0.88650686f, 0.90733445f, 0.92597628f, |
1711 | | 0.94238728f, 0.95652801f, 0.96836442f, 0.97786790f, 0.98501563f, 0.98979038f, 0.99218065f, 0.99218065f, 0.98979038f, |
1712 | | 0.98501563f, 0.97786790f, 0.96836442f, 0.95652801f, 0.94238728f, 0.92597628f, 0.90733445f, 0.88650686f, 0.86354351f, |
1713 | | 0.83849984f, 0.81143618f, 0.78241771f, 0.75151426f, 0.71880043f, 0.68435490f, 0.64826065f, 0.61060476f, 0.57147783f, |
1714 | | 0.53097421f, 0.48919138f, 0.44623005f, 0.40219373f, 0.35718846f, 0.31132272f, 0.26470694f, 0.21745349f, 0.16967617f, |
1715 | | 0.12149009f, 0.07301132f, 0.02435667f, 0.02447473f, 0.07336523f, 0.12207900f, 0.17049865f, 0.21850757f, 0.26599008f, |
1716 | | 0.31283182f, 0.35891989f, 0.40414330f, 0.44839308f, 0.49156266f, 0.53354800f, 0.57424802f, 0.61356461f, 0.65140307f, |
1717 | | 0.68767220f, 0.72228467f, 0.75515717f, 0.78621036f, 0.81536955f, 0.84256440f, 0.86772943f, 0.89080405f, 0.91173267f, |
1718 | | 0.93046480f, 0.94695538f, 0.96116465f, 0.97305840f, 0.98260796f, 0.98979038f, 0.99458826f, 0.99699008f, 0.99699008f, |
1719 | | 0.99458826f, 0.98979038f, 0.98260796f, 0.97305840f, 0.96116465f, 0.94695538f, 0.93046480f, 0.91173267f, 0.89080405f, |
1720 | | 0.86772943f, 0.84256440f, 0.81536955f, 0.78621036f, 0.75515717f, 0.72228467f, 0.68767220f, 0.65140307f, 0.61356461f, |
1721 | | 0.57424802f, 0.53354800f, 0.49156266f, 0.44839308f, 0.40414330f, 0.35891989f, 0.31283182f, 0.26599008f, 0.21850757f, |
1722 | | 0.17049865f, 0.12207900f, 0.07336523f, 0.02447473f, 0.02453384f, 0.07354241f, 0.12237380f, 0.17091040f, 0.21903525f, |
1723 | | 0.26663244f, 0.31358728f, 0.35978663f, 0.40511927f, 0.44947591f, 0.49274975f, 0.53483647f, 0.57563478f, 0.61504632f, |
1724 | | 0.65297610f, 0.68933284f, 0.72402894f, 0.75698078f, 0.78810900f, 0.81733859f, 0.84459913f, 0.86982495f, 0.89295530f, |
1725 | | 0.91393441f, 0.93271178f, 0.94924217f, 0.96348578f, 0.97540826f, 0.98498088f, 0.99218065f, 0.99699008f, 0.99939775f, |
1726 | | 0.99939775f, 0.99699008f, 0.99218065f, 0.98498088f, 0.97540826f, 0.96348578f, 0.94924217f, 0.93271178f, 0.91393441f, |
1727 | | 0.89295530f, 0.86982495f, 0.84459913f, 0.81733859f, 0.78810900f, 0.75698078f, 0.72402894f, 0.68933284f, 0.65297610f, |
1728 | | 0.61504632f, 0.57563478f, 0.53483647f, 0.49274975f, 0.44947591f, 0.40511927f, 0.35978663f, 0.31358728f, 0.26663244f, |
1729 | | 0.21903525f, 0.17091040f, 0.12237380f, 0.07354241f, 0.02453384f, 0.02453384f, 0.07354241f, 0.12237380f, 0.17091040f, |
1730 | | 0.21903525f, 0.26663244f, 0.31358728f, 0.35978663f, 0.40511927f, 0.44947591f, 0.49274975f, 0.53483647f, 0.57563478f, |
1731 | | 0.61504632f, 0.65297610f, 0.68933284f, 0.72402894f, 0.75698078f, 0.78810900f, 0.81733859f, 0.84459913f, 0.86982495f, |
1732 | | 0.89295530f, 0.91393441f, 0.93271178f, 0.94924217f, 0.96348578f, 0.97540826f, 0.98498088f, 0.99218065f, 0.99699008f, |
1733 | | 0.99939775f, 0.99939775f, 0.99699008f, 0.99218065f, 0.98498088f, 0.97540826f, 0.96348578f, 0.94924217f, 0.93271178f, |
1734 | | 0.91393441f, 0.89295530f, 0.86982495f, 0.84459913f, 0.81733859f, 0.78810900f, 0.75698078f, 0.72402894f, 0.68933284f, |
1735 | | 0.65297610f, 0.61504632f, 0.57563478f, 0.53483647f, 0.49274975f, 0.44947591f, 0.40511927f, 0.35978663f, 0.31358728f, |
1736 | | 0.26663244f, 0.21903525f, 0.17091040f, 0.12237380f, 0.07354241f, 0.02453384f, 0.02447473f, 0.07336523f, 0.12207900f, |
1737 | | 0.17049865f, 0.21850757f, 0.26599008f, 0.31283182f, 0.35891989f, 0.40414330f, 0.44839308f, 0.49156266f, 0.53354800f, |
1738 | | 0.57424802f, 0.61356461f, 0.65140307f, 0.68767220f, 0.72228467f, 0.75515717f, 0.78621036f, 0.81536955f, 0.84256440f, |
1739 | | 0.86772943f, 0.89080405f, 0.91173267f, 0.93046480f, 0.94695538f, 0.96116465f, 0.97305840f, 0.98260796f, 0.98979038f, |
1740 | | 0.99458826f, 0.99699008f, 0.99699008f, 0.99458826f, 0.98979038f, 0.98260796f, 0.97305840f, 0.96116465f, 0.94695538f, |
1741 | | 0.93046480f, 0.91173267f, 0.89080405f, 0.86772943f, 0.84256440f, 0.81536955f, 0.78621036f, 0.75515717f, 0.72228467f, |
1742 | | 0.68767220f, 0.65140307f, 0.61356461f, 0.57424802f, 0.53354800f, 0.49156266f, 0.44839308f, 0.40414330f, 0.35891989f, |
1743 | | 0.31283182f, 0.26599008f, 0.21850757f, 0.17049865f, 0.12207900f, 0.07336523f, 0.02447473f, 0.02435667f, 0.07301132f, |
1744 | | 0.12149009f, 0.16967617f, 0.21745349f, 0.26470694f, 0.31132272f, 0.35718846f, 0.40219373f, 0.44623005f, 0.48919138f, |
1745 | | 0.53097421f, 0.57147783f, 0.61060476f, 0.64826065f, 0.68435490f, 0.71880043f, 0.75151426f, 0.78241771f, 0.81143618f, |
1746 | | 0.83849984f, 0.86354351f, 0.88650686f, 0.90733445f, 0.92597628f, 0.94238728f, 0.95652801f, 0.96836442f, 0.97786790f, |
1747 | | 0.98501563f, 0.98979038f, 0.99218065f, 0.99218065f, 0.98979038f, 0.98501563f, 0.97786790f, 0.96836442f, 0.95652801f, |
1748 | | 0.94238728f, 0.92597628f, 0.90733445f, 0.88650686f, 0.86354351f, 0.83849984f, 0.81143618f, 0.78241771f, 0.75151426f, |
1749 | | 0.71880043f, 0.68435490f, 0.64826065f, 0.61060476f, 0.57147783f, 0.53097421f, 0.48919138f, 0.44623005f, 0.40219373f, |
1750 | | 0.35718846f, 0.31132272f, 0.26470694f, 0.21745349f, 0.16967617f, 0.12149009f, 0.07301132f, 0.02435667f, 0.02417992f, |
1751 | | 0.07248152f, 0.12060850f, 0.16844493f, 0.21587555f, 0.26278612f, 0.30906361f, 0.35459653f, 0.39927521f, 0.44299200f, |
1752 | | 0.48564157f, 0.52712119f, 0.56733096f, 0.60617393f, 0.64355659f, 0.67938888f, 0.71358448f, 0.74606097f, 0.77674013f, |
1753 | | 0.80554801f, 0.83241534f, 0.85727727f, 0.88007390f, 0.90075046f, 0.91925693f, 0.93554890f, 0.94958699f, 0.96133751f, |
1754 | | 0.97077203f, 0.97786790f, 0.98260796f, 0.98498088f, 0.98498088f, 0.98260796f, 0.97786790f, 0.97077203f, 0.96133751f, |
1755 | | 0.94958699f, 0.93554890f, 0.91925693f, 0.90075046f, 0.88007390f, 0.85727727f, 0.83241534f, 0.80554801f, 0.77674013f, |
1756 | | 0.74606097f, 0.71358448f, 0.67938888f, 0.64355659f, 0.60617393f, 0.56733096f, 0.52712119f, 0.48564157f, 0.44299200f, |
1757 | | 0.39927521f, 0.35459653f, 0.30906361f, 0.26278612f, 0.21587555f, 0.16844493f, 0.12060850f, 0.07248152f, 0.02417992f, |
1758 | | 0.02394493f, 0.07177710f, 0.11943635f, 0.16680788f, 0.21377754f, 0.26023221f, 0.30605996f, 0.35115036f, 0.39539480f, |
1759 | | 0.43868673f, 0.48092180f, 0.52199835f, 0.56181729f, 0.60028279f, 0.63730216f, 0.67278618f, 0.70664942f, 0.73881030f, |
1760 | | 0.76919127f, 0.79771924f, 0.82432544f, 0.84894574f, 0.87152088f, 0.89199638f, 0.91032308f, 0.92645669f, 0.94035834f, |
1761 | | 0.95199466f, 0.96133751f, 0.96836442f, 0.97305840f, 0.97540826f, 0.97540826f, 0.97305840f, 0.96836442f, 0.96133751f, |
1762 | | 0.95199466f, 0.94035834f, 0.92645669f, 0.91032308f, 0.89199638f, 0.87152088f, 0.84894574f, 0.82432544f, 0.79771924f, |
1763 | | 0.76919127f, 0.73881030f, 0.70664942f, 0.67278618f, 0.63730216f, 0.60028279f, 0.56181729f, 0.52199835f, 0.48092180f, |
1764 | | 0.43868673f, 0.39539480f, 0.35115036f, 0.30605996f, 0.26023221f, 0.21377754f, 0.16680788f, 0.11943635f, 0.07177710f, |
1765 | | 0.02394493f, 0.02365225f, 0.07089976f, 0.11797648f, 0.16476898f, 0.21116453f, 0.25705138f, 0.30231896f, 0.34685823f, |
1766 | | 0.39056188f, 0.43332464f, 0.47504348f, 0.51561791f, 0.55495018f, 0.59294546f, 0.62951237f, 0.66456270f, 0.69801199f, |
1767 | | 0.72977978f, 0.75978941f, 0.78796870f, 0.81424963f, 0.83856905f, 0.86086822f, 0.88109350f, 0.89919615f, 0.91513252f, |
1768 | | 0.92886430f, 0.94035834f, 0.94958699f, 0.95652801f, 0.96116465f, 0.96348578f, 0.96348578f, 0.96116465f, 0.95652801f, |
1769 | | 0.94958699f, 0.94035834f, 0.92886430f, 0.91513252f, 0.89919615f, 0.88109350f, 0.86086822f, 0.83856905f, 0.81424963f, |
1770 | | 0.78796870f, 0.75978941f, 0.72977978f, 0.69801199f, 0.66456270f, 0.62951237f, 0.59294546f, 0.55495018f, 0.51561791f, |
1771 | | 0.47504348f, 0.43332464f, 0.39056188f, 0.34685823f, 0.30231896f, 0.25705138f, 0.21116453f, 0.16476898f, 0.11797648f, |
1772 | | 0.07089976f, 0.02365225f, 0.02330259f, 0.06985163f, 0.11623239f, 0.16233313f, 0.20804280f, 0.25325128f, 0.29784966f, |
1773 | | 0.34173048f, 0.38478804f, 0.42691863f, 0.46802074f, 0.50799531f, 0.54674608f, 0.58417976f, 0.62020600f, 0.65473819f, |
1774 | | 0.68769300f, 0.71899116f, 0.74855715f, 0.77631980f, 0.80221230f, 0.82617211f, 0.84814167f, 0.86806792f, 0.88590294f, |
1775 | | 0.90160376f, 0.91513252f, 0.92645669f, 0.93554890f, 0.94238728f, 0.94695538f, 0.94924217f, 0.94924217f, 0.94695538f, |
1776 | | 0.94238728f, 0.93554890f, 0.92645669f, 0.91513252f, 0.90160376f, 0.88590294f, 0.86806792f, 0.84814167f, 0.82617211f, |
1777 | | 0.80221230f, 0.77631980f, 0.74855715f, 0.71899116f, 0.68769300f, 0.65473819f, 0.62020600f, 0.58417976f, 0.54674608f, |
1778 | | 0.50799531f, 0.46802074f, 0.42691863f, 0.38478804f, 0.34173048f, 0.29784966f, 0.25325128f, 0.20804280f, 0.16233313f, |
1779 | | 0.11623239f, 0.06985163f, 0.02330259f, 0.02289679f, 0.06863521f, 0.11420828f, 0.15950622f, 0.20441988f, 0.24884108f, |
1780 | | 0.29266280f, 0.33577949f, 0.37808722f, 0.41948414f, 0.45987046f, 0.49914894f, 0.53722489f, 0.57400662f, 0.60940558f, |
1781 | | 0.64333636f, 0.67571729f, 0.70647043f, 0.73552155f, 0.76280075f, 0.78824228f, 0.81178492f, 0.83337182f, 0.85295111f, |
1782 | | 0.87047559f, 0.88590294f, 0.89919615f, 0.91032308f, 0.91925693f, 0.92597628f, 0.93046480f, 0.93271178f, 0.93271178f, |
1783 | | 0.93046480f, 0.92597628f, 0.91925693f, 0.91032308f, 0.89919615f, 0.88590294f, 0.87047559f, 0.85295111f, 0.83337182f, |
1784 | | 0.81178492f, 0.78824228f, 0.76280075f, 0.73552155f, 0.70647043f, 0.67571729f, 0.64333636f, 0.60940558f, 0.57400662f, |
1785 | | 0.53722489f, 0.49914894f, 0.45987046f, 0.41948414f, 0.37808722f, 0.33577949f, 0.29266280f, 0.24884108f, 0.20441988f, |
1786 | | 0.15950622f, 0.11420828f, 0.06863521f, 0.02289679f, 0.02243583f, 0.06725344f, 0.11190903f, 0.15629503f, 0.20030449f, |
1787 | | 0.24383141f, 0.28677091f, 0.32901955f, 0.37047556f, 0.41103905f, 0.45061234f, 0.48910004f, 0.52640945f, 0.56245071f, |
1788 | | 0.59713697f, 0.63038468f, 0.66211373f, 0.69224769f, 0.72071397f, 0.74744403f, 0.77237338f, 0.79544204f, 0.81659436f, |
1789 | | 0.83577949f, 0.85295111f, 0.86806792f, 0.88109350f, 0.89199638f, 0.90075046f, 0.90733445f, 0.91173267f, 0.91393441f, |
1790 | | 0.91393441f, 0.91173267f, 0.90733445f, 0.90075046f, 0.89199638f, 0.88109350f, 0.86806792f, 0.85295111f, 0.83577949f, |
1791 | | 0.81659436f, 0.79544204f, 0.77237338f, 0.74744403f, 0.72071397f, 0.69224769f, 0.66211373f, 0.63038468f, 0.59713697f, |
1792 | | 0.56245071f, 0.52640945f, 0.48910004f, 0.45061234f, 0.41103905f, 0.37047556f, 0.32901955f, 0.28677091f, 0.24383141f, |
1793 | | 0.20030449f, 0.15629503f, 0.11190903f, 0.06725344f, 0.02243583f, 0.02192082f, 0.06570966f, 0.10934019f, 0.15270731f, |
1794 | | 0.19570655f, 0.23823431f, 0.28018814f, 0.32146698f, 0.36197138f, 0.40160376f, 0.44026864f, 0.47787288f, 0.51432586f, |
1795 | | 0.54953980f, 0.58342987f, 0.61591434f, 0.64691508f, 0.67635733f, 0.70417017f, 0.73028660f, 0.75464374f, 0.77718282f, |
1796 | | 0.79784966f, 0.81659436f, 0.83337182f, 0.84814167f, 0.86086822f, 0.87152088f, 0.88007390f, 0.88650686f, 0.89080405f, |
1797 | | 0.89295530f, 0.89295530f, 0.89080405f, 0.88650686f, 0.88007390f, 0.87152088f, 0.86086822f, 0.84814167f, 0.83337182f, |
1798 | | 0.81659436f, 0.79784966f, 0.77718282f, 0.75464374f, 0.73028660f, 0.70417017f, 0.67635733f, 0.64691508f, 0.61591434f, |
1799 | | 0.58342987f, 0.54953980f, 0.51432586f, 0.47787288f, 0.44026864f, 0.40160376f, 0.36197138f, 0.32146698f, 0.28018814f, |
1800 | | 0.23823431f, 0.19570655f, 0.15270731f, 0.10934019f, 0.06570966f, 0.02192082f, 0.02135300f, 0.06400757f, 0.10650793f, |
1801 | | 0.14875172f, 0.19063714f, 0.23206329f, 0.27293041f, 0.31313998f, 0.35259521f, 0.39120096f, 0.42886430f, 0.46549448f, |
1802 | | 0.50100321f, 0.53530502f, 0.56831717f, 0.59996027f, 0.63015795f, 0.65883756f, 0.68592995f, 0.71136993f, 0.73509610f, |
1803 | | 0.75705135f, 0.77718282f, 0.79544204f, 0.81178492f, 0.82617211f, 0.83856905f, 0.84894574f, 0.85727727f, 0.86354351f, |
1804 | | 0.86772943f, 0.86982495f, 0.86982495f, 0.86772943f, 0.86354351f, 0.85727727f, 0.84894574f, 0.83856905f, 0.82617211f, |
1805 | | 0.81178492f, 0.79544204f, 0.77718282f, 0.75705135f, 0.73509610f, 0.71136993f, 0.68592995f, 0.65883756f, 0.63015795f, |
1806 | | 0.59996027f, 0.56831717f, 0.53530502f, 0.50100321f, 0.46549448f, 0.42886430f, 0.39120096f, 0.35259521f, 0.31313998f, |
1807 | | 0.27293041f, 0.23206329f, 0.19063714f, 0.14875172f, 0.10650793f, 0.06400757f, 0.02135300f, 0.02073374f, 0.06215128f, |
1808 | | 0.10341910f, 0.14443776f, 0.18510847f, 0.22533323f, 0.26501513f, 0.30405861f, 0.34236956f, 0.37985572f, 0.41642681f, |
1809 | | 0.45199466f, 0.48647359f, 0.51978058f, 0.55183542f, 0.58256078f, 0.61188275f, 0.63973057f, 0.66603726f, 0.69073945f, |
1810 | | 0.71377754f, 0.73509610f, 0.75464374f, 0.77237338f, 0.78824228f, 0.80221230f, 0.81424963f, 0.82432544f, 0.83241534f, |
1811 | | 0.83849984f, 0.84256440f, 0.84459913f, 0.84459913f, 0.84256440f, 0.83849984f, 0.83241534f, 0.82432544f, 0.81424963f, |
1812 | | 0.80221230f, 0.78824228f, 0.77237338f, 0.75464374f, 0.73509610f, 0.71377754f, 0.69073945f, 0.66603726f, 0.63973057f, |
1813 | | 0.61188275f, 0.58256078f, 0.55183542f, 0.51978058f, 0.48647359f, 0.45199466f, 0.41642681f, 0.37985572f, 0.34236956f, |
1814 | | 0.30405861f, 0.26501513f, 0.22533323f, 0.18510847f, 0.14443776f, 0.10341910f, 0.06215128f, 0.02073374f, 0.02006454f, |
1815 | | 0.06014527f, 0.10008111f, 0.13977584f, 0.17913385f, 0.21806030f, 0.25646144f, 0.29424471f, 0.33131915f, 0.36759540f, |
1816 | | 0.40298608f, 0.43740594f, 0.47077203f, 0.50300401f, 0.53402418f, 0.56375790f, 0.59213340f, 0.61908245f, 0.64454007f, |
1817 | | 0.66844493f, 0.69073945f, 0.71136993f, 0.73028660f, 0.74744403f, 0.76280075f, 0.77631980f, 0.78796870f, 0.79771924f, |
1818 | | 0.80554801f, 0.81143618f, 0.81536955f, 0.81733859f, 0.81733859f, 0.81536955f, 0.81143618f, 0.80554801f, 0.79771924f, |
1819 | | 0.78796870f, 0.77631980f, 0.76280075f, 0.74744403f, 0.73028660f, 0.71136993f, 0.69073945f, 0.66844493f, 0.64454007f, |
1820 | | 0.61908245f, 0.59213340f, 0.56375790f, 0.53402418f, 0.50300401f, 0.47077203f, 0.43740594f, 0.40298608f, 0.36759540f, |
1821 | | 0.33131915f, 0.29424471f, 0.25646144f, 0.21806030f, 0.17913385f, 0.13977584f, 0.10008111f, 0.06014527f, 0.02006454f, |
1822 | | 0.01934699f, 0.05799436f, 0.09650202f, 0.13477719f, 0.17272767f, 0.21026205f, 0.24728988f, 0.28372195f, 0.31947055f, |
1823 | | 0.35444948f, 0.38857454f, 0.42176345f, 0.45393634f, 0.48501563f, 0.51492649f, 0.54359680f, 0.57095760f, 0.59694290f, |
1824 | | 0.62149006f, 0.64454007f, 0.66603726f, 0.68592995f, 0.70417017f, 0.72071397f, 0.73552155f, 0.74855715f, 0.75978941f, |
1825 | | 0.76919127f, 0.77674013f, 0.78241771f, 0.78621036f, 0.78810900f, 0.78810900f, 0.78621036f, 0.78241771f, 0.77674013f, |
1826 | | 0.76919127f, 0.75978941f, 0.74855715f, 0.73552155f, 0.72071397f, 0.70417017f, 0.68592995f, 0.66603726f, 0.64454007f, |
1827 | | 0.62149006f, 0.59694290f, 0.57095760f, 0.54359680f, 0.51492649f, 0.48501563f, 0.45393634f, 0.42176345f, 0.38857454f, |
1828 | | 0.35444948f, 0.31947055f, 0.28372195f, 0.24728988f, 0.21026205f, 0.17272767f, 0.13477719f, 0.09650202f, 0.05799436f, |
1829 | | 0.01934699f, 0.01858284f, 0.05570374f, 0.09269045f, 0.12945385f, 0.16590540f, 0.20195726f, 0.23752259f, 0.27251571f, |
1830 | | 0.30685231f, 0.34044969f, 0.37322688f, 0.40510494f, 0.43600705f, 0.46585882f, 0.49458826f, 0.52212620f, 0.54840630f, |
1831 | | 0.57336521f, 0.59694290f, 0.61908245f, 0.63973057f, 0.65883756f, 0.67635733f, 0.69224769f, 0.70647043f, 0.71899116f, |
1832 | | 0.72977978f, 0.73881030f, 0.74606097f, 0.75151426f, 0.75515717f, 0.75698078f, 0.75698078f, 0.75515717f, 0.75151426f, |
1833 | | 0.74606097f, 0.73881030f, 0.72977978f, 0.71899116f, 0.70647043f, 0.69224769f, 0.67635733f, 0.65883756f, 0.63973057f, |
1834 | | 0.61908245f, 0.59694290f, 0.57336521f, 0.54840630f, 0.52212620f, 0.49458826f, 0.46585882f, 0.43600705f, 0.40510494f, |
1835 | | 0.37322688f, 0.34044969f, 0.30685231f, 0.27251571f, 0.23752259f, 0.20195726f, 0.16590540f, 0.12945385f, 0.09269045f, |
1836 | | 0.05570374f, 0.01858284f, 0.01777391f, 0.05327892f, 0.08865558f, 0.12381865f, 0.15868343f, 0.19316594f, 0.22718309f, |
1837 | | 0.26065293f, 0.29349485f, 0.32562968f, 0.35698009f, 0.38747045f, 0.41702741f, 0.44557968f, 0.47305852f, 0.49939772f, |
1838 | | 0.52453381f, 0.54840630f, 0.57095760f, 0.59213340f, 0.61188275f, 0.63015795f, 0.64691508f, 0.66211373f, 0.67571729f, |
1839 | | 0.68769300f, 0.69801199f, 0.70664942f, 0.71358448f, 0.71880043f, 0.72228467f, 0.72402894f, 0.72402894f, 0.72228467f, |
1840 | | 0.71880043f, 0.71358448f, 0.70664942f, 0.69801199f, 0.68769300f, 0.67571729f, 0.66211373f, 0.64691508f, 0.63015795f, |
1841 | | 0.61188275f, 0.59213340f, 0.57095760f, 0.54840630f, 0.52453381f, 0.49939772f, 0.47305852f, 0.44557968f, 0.41702741f, |
1842 | | 0.38747045f, 0.35698009f, 0.32562968f, 0.29349485f, 0.26065293f, 0.22718309f, 0.19316594f, 0.15868343f, 0.12381865f, |
1843 | | 0.08865558f, 0.05327892f, 0.01777391f, 0.01692217f, 0.05072575f, 0.08440712f, 0.11788516f, 0.15107919f, 0.18390927f, |
1844 | | 0.21629629f, 0.24816222f, 0.27943033f, 0.31002524f, 0.33987328f, 0.36890256f, 0.39704308f, 0.42422712f, 0.45038915f, |
1845 | | 0.47546616f, 0.49939772f, 0.52212620f, 0.54359680f, 0.56375790f, 0.58256078f, 0.59996027f, 0.61591434f, 0.63038468f, |
1846 | | 0.64333636f, 0.65473819f, 0.66456270f, 0.67278618f, 0.67938888f, 0.68435490f, 0.68767220f, 0.68933284f, 0.68933284f, |
1847 | | 0.68767220f, 0.68435490f, 0.67938888f, 0.67278618f, 0.66456270f, 0.65473819f, 0.64333636f, 0.63038468f, 0.61591434f, |
1848 | | 0.59996027f, 0.58256078f, 0.56375790f, 0.54359680f, 0.52212620f, 0.49939772f, 0.47546616f, 0.45038915f, 0.42422712f, |
1849 | | 0.39704308f, 0.36890256f, 0.33987328f, 0.31002524f, 0.27943033f, 0.24816222f, 0.21629629f, 0.18390927f, 0.15107919f, |
1850 | | 0.11788516f, 0.08440712f, 0.05072575f, 0.01692217f, 0.01602966f, 0.04805037f, 0.07995533f, 0.11166766f, 0.14311098f, |
1851 | | 0.17420954f, 0.20488839f, 0.23507367f, 0.26469263f, 0.29367390f, 0.32194772f, 0.34944591f, 0.37610227f, 0.40185258f, |
1852 | | 0.42663476f, 0.45038915f, 0.47305852f, 0.49458826f, 0.51492649f, 0.53402418f, 0.55183542f, 0.56831717f, 0.58342987f, |
1853 | | 0.59713697f, 0.60940558f, 0.62020600f, 0.62951237f, 0.63730216f, 0.64355659f, 0.64826065f, 0.65140307f, 0.65297610f, |
1854 | | 0.65297610f, 0.65140307f, 0.64826065f, 0.64355659f, 0.63730216f, 0.62951237f, 0.62020600f, 0.60940558f, 0.59713697f, |
1855 | | 0.58342987f, 0.56831717f, 0.55183542f, 0.53402418f, 0.51492649f, 0.49458826f, 0.47305852f, 0.45038915f, 0.42663476f, |
1856 | | 0.40185258f, 0.37610227f, 0.34944591f, 0.32194772f, 0.29367390f, 0.26469263f, 0.23507367f, 0.20488839f, 0.17420954f, |
1857 | | 0.14311098f, 0.11166766f, 0.07995533f, 0.04805037f, 0.01602966f, 0.01509854f, 0.04525924f, 0.07531092f, 0.10518116f, |
1858 | | 0.13479801f, 0.16409011f, 0.19298692f, 0.22141880f, 0.24931726f, 0.27661508f, 0.30324653f, 0.32914743f, 0.35425538f, |
1859 | | 0.37850991f, 0.40185258f, 0.42422712f, 0.44557968f, 0.46585882f, 0.48501563f, 0.50300401f, 0.51978058f, 0.53530502f, |
1860 | | 0.54953980f, 0.56245071f, 0.57400662f, 0.58417976f, 0.59294546f, 0.60028279f, 0.60617393f, 0.61060476f, 0.61356461f, |
1861 | | 0.61504632f, 0.61504632f, 0.61356461f, 0.61060476f, 0.60617393f, 0.60028279f, 0.59294546f, 0.58417976f, 0.57400662f, |
1862 | | 0.56245071f, 0.54953980f, 0.53530502f, 0.51978058f, 0.50300401f, 0.48501563f, 0.46585882f, 0.44557968f, 0.42422712f, |
1863 | | 0.40185258f, 0.37850991f, 0.35425538f, 0.32914743f, 0.30324653f, 0.27661508f, 0.24931726f, 0.22141880f, 0.19298692f, |
1864 | | 0.16409011f, 0.13479801f, 0.10518116f, 0.07531092f, 0.04525924f, 0.01509854f, 0.01413104f, 0.04235908f, 0.07048507f, |
1865 | | 0.09844126f, 0.12616029f, 0.15357539f, 0.18062052f, 0.20723051f, 0.23334126f, 0.25888988f, 0.28381482f, 0.30805603f, |
1866 | | 0.33155507f, 0.35425538f, 0.37610227f, 0.39704308f, 0.41702741f, 0.43600705f, 0.45393634f, 0.47077203f, 0.48647359f, |
1867 | | 0.50100321f, 0.51432586f, 0.52640945f, 0.53722489f, 0.54674608f, 0.55495018f, 0.56181729f, 0.56733096f, 0.57147783f, |
1868 | | 0.57424802f, 0.57563478f, 0.57563478f, 0.57424802f, 0.57147783f, 0.56733096f, 0.56181729f, 0.55495018f, 0.54674608f, |
1869 | | 0.53722489f, 0.52640945f, 0.51432586f, 0.50100321f, 0.48647359f, 0.47077203f, 0.45393634f, 0.43600705f, 0.41702741f, |
1870 | | 0.39704308f, 0.37610227f, 0.35425538f, 0.33155507f, 0.30805603f, 0.28381482f, 0.25888988f, 0.23334126f, 0.20723051f, |
1871 | | 0.18062052f, 0.15357539f, 0.12616029f, 0.09844126f, 0.07048507f, 0.04235908f, 0.01413104f, 0.01312950f, 0.03935686f, |
1872 | | 0.06548942f, 0.09146421f, 0.11721864f, 0.14269069f, 0.16781898f, 0.19254299f, 0.21680313f, 0.24054100f, 0.26369935f, |
1873 | | 0.28622246f, 0.30805603f, 0.32914743f, 0.34944591f, 0.36890256f, 0.38747045f, 0.40510494f, 0.42176345f, 0.43740594f, |
1874 | | 0.45199466f, 0.46549448f, 0.47787288f, 0.48910004f, 0.49914894f, 0.50799531f, 0.51561791f, 0.52199835f, 0.52712119f, |
1875 | | 0.53097421f, 0.53354800f, 0.53483647f, 0.53483647f, 0.53354800f, 0.53097421f, 0.52712119f, 0.52199835f, 0.51561791f, |
1876 | | 0.50799531f, 0.49914894f, 0.48910004f, 0.47787288f, 0.46549448f, 0.45199466f, 0.43740594f, 0.42176345f, 0.40510494f, |
1877 | | 0.38747045f, 0.36890256f, 0.34944591f, 0.32914743f, 0.30805603f, 0.28622246f, 0.26369935f, 0.24054100f, 0.21680313f, |
1878 | | 0.19254299f, 0.16781898f, 0.14269069f, 0.11721864f, 0.09146421f, 0.06548942f, 0.03935686f, 0.01312950f, 0.01209633f, |
1879 | | 0.03625984f, 0.06033600f, 0.08426680f, 0.10799461f, 0.13146223f, 0.15461317f, 0.17739162f, 0.19974270f, 0.22161262f, |
1880 | | 0.24294862f, 0.26369935f, 0.28381482f, 0.30324653f, 0.32194772f, 0.33987328f, 0.35698009f, 0.37322688f, 0.38857454f, |
1881 | | 0.40298608f, 0.41642681f, 0.42886430f, 0.44026864f, 0.45061234f, 0.45987046f, 0.46802074f, 0.47504348f, 0.48092180f, |
1882 | | 0.48564157f, 0.48919138f, 0.49156266f, 0.49274975f, 0.49274975f, 0.49156266f, 0.48919138f, 0.48564157f, 0.48092180f, |
1883 | | 0.47504348f, 0.46802074f, 0.45987046f, 0.45061234f, 0.44026864f, 0.42886430f, 0.41642681f, 0.40298608f, 0.38857454f, |
1884 | | 0.37322688f, 0.35698009f, 0.33987328f, 0.32194772f, 0.30324653f, 0.28381482f, 0.26369935f, 0.24294862f, 0.22161262f, |
1885 | | 0.19974270f, 0.17739162f, 0.15461317f, 0.13146223f, 0.10799461f, 0.08426680f, 0.06033600f, 0.03625984f, 0.01209633f, |
1886 | | 0.01103401f, 0.03307546f, 0.05503723f, 0.07686640f, 0.09851040f, 0.11991708f, 0.14103487f, 0.16181289f, 0.18220109f, |
1887 | | 0.20215034f, 0.22161262f, 0.24054100f, 0.25888988f, 0.27661508f, 0.29367390f, 0.31002524f, 0.32562968f, 0.34044969f, |
1888 | | 0.35444948f, 0.36759540f, 0.37985572f, 0.39120096f, 0.40160376f, 0.41103905f, 0.41948414f, 0.42691863f, 0.43332464f, |
1889 | | 0.43868673f, 0.44299200f, 0.44623005f, 0.44839308f, 0.44947591f, 0.44947591f, 0.44839308f, 0.44623005f, 0.44299200f, |
1890 | | 0.43868673f, 0.43332464f, 0.42691863f, 0.41948414f, 0.41103905f, 0.40160376f, 0.39120096f, 0.37985572f, 0.36759540f, |
1891 | | 0.35444948f, 0.34044969f, 0.32562968f, 0.31002524f, 0.29367390f, 0.27661508f, 0.25888988f, 0.24054100f, 0.22161262f, |
1892 | | 0.20215034f, 0.18220109f, 0.16181289f, 0.14103487f, 0.11991708f, 0.09851040f, 0.07686640f, 0.05503723f, 0.03307546f, |
1893 | | 0.01103401f, 0.00994512f, 0.02981140f, 0.04960586f, 0.06928082f, 0.08878887f, 0.10808302f, 0.12711680f, 0.14584434f, |
1894 | | 0.16422053f, 0.18220109f, 0.19974270f, 0.21680313f, 0.23334126f, 0.24931726f, 0.26469263f, 0.27943033f, 0.29349485f, |
1895 | | 0.30685231f, 0.31947055f, 0.33131915f, 0.34236956f, 0.35259521f, 0.36197138f, 0.37047556f, 0.37808722f, 0.38478804f, |
1896 | | 0.39056188f, 0.39539480f, 0.39927521f, 0.40219373f, 0.40414330f, 0.40511927f, 0.40511927f, 0.40414330f, 0.40219373f, |
1897 | | 0.39927521f, 0.39539480f, 0.39056188f, 0.38478804f, 0.37808722f, 0.37047556f, 0.36197138f, 0.35259521f, 0.34236956f, |
1898 | | 0.33131915f, 0.31947055f, 0.30685231f, 0.29349485f, 0.27943033f, 0.26469263f, 0.24931726f, 0.23334126f, 0.21680313f, |
1899 | | 0.19974270f, 0.18220109f, 0.16422053f, 0.14584434f, 0.12711680f, 0.10808302f, 0.08878887f, 0.06928082f, 0.04960586f, |
1900 | | 0.02981140f, 0.00994512f, 0.00883227f, 0.02647552f, 0.04405500f, 0.06152834f, 0.07885345f, 0.09598859f, 0.11289250f, |
1901 | | 0.12952444f, 0.14584434f, 0.16181289f, 0.17739162f, 0.19254299f, 0.20723051f, 0.22141880f, 0.23507367f, 0.24816222f, |
1902 | | 0.26065293f, 0.27251571f, 0.28372195f, 0.29424471f, 0.30405861f, 0.31313998f, 0.32146698f, 0.32901955f, 0.33577949f, |
1903 | | 0.34173048f, 0.34685823f, 0.35115036f, 0.35459653f, 0.35718846f, 0.35891989f, 0.35978663f, 0.35978663f, 0.35891989f, |
1904 | | 0.35718846f, 0.35459653f, 0.35115036f, 0.34685823f, 0.34173048f, 0.33577949f, 0.32901955f, 0.32146698f, 0.31313998f, |
1905 | | 0.30405861f, 0.29424471f, 0.28372195f, 0.27251571f, 0.26065293f, 0.24816222f, 0.23507367f, 0.22141880f, 0.20723051f, |
1906 | | 0.19254299f, 0.17739162f, 0.16181289f, 0.14584434f, 0.12952444f, 0.11289250f, 0.09598859f, 0.07885345f, 0.06152834f, |
1907 | | 0.04405500f, 0.02647552f, 0.00883227f, 0.00769814f, 0.02307586f, 0.03839799f, 0.05362762f, 0.06872806f, 0.08366292f, |
1908 | | 0.09839623f, 0.11289250f, 0.12711680f, 0.14103487f, 0.15461317f, 0.16781898f, 0.18062052f, 0.19298692f, 0.20488839f, |
1909 | | 0.21629629f, 0.22718309f, 0.23752259f, 0.24728988f, 0.25646144f, 0.26501513f, 0.27293041f, 0.28018814f, 0.28677091f, |
1910 | | 0.29266280f, 0.29784966f, 0.30231896f, 0.30605996f, 0.30906361f, 0.31132272f, 0.31283182f, 0.31358728f, 0.31358728f, |
1911 | | 0.31283182f, 0.31132272f, 0.30906361f, 0.30605996f, 0.30231896f, 0.29784966f, 0.29266280f, 0.28677091f, 0.28018814f, |
1912 | | 0.27293041f, 0.26501513f, 0.25646144f, 0.24728988f, 0.23752259f, 0.22718309f, 0.21629629f, 0.20488839f, 0.19298692f, |
1913 | | 0.18062052f, 0.16781898f, 0.15461317f, 0.14103487f, 0.12711680f, 0.11289250f, 0.09839623f, 0.08366292f, 0.06872806f, |
1914 | | 0.05362762f, 0.03839799f, 0.02307586f, 0.00769814f, 0.00654546f, 0.01962061f, 0.03264849f, 0.04559772f, 0.05843709f, |
1915 | | 0.07113569f, 0.08366292f, 0.09598859f, 0.10808302f, 0.11991708f, 0.13146223f, 0.14269069f, 0.15357539f, 0.16409011f, |
1916 | | 0.17420954f, 0.18390927f, 0.19316594f, 0.20195726f, 0.21026205f, 0.21806030f, 0.22533323f, 0.23206329f, 0.23823431f, |
1917 | | 0.24383141f, 0.24884108f, 0.25325128f, 0.25705138f, 0.26023221f, 0.26278612f, 0.26470694f, 0.26599008f, 0.26663244f, |
1918 | | 0.26663244f, 0.26599008f, 0.26470694f, 0.26278612f, 0.26023221f, 0.25705138f, 0.25325128f, 0.24884108f, 0.24383141f, |
1919 | | 0.23823431f, 0.23206329f, 0.22533323f, 0.21806030f, 0.21026205f, 0.20195726f, 0.19316594f, 0.18390927f, 0.17420954f, |
1920 | | 0.16409011f, 0.15357539f, 0.14269069f, 0.13146223f, 0.11991708f, 0.10808302f, 0.09598859f, 0.08366292f, 0.07113569f, |
1921 | | 0.05843709f, 0.04559772f, 0.03264849f, 0.01962061f, 0.00654546f, 0.00537701f, 0.01611809f, 0.02682033f, 0.03745796f, |
1922 | | 0.04800535f, 0.05843709f, 0.06872806f, 0.07885345f, 0.08878887f, 0.09851040f, 0.10799461f, 0.11721864f, 0.12616029f, |
1923 | | 0.13479801f, 0.14311098f, 0.15107919f, 0.15868343f, 0.16590540f, 0.17272767f, 0.17913385f, 0.18510847f, 0.19063714f, |
1924 | | 0.19570655f, 0.20030449f, 0.20441988f, 0.20804280f, 0.21116453f, 0.21377754f, 0.21587555f, 0.21745349f, 0.21850757f, |
1925 | | 0.21903525f, 0.21903525f, 0.21850757f, 0.21745349f, 0.21587555f, 0.21377754f, 0.21116453f, 0.20804280f, 0.20441988f, |
1926 | | 0.20030449f, 0.19570655f, 0.19063714f, 0.18510847f, 0.17913385f, 0.17272767f, 0.16590540f, 0.15868343f, 0.15107919f, |
1927 | | 0.14311098f, 0.13479801f, 0.12616029f, 0.11721864f, 0.10799461f, 0.09851040f, 0.08878887f, 0.07885345f, 0.06872806f, |
1928 | | 0.05843709f, 0.04800535f, 0.03745796f, 0.02682033f, 0.01611809f, 0.00537701f, 0.00419561f, 0.01257674f, 0.02092756f, |
1929 | | 0.02922797f, 0.03745796f, 0.04559772f, 0.05362762f, 0.06152834f, 0.06928082f, 0.07686640f, 0.08426680f, 0.09146421f, |
1930 | | 0.09844126f, 0.10518116f, 0.11166766f, 0.11788516f, 0.12381865f, 0.12945385f, 0.13477719f, 0.13977584f, 0.14443776f, |
1931 | | 0.14875172f, 0.15270731f, 0.15629503f, 0.15950622f, 0.16233313f, 0.16476898f, 0.16680788f, 0.16844493f, 0.16967617f, |
1932 | | 0.17049865f, 0.17091040f, 0.17091040f, 0.17049865f, 0.16967617f, 0.16844493f, 0.16680788f, 0.16476898f, 0.16233313f, |
1933 | | 0.15950622f, 0.15629503f, 0.15270731f, 0.14875172f, 0.14443776f, 0.13977584f, 0.13477719f, 0.12945385f, 0.12381865f, |
1934 | | 0.11788516f, 0.11166766f, 0.10518116f, 0.09844126f, 0.09146421f, 0.08426680f, 0.07686640f, 0.06928082f, 0.06152834f, |
1935 | | 0.05362762f, 0.04559772f, 0.03745796f, 0.02922797f, 0.02092756f, 0.01257674f, 0.00419561f, 0.00300411f, 0.00900509f, |
1936 | | 0.01498437f, 0.02092756f, 0.02682033f, 0.03264849f, 0.03839799f, 0.04405500f, 0.04960586f, 0.05503723f, 0.06033600f, |
1937 | | 0.06548942f, 0.07048507f, 0.07531092f, 0.07995533f, 0.08440712f, 0.08865558f, 0.09269045f, 0.09650202f, 0.10008111f, |
1938 | | 0.10341910f, 0.10650793f, 0.10934019f, 0.11190903f, 0.11420828f, 0.11623239f, 0.11797648f, 0.11943635f, 0.12060850f, |
1939 | | 0.12149009f, 0.12207900f, 0.12237380f, 0.12237380f, 0.12207900f, 0.12149009f, 0.12060850f, 0.11943635f, 0.11797648f, |
1940 | | 0.11623239f, 0.11420828f, 0.11190903f, 0.10934019f, 0.10650793f, 0.10341910f, 0.10008111f, 0.09650202f, 0.09269045f, |
1941 | | 0.08865558f, 0.08440712f, 0.07995533f, 0.07531092f, 0.07048507f, 0.06548942f, 0.06033600f, 0.05503723f, 0.04960586f, |
1942 | | 0.04405500f, 0.03839799f, 0.03264849f, 0.02682033f, 0.02092756f, 0.01498437f, 0.00900509f, 0.00300411f, 0.00180536f, |
1943 | | 0.00541175f, 0.00900509f, 0.01257674f, 0.01611809f, 0.01962061f, 0.02307586f, 0.02647552f, 0.02981140f, 0.03307546f, |
1944 | | 0.03625984f, 0.03935686f, 0.04235908f, 0.04525924f, 0.04805037f, 0.05072575f, 0.05327892f, 0.05570374f, 0.05799436f, |
1945 | | 0.06014527f, 0.06215128f, 0.06400757f, 0.06570966f, 0.06725344f, 0.06863521f, 0.06985163f, 0.07089976f, 0.07177710f, |
1946 | | 0.07248152f, 0.07301132f, 0.07336523f, 0.07354241f, 0.07354241f, 0.07336523f, 0.07301132f, 0.07248152f, 0.07177710f, |
1947 | | 0.07089976f, 0.06985163f, 0.06863521f, 0.06725344f, 0.06570966f, 0.06400757f, 0.06215128f, 0.06014527f, 0.05799436f, |
1948 | | 0.05570374f, 0.05327892f, 0.05072575f, 0.04805037f, 0.04525924f, 0.04235908f, 0.03935686f, 0.03625984f, 0.03307546f, |
1949 | | 0.02981140f, 0.02647552f, 0.02307586f, 0.01962061f, 0.01611809f, 0.01257674f, 0.00900509f, 0.00541175f, 0.00180536f, |
1950 | | 0.00060227f, 0.00180536f, 0.00300411f, 0.00419561f, 0.00537701f, 0.00654546f, 0.00769814f, 0.00883227f, 0.00994512f, |
1951 | | 0.01103401f, 0.01209633f, 0.01312950f, 0.01413104f, 0.01509854f, 0.01602966f, 0.01692217f, 0.01777391f, 0.01858284f, |
1952 | | 0.01934699f, 0.02006454f, 0.02073374f, 0.02135300f, 0.02192082f, 0.02243583f, 0.02289679f, 0.02330259f, 0.02365225f, |
1953 | | 0.02394493f, 0.02417992f, 0.02435667f, 0.02447473f, 0.02453384f, 0.02453384f, 0.02447473f, 0.02435667f, 0.02417992f, |
1954 | | 0.02394493f, 0.02365225f, 0.02330259f, 0.02289679f, 0.02243583f, 0.02192082f, 0.02135300f, 0.02073374f, 0.02006454f, |
1955 | | 0.01934699f, 0.01858284f, 0.01777391f, 0.01692217f, 0.01602966f, 0.01509854f, 0.01413104f, 0.01312950f, 0.01209633f, |
1956 | | 0.01103401f, 0.00994512f, 0.00883227f, 0.00769814f, 0.00654546f, 0.00537701f, 0.00419561f, 0.00300411f, 0.00180536f, |
1957 | | 0.00060227f, |
1958 | | }; |
1959 | | |
1960 | | static const float* get_half_cos_window(int32_t block_size) { |
1961 | | switch (block_size) { |
1962 | | case 2: { |
1963 | | return window_function_half_cos_window_2; |
1964 | | } |
1965 | | case 4: { |
1966 | | return window_function_half_cos_window_4; |
1967 | | } |
1968 | | case 8: { |
1969 | | return window_function_half_cos_window_8; |
1970 | | } |
1971 | | case 16: { |
1972 | | return window_function_half_cos_window_16; |
1973 | | } |
1974 | | case 32: { |
1975 | | return window_function_half_cos_window_32; |
1976 | | } |
1977 | | case 64: { |
1978 | | return window_function_half_cos_window_64; |
1979 | | } |
1980 | | } |
1981 | | assert(0); |
1982 | | return NULL; |
1983 | | } |
1984 | | |
1985 | | #define DITHER_AND_QUANTIZE(INT_TYPE, suffix) \ |
1986 | | static void dither_and_quantize_##suffix(float* result, \ |
1987 | | int32_t result_stride, \ |
1988 | | INT_TYPE* denoised, \ |
1989 | | int32_t w, \ |
1990 | | int32_t h, \ |
1991 | | int32_t stride, \ |
1992 | | int32_t chroma_sub_w, \ |
1993 | | int32_t chroma_sub_h, \ |
1994 | | int32_t block_size, \ |
1995 | | float block_normalization) { \ |
1996 | | for (int32_t y = 0; y < (h >> chroma_sub_h); ++y) { \ |
1997 | | for (int32_t x = 0; x < (w >> chroma_sub_w); ++x) { \ |
1998 | | const int32_t result_idx = (y + (block_size >> chroma_sub_h)) * result_stride + x + \ |
1999 | | (block_size >> chroma_sub_w); \ |
2000 | | INT_TYPE new_val = (INT_TYPE)AOMMIN(AOMMAX(result[result_idx] * block_normalization + 0.5f, 0), \ |
2001 | | block_normalization); \ |
2002 | | const float err = -(((float)new_val) / block_normalization - result[result_idx]); \ |
2003 | | denoised[y * stride + x] = new_val; \ |
2004 | | if (x + 1 < (w >> chroma_sub_w)) { \ |
2005 | | result[result_idx + 1] += err * 7.0f / 16.0f; \ |
2006 | | } \ |
2007 | | if (y + 1 < (h >> chroma_sub_h)) { \ |
2008 | | if (x > 0) { \ |
2009 | | result[result_idx + result_stride - 1] += err * 3.0f / 16.0f; \ |
2010 | | } \ |
2011 | | result[result_idx + result_stride] += err * 5.0f / 16.0f; \ |
2012 | | if (x + 1 < (w >> chroma_sub_w)) { \ |
2013 | | result[result_idx + result_stride + 1] += err * 1.0f / 16.0f; \ |
2014 | | } \ |
2015 | | } \ |
2016 | | } \ |
2017 | | } \ |
2018 | | } |
2019 | | |
2020 | | DITHER_AND_QUANTIZE(uint8_t, lowbd); |
2021 | | DITHER_AND_QUANTIZE(uint16_t, highbd); |
2022 | | |
2023 | | void svt_av1_apply_window_function_to_plane_c(int32_t y_size, int32_t x_size, float* result_ptr, uint32_t result_stride, |
2024 | 0 | float* block, float* plane, const float* window_function) { |
2025 | 0 | for (int32_t y = 0; y < y_size; ++y) { |
2026 | 0 | for (int32_t x = 0; x < x_size; ++x) { |
2027 | 0 | result_ptr[y * result_stride + x] += (block[y * x_size + x] + plane[y * x_size + x]) * |
2028 | 0 | window_function[y * x_size + x]; |
2029 | 0 | } |
2030 | 0 | } |
2031 | 0 | } |
2032 | | |
2033 | | int32_t svt_aom_wiener_denoise_2d(const uint8_t* const data[3], uint8_t* denoised[3], int32_t w, int32_t h, |
2034 | | int32_t stride[3], int32_t chroma_sub[2], float noise_psd[3], int32_t block_size, |
2035 | 0 | int32_t bit_depth, int32_t use_highbd) { |
2036 | 0 | const float *window_full = NULL, *window_chroma = NULL; |
2037 | 0 | float* plane = NULL; |
2038 | 0 | DECLARE_ALIGNED(32, float, *block); |
2039 | 0 | block = NULL; |
2040 | 0 | double * block_d = NULL, *plane_d = NULL; |
2041 | 0 | struct aom_noise_tx_t* tx_full = NULL; |
2042 | 0 | struct aom_noise_tx_t* tx_chroma = NULL; |
2043 | 0 | const int32_t num_blocks_w = (w + block_size - 1) / block_size; |
2044 | 0 | const int32_t num_blocks_h = (h + block_size - 1) / block_size; |
2045 | 0 | const int32_t result_stride = (num_blocks_w + 2) * block_size; |
2046 | 0 | const int32_t result_height = (num_blocks_h + 2) * block_size; |
2047 | 0 | float* result = NULL; |
2048 | 0 | int32_t init_success = 1; |
2049 | 0 | AomFlatBlockFinder block_finder_full; |
2050 | 0 | AomFlatBlockFinder block_finder_chroma; |
2051 | 0 | const float k_block_normalization = (float)((1 << bit_depth) - 1); |
2052 | 0 | if (chroma_sub[0] != chroma_sub[1]) { |
2053 | 0 | SVT_ERROR( |
2054 | 0 | "svt_aom_wiener_denoise_2d doesn't handle different chroma " |
2055 | 0 | "subsampling"); |
2056 | 0 | return 0; |
2057 | 0 | } |
2058 | 0 | init_success &= svt_aom_flat_block_finder_init(&block_finder_full, block_size, bit_depth, use_highbd); |
2059 | 0 | result = (float*)malloc((num_blocks_h + 2) * block_size * result_stride * sizeof(*result)); |
2060 | 0 | plane = (float*)malloc(block_size * block_size * sizeof(*plane)); |
2061 | 0 | block = (float*)svt_aom_memalign(32, 2 * block_size * block_size * sizeof(*block)); |
2062 | 0 | block_d = (double*)malloc(block_size * block_size * sizeof(*block_d)); |
2063 | 0 | plane_d = (double*)malloc(block_size * block_size * sizeof(*plane_d)); |
2064 | 0 | window_full = get_half_cos_window(block_size); |
2065 | 0 | tx_full = svt_aom_noise_tx_malloc(block_size); |
2066 | |
|
2067 | 0 | if (chroma_sub[0] != 0) { |
2068 | 0 | init_success &= svt_aom_flat_block_finder_init( |
2069 | 0 | &block_finder_chroma, block_size >> chroma_sub[0], bit_depth, use_highbd); |
2070 | 0 | window_chroma = get_half_cos_window(block_size >> chroma_sub[0]); |
2071 | 0 | tx_chroma = svt_aom_noise_tx_malloc(block_size >> chroma_sub[0]); |
2072 | 0 | } else { |
2073 | 0 | window_chroma = window_full; |
2074 | 0 | tx_chroma = tx_full; |
2075 | 0 | } |
2076 | |
|
2077 | 0 | init_success &= (int32_t)((tx_full != NULL) && (tx_chroma != NULL) && (plane != NULL) && (plane_d != NULL) && |
2078 | 0 | (block != NULL) && (block_d != NULL) && (window_full != NULL) && |
2079 | 0 | (window_chroma != NULL) && (result != NULL)); |
2080 | 0 | for (int32_t c = init_success ? 0 : 3; c < 3; ++c) { |
2081 | 0 | const float* window_function = c == 0 ? window_full : window_chroma; |
2082 | 0 | AomFlatBlockFinder* block_finder = &block_finder_full; |
2083 | 0 | const int32_t chroma_sub_h = c > 0 ? chroma_sub[1] : 0; |
2084 | 0 | const int32_t chroma_sub_w = c > 0 ? chroma_sub[0] : 0; |
2085 | 0 | struct aom_noise_tx_t* tx = (c > 0 && chroma_sub[0] > 0) ? tx_chroma : tx_full; |
2086 | 0 | if (!data[c] || !denoised[c]) { |
2087 | 0 | continue; |
2088 | 0 | } |
2089 | 0 | if (c > 0 && chroma_sub[0] != 0) { |
2090 | 0 | block_finder = &block_finder_chroma; |
2091 | 0 | } |
2092 | 0 | memset(result, 0, sizeof(*result) * result_stride * result_height); |
2093 | | // Do overlapped block processing (half overlapped). The block rows can |
2094 | | // easily be done in parallel |
2095 | 0 | for (int32_t offsy = 0; offsy < (block_size >> chroma_sub_h); offsy += (block_size >> chroma_sub_h) / 2) { |
2096 | 0 | for (int32_t offsx = 0; offsx < (block_size >> chroma_sub_w); offsx += (block_size >> chroma_sub_w) / 2) { |
2097 | | // Pad the boundary when processing each block-set. |
2098 | 0 | for (int32_t by = -1; by < num_blocks_h; ++by) { |
2099 | 0 | for (int32_t bx = -1; bx < num_blocks_w; ++bx) { |
2100 | 0 | const int32_t pixels_per_block = (block_size >> chroma_sub_w) * (block_size >> chroma_sub_h); |
2101 | 0 | svt_aom_flat_block_finder_extract_block(block_finder, |
2102 | 0 | data[c], |
2103 | 0 | w >> chroma_sub_w, |
2104 | 0 | h >> chroma_sub_h, |
2105 | 0 | stride[c], |
2106 | 0 | bx * (block_size >> chroma_sub_w) + offsx, |
2107 | 0 | by * (block_size >> chroma_sub_h) + offsy, |
2108 | 0 | plane_d, |
2109 | 0 | block_d); |
2110 | 0 | svt_av1_pointwise_multiply(window_function, plane, block, plane_d, block_d, pixels_per_block); |
2111 | 0 | svt_aom_noise_tx_forward(tx, block); |
2112 | 0 | svt_aom_noise_tx_filter(tx->block_size, tx->tx_block, noise_psd[c]); |
2113 | 0 | svt_aom_noise_tx_inverse(tx, block); |
2114 | | |
2115 | | // Apply window function to the plane approximation (we will apply |
2116 | | // it to the sum of plane + block when composing the results). |
2117 | |
|
2118 | 0 | const int y_size = (block_size >> chroma_sub_h); |
2119 | 0 | const int x_size = (block_size >> chroma_sub_w); |
2120 | 0 | float* result_ptr = result + ((by + 1) * y_size + offsy) * result_stride + (bx + 1) * x_size + |
2121 | 0 | offsx; |
2122 | 0 | svt_av1_apply_window_function_to_plane( |
2123 | 0 | y_size, x_size, result_ptr, result_stride, block, plane, window_function); |
2124 | 0 | } |
2125 | 0 | } |
2126 | 0 | } |
2127 | 0 | } |
2128 | 0 | if (use_highbd) { |
2129 | 0 | dither_and_quantize_highbd(result, |
2130 | 0 | result_stride, |
2131 | 0 | (uint16_t*)denoised[c], |
2132 | 0 | w, |
2133 | 0 | h, |
2134 | 0 | stride[c], |
2135 | 0 | chroma_sub_w, |
2136 | 0 | chroma_sub_h, |
2137 | 0 | block_size, |
2138 | 0 | k_block_normalization); |
2139 | 0 | } else { |
2140 | 0 | dither_and_quantize_lowbd(result, |
2141 | 0 | result_stride, |
2142 | 0 | denoised[c], |
2143 | 0 | w, |
2144 | 0 | h, |
2145 | 0 | stride[c], |
2146 | 0 | chroma_sub_w, |
2147 | 0 | chroma_sub_h, |
2148 | 0 | block_size, |
2149 | 0 | k_block_normalization); |
2150 | 0 | } |
2151 | 0 | } |
2152 | 0 | free(result); |
2153 | 0 | free(plane); |
2154 | 0 | svt_aom_free(block); |
2155 | 0 | free(plane_d); |
2156 | 0 | free(block_d); |
2157 | |
|
2158 | 0 | svt_aom_noise_tx_free(tx_full); |
2159 | |
|
2160 | 0 | svt_aom_flat_block_finder_free(&block_finder_full); |
2161 | 0 | if (chroma_sub[0] != 0) { |
2162 | 0 | svt_aom_flat_block_finder_free(&block_finder_chroma); |
2163 | 0 | svt_aom_noise_tx_free(tx_chroma); |
2164 | 0 | } |
2165 | 0 | return init_success; |
2166 | 0 | } |
2167 | | |
2168 | 0 | static void denoise_and_model_dctor(EbPtr p) { |
2169 | 0 | AomDenoiseAndModel* obj = (AomDenoiseAndModel*)p; |
2170 | |
|
2171 | 0 | free(obj->flat_blocks); |
2172 | 0 | for (int32_t i = 0; i < 3; ++i) { |
2173 | 0 | EB_FREE_ARRAY(obj->denoised[i]); |
2174 | 0 | EB_FREE_ARRAY(obj->packed[i]); |
2175 | 0 | } |
2176 | 0 | svt_aom_noise_model_free(&obj->noise_model); |
2177 | 0 | svt_aom_flat_block_finder_free(&obj->flat_block_finder); |
2178 | 0 | } |
2179 | | |
2180 | 0 | EbErrorType svt_aom_denoise_and_model_ctor(AomDenoiseAndModel* object_ptr, EbPtr object_init_data_ptr) { |
2181 | 0 | DenoiseAndModelInitData* init_data_ptr = (DenoiseAndModelInitData*)object_init_data_ptr; |
2182 | 0 | EbErrorType return_error = EB_ErrorNone; |
2183 | 0 | uint32_t use_highbd = init_data_ptr->encoder_bit_depth > EB_EIGHT_BIT ? 1 : 0; |
2184 | 0 | ResolutionRange input_resolution; |
2185 | |
|
2186 | 0 | int32_t chroma_sub_log2[2] = {1, 1}; //todo: send chroma subsampling |
2187 | 0 | chroma_sub_log2[0] = (init_data_ptr->encoder_color_format == EB_YUV444 ? 0 : 1); |
2188 | 0 | chroma_sub_log2[1] = (init_data_ptr->encoder_color_format >= EB_YUV422 ? 0 : 1); |
2189 | |
|
2190 | 0 | object_ptr->dctor = denoise_and_model_dctor; |
2191 | |
|
2192 | 0 | const uint32_t input_size = init_data_ptr->width * init_data_ptr->height; |
2193 | 0 | svt_aom_derive_input_resolution(&input_resolution, input_size); |
2194 | |
|
2195 | 0 | int32_t denoise_block_size = 32; |
2196 | 0 | if (init_data_ptr->adaptive_film_grain) { |
2197 | 0 | if (input_resolution <= INPUT_SIZE_1080p_RANGE) { |
2198 | 0 | denoise_block_size = 8; |
2199 | 0 | } else if (input_resolution <= INPUT_SIZE_4K_RANGE) { |
2200 | 0 | denoise_block_size = 16; |
2201 | 0 | } |
2202 | 0 | } |
2203 | |
|
2204 | 0 | object_ptr->block_size = denoise_block_size; |
2205 | 0 | object_ptr->noise_level = (float)(init_data_ptr->noise_level / 10.0); |
2206 | 0 | object_ptr->bit_depth = init_data_ptr->encoder_bit_depth > EB_EIGHT_BIT ? 10 : 8; |
2207 | |
|
2208 | 0 | object_ptr->width = init_data_ptr->width; |
2209 | 0 | object_ptr->height = init_data_ptr->height; |
2210 | 0 | object_ptr->y_stride = init_data_ptr->y_stride; |
2211 | 0 | object_ptr->uv_stride = init_data_ptr->u_stride; |
2212 | | |
2213 | | //todo: consider replacing with EbPictureBuffersDesc |
2214 | |
|
2215 | 0 | EB_CALLOC_ARRAY(object_ptr->denoised[0], (object_ptr->y_stride * object_ptr->height) << use_highbd); |
2216 | 0 | EB_CALLOC_ARRAY(object_ptr->denoised[1], |
2217 | 0 | (object_ptr->uv_stride * (object_ptr->height >> chroma_sub_log2[0])) << use_highbd); |
2218 | 0 | EB_CALLOC_ARRAY(object_ptr->denoised[2], |
2219 | 0 | (object_ptr->uv_stride * (object_ptr->height >> chroma_sub_log2[0])) << use_highbd); |
2220 | | |
2221 | 0 | if (use_highbd) { |
2222 | 0 | EB_CALLOC_ARRAY(object_ptr->packed[0], (object_ptr->y_stride * object_ptr->height)); |
2223 | 0 | EB_CALLOC_ARRAY(object_ptr->packed[1], (object_ptr->uv_stride * (object_ptr->height >> chroma_sub_log2[0]))); |
2224 | 0 | EB_CALLOC_ARRAY(object_ptr->packed[2], (object_ptr->uv_stride * (object_ptr->height >> chroma_sub_log2[0]))); |
2225 | 0 | } |
2226 | | |
2227 | 0 | object_ptr->denoise_apply = init_data_ptr->denoise_apply; |
2228 | |
|
2229 | 0 | return return_error; |
2230 | 0 | } |
2231 | | |
2232 | | static int32_t denoise_and_model_realloc_if_necessary(struct AomDenoiseAndModel* ctx, EbPictureBufferDesc* sd, |
2233 | | int32_t use_highbd) { |
2234 | | const int32_t chroma_sub_log2[2] = {1, 1}; //todo: send chroma subsampling |
2235 | | |
2236 | | free(ctx->flat_blocks); |
2237 | | ctx->flat_blocks = NULL; |
2238 | | |
2239 | | ctx->num_blocks_w = (sd->width + ctx->block_size - 1) / ctx->block_size; |
2240 | | ctx->num_blocks_h = (sd->height + ctx->block_size - 1) / ctx->block_size; |
2241 | | ctx->flat_blocks = malloc(ctx->num_blocks_w * ctx->num_blocks_h); |
2242 | | |
2243 | | svt_aom_flat_block_finder_free(&ctx->flat_block_finder); |
2244 | | if (!svt_aom_flat_block_finder_init(&ctx->flat_block_finder, ctx->block_size, ctx->bit_depth, use_highbd)) { |
2245 | | SVT_ERROR("Unable to init flat block finder\n"); |
2246 | | return 0; |
2247 | | } |
2248 | | |
2249 | | const AomNoiseModelParams params = {AOM_NOISE_SHAPE_SQUARE, 3, ctx->bit_depth, use_highbd}; |
2250 | | // svt_aom_noise_model_free(&ctx->noise_model); |
2251 | | if (!svt_aom_noise_model_init(&ctx->noise_model, params)) { |
2252 | | SVT_ERROR("Unable to init noise model\n"); |
2253 | | return 0; |
2254 | | } |
2255 | | |
2256 | | // Simply use a flat PSD (although we could use the flat blocks to estimate |
2257 | | // PSD) those to estimate an actual noise PSD) |
2258 | | const float y_noise_level = svt_aom_noise_psd_get_default_value(ctx->block_size, ctx->noise_level); |
2259 | | const float uv_noise_level = svt_aom_noise_psd_get_default_value(ctx->block_size >> chroma_sub_log2[1], |
2260 | | ctx->noise_level); |
2261 | | ctx->noise_psd[0] = y_noise_level; |
2262 | | ctx->noise_psd[1] = ctx->noise_psd[2] = uv_noise_level; |
2263 | | return 1; |
2264 | | } |
2265 | | |
2266 | 0 | static void unpack_2d_pic(uint8_t* packed[3], EbPictureBufferDesc* outputPicturePtr) { |
2267 | 0 | uint16_t luma_width = (uint16_t)(outputPicturePtr->width); |
2268 | 0 | uint16_t chroma_width = luma_width >> 1; |
2269 | 0 | uint16_t luma_height = (uint16_t)(outputPicturePtr->height); |
2270 | 0 | uint16_t chroma_height = luma_height >> 1; |
2271 | |
|
2272 | 0 | svt_unpack_and_2bcompress((uint16_t*)(packed[0]), |
2273 | 0 | outputPicturePtr->y_stride, |
2274 | 0 | outputPicturePtr->y_buffer, |
2275 | 0 | outputPicturePtr->y_stride, |
2276 | 0 | outputPicturePtr->y_buffer_bit_inc, |
2277 | 0 | outputPicturePtr->y_stride_bit_inc >> 2, |
2278 | 0 | luma_width, |
2279 | 0 | luma_height); |
2280 | |
|
2281 | 0 | svt_unpack_and_2bcompress((uint16_t*)(packed[1]), |
2282 | 0 | outputPicturePtr->u_stride, |
2283 | 0 | outputPicturePtr->u_buffer, |
2284 | 0 | outputPicturePtr->u_stride, |
2285 | 0 | outputPicturePtr->u_buffer_bit_inc, |
2286 | 0 | outputPicturePtr->u_stride_bit_inc >> 2, |
2287 | 0 | chroma_width, |
2288 | 0 | chroma_height); |
2289 | |
|
2290 | 0 | svt_unpack_and_2bcompress((uint16_t*)(packed[2]), |
2291 | 0 | outputPicturePtr->v_stride, |
2292 | 0 | outputPicturePtr->v_buffer, |
2293 | 0 | outputPicturePtr->v_stride, |
2294 | 0 | outputPicturePtr->v_buffer_bit_inc, |
2295 | 0 | outputPicturePtr->v_stride_bit_inc >> 2, |
2296 | 0 | chroma_width, |
2297 | 0 | chroma_height); |
2298 | 0 | } |
2299 | | |
2300 | | int32_t svt_aom_denoise_and_model_run(struct AomDenoiseAndModel* ctx, EbPictureBufferDesc* sd, AomFilmGrain* film_grain, |
2301 | 0 | int32_t use_highbd) { |
2302 | 0 | const int32_t block_size = ctx->block_size; |
2303 | 0 | uint8_t* raw_data[3]; |
2304 | 0 | int32_t chroma_sub_log2[2] = {1, 1}; //todo: send chroma subsampling |
2305 | 0 | int32_t strides[3] = {sd->y_stride, sd->u_stride, sd->v_stride}; |
2306 | |
|
2307 | 0 | if (!denoise_and_model_realloc_if_necessary(ctx, sd, use_highbd)) { |
2308 | 0 | SVT_ERROR("Unable to realloc buffers\n"); |
2309 | 0 | return 0; |
2310 | 0 | } |
2311 | | |
2312 | 0 | if (!use_highbd) { // 8 bits input |
2313 | 0 | raw_data[0] = sd->y_buffer; |
2314 | 0 | raw_data[1] = sd->u_buffer; |
2315 | 0 | raw_data[2] = sd->v_buffer; |
2316 | 0 | } else { // 10 bits input |
2317 | 0 | svt_aom_pack_2d_pic(sd, ctx->packed); |
2318 | |
|
2319 | 0 | raw_data[0] = (uint8_t*)(ctx->packed[0]); |
2320 | 0 | raw_data[1] = (uint8_t*)(ctx->packed[1]); |
2321 | 0 | raw_data[2] = (uint8_t*)(ctx->packed[2]); |
2322 | 0 | } |
2323 | |
|
2324 | 0 | const uint8_t* const data[3] = {raw_data[0], raw_data[1], raw_data[2]}; |
2325 | |
|
2326 | 0 | svt_aom_flat_block_finder_run( |
2327 | 0 | &ctx->flat_block_finder, data[0], sd->width, sd->height, strides[0], ctx->flat_blocks); |
2328 | |
|
2329 | 0 | if (!svt_aom_wiener_denoise_2d(data, |
2330 | 0 | ctx->denoised, |
2331 | 0 | sd->width, |
2332 | 0 | sd->height, |
2333 | 0 | strides, |
2334 | 0 | chroma_sub_log2, |
2335 | 0 | ctx->noise_psd, |
2336 | 0 | block_size, |
2337 | 0 | ctx->bit_depth, |
2338 | 0 | use_highbd)) { |
2339 | 0 | SVT_ERROR("Unable to denoise image\n"); |
2340 | 0 | return 0; |
2341 | 0 | } |
2342 | | |
2343 | 0 | const AomNoiseStatus status = noise_model_update(&ctx->noise_model, |
2344 | 0 | data, |
2345 | 0 | (const uint8_t* const*)ctx->denoised, |
2346 | 0 | sd->width, |
2347 | 0 | sd->height, |
2348 | 0 | strides, |
2349 | 0 | chroma_sub_log2, |
2350 | 0 | ctx->flat_blocks, |
2351 | 0 | block_size); |
2352 | |
|
2353 | 0 | int32_t have_noise_estimate = 0; |
2354 | 0 | if (status == AOM_NOISE_STATUS_OK || status == AOM_NOISE_STATUS_DIFFERENT_NOISE_TYPE) { |
2355 | 0 | svt_aom_noise_model_save_latest(&ctx->noise_model); |
2356 | 0 | have_noise_estimate = 1; |
2357 | 0 | } |
2358 | |
|
2359 | 0 | film_grain->apply_grain = 0; |
2360 | 0 | if (have_noise_estimate) { |
2361 | 0 | if (!svt_aom_noise_model_get_grain_parameters(&ctx->noise_model, film_grain)) { |
2362 | 0 | SVT_ERROR("Unable to get grain parameters.\n"); |
2363 | 0 | return 0; |
2364 | 0 | } |
2365 | 0 | film_grain->apply_grain = 1; |
2366 | |
|
2367 | 0 | if (ctx->denoise_apply) { |
2368 | 0 | if (!use_highbd) { |
2369 | 0 | if (svt_memcpy != NULL) { |
2370 | 0 | svt_memcpy(raw_data[0], ctx->denoised[0], (strides[0] * sd->height) << use_highbd); |
2371 | 0 | svt_memcpy( |
2372 | 0 | raw_data[1], ctx->denoised[1], (strides[1] * (sd->height >> chroma_sub_log2[0])) << use_highbd); |
2373 | 0 | svt_memcpy( |
2374 | 0 | raw_data[2], ctx->denoised[2], (strides[2] * (sd->height >> chroma_sub_log2[0])) << use_highbd); |
2375 | 0 | } else { |
2376 | 0 | svt_memcpy_c(raw_data[0], ctx->denoised[0], (strides[0] * sd->height) << use_highbd); |
2377 | 0 | svt_memcpy_c( |
2378 | 0 | raw_data[1], ctx->denoised[1], (strides[1] * (sd->height >> chroma_sub_log2[0])) << use_highbd); |
2379 | 0 | svt_memcpy_c( |
2380 | 0 | raw_data[2], ctx->denoised[2], (strides[2] * (sd->height >> chroma_sub_log2[0])) << use_highbd); |
2381 | 0 | } |
2382 | 0 | } else { |
2383 | 0 | unpack_2d_pic(ctx->denoised, sd); |
2384 | 0 | } |
2385 | 0 | } |
2386 | 0 | } |
2387 | 0 | svt_aom_flat_block_finder_free(&ctx->flat_block_finder); |
2388 | 0 | svt_aom_noise_model_free(&ctx->noise_model); |
2389 | 0 | free(ctx->flat_blocks); |
2390 | 0 | ctx->flat_blocks = NULL; |
2391 | |
|
2392 | 0 | return 1; |
2393 | 0 | } |
2394 | | #endif |