aboutsummaryrefslogtreecommitdiff
path: root/src/kernel.h
blob: d1dd2eee85fa64b49649f065b4fc63e3b2c2c0da (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <[email protected]>

#pragma once
#include <stdlib.h>
#include "compiler.h"

/// Code for generating convolution kernels

typedef struct conv {
	int w, h;
	double *rsum;
	double data[];
} conv;

/// Calculate the sum of a rectangle part of the convolution kernel
/// the rectangle is defined by top left (x, y), and a size (width x height)
double attr_pure sum_kernel(const conv *map, int x, int y, int width, int height);
double attr_pure sum_kernel_normalized(const conv *map, int x, int y, int width, int height);

/// Create a kernel with gaussian distribution with standard deviation `r`, and size
/// `size`.
conv *gaussian_kernel(double r, int size);

/// Estimate the best standard deviation for a give kernel size.
double gaussian_kernel_std_for_size(double size, double row_limit);

/// Create a gaussian kernel with auto detected standard deviation. The choosen standard
/// deviation tries to make sure the outer most pixels of the shadow are completely
/// transparent.
///
/// @param[in] shadow_radius the radius of the shadow
conv *gaussian_kernel_autodetect_deviation(double shadow_radius);

/// preprocess kernels to make shadow generation faster
/// shadow_sum[x*d+y] is the sum of the kernel from (0, 0) to (x, y), inclusive
void sum_kernel_preprocess(conv *map);

static inline void free_conv(conv *k) {
	free(k->rsum);
	free(k);
}