Make setting sigma independent of kernel size

This commit is contained in:
Kovid Goyal 2021-04-05 10:55:30 +05:30
parent 7199c62b76
commit c781825b00
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -27,10 +27,9 @@ static const uint32_t active_bg_color = 0xffdddad6;
typedef float kernel_type;
static void
build_blur_kernel(kernel_type *blur_kernel, const size_t size, kernel_type sigma_multiplier) {
build_blur_kernel(kernel_type *blur_kernel, const size_t size, kernel_type sigma) {
// 1D Normalized Gaussian
const kernel_type half = size / (kernel_type)2;
const kernel_type sigma = size * sigma_multiplier;
kernel_type sum = 0;
for (size_t i = 0; i < size; i++) {
kernel_type f = (i - half);
@ -41,14 +40,19 @@ build_blur_kernel(kernel_type *blur_kernel, const size_t size, kernel_type sigma
}
static void
blur_mask(uint8_t *image_data, ssize_t width, ssize_t height, ssize_t kernel_size, kernel_type sigma_multiplier, uint8_t *scratch, kernel_type *blur_kernel) {
build_blur_kernel(blur_kernel, kernel_size, sigma_multiplier);
blur_mask(uint8_t *image_data, ssize_t width, ssize_t height, ssize_t kernel_size, kernel_type sigma, uint8_t *scratch, kernel_type *blur_kernel, ssize_t margin) {
(void)margin;
build_blur_kernel(blur_kernel, kernel_size, sigma);
const size_t half = kernel_size / 2;
for (ssize_t y = 0; y < height; y++) {
uint8_t *s = image_data + y * width, *d = scratch + y * width;
for (ssize_t x = 0; x < width; x++) {
uint8_t a = 0;
/* if (margin < x && x < width - margin) { */
/* d[x] = s[x]; */
/* continue; */
/* } */
for (ssize_t k = 0; k < kernel_size; k++) {
const ssize_t px = x + k - half;
if (0 <= px && px < width) a += (uint8_t)(s[px] * blur_kernel[k]);
@ -61,6 +65,10 @@ blur_mask(uint8_t *image_data, ssize_t width, ssize_t height, ssize_t kernel_siz
uint8_t *d = image_data + y * width;
for (ssize_t x = 0; x < width; x++) {
uint8_t a = 0;
/* if (margin <= y && y < height - margin) { */
/* d[x] = (scratch + y * width)[x]; */
/* continue; */
/* } */
for (ssize_t k = 0; k < kernel_size; k++) {
const ssize_t py = y + k - half;
if (0 <= py && py < height) {
@ -74,14 +82,14 @@ blur_mask(uint8_t *image_data, ssize_t width, ssize_t height, ssize_t kernel_siz
}
static uint8_t*
create_shadow_mask(size_t width, size_t height, size_t margin, size_t kernel_size, uint8_t base_alpha, kernel_type sigma_multiplier) {
create_shadow_mask(size_t width, size_t height, size_t margin, size_t kernel_size, uint8_t base_alpha, kernel_type sigma) {
uint8_t *mask = calloc(1, 2 * width * height + sizeof(kernel_type) * kernel_size);
if (!mask) return NULL;
for (size_t y = margin; y < height - margin; y++) {
uint8_t *row = mask + y * width;
for (size_t x = margin; x < width - margin; x++) row[x] = base_alpha;
}
blur_mask(mask, width, height, kernel_size, sigma_multiplier, mask + width * height, (kernel_type*)(mask + 2 * width * height));
blur_mask(mask, width, height, kernel_size, sigma, mask + width * height, (kernel_type*)(mask + 2 * width * height), margin);
return mask;
}
@ -124,7 +132,7 @@ create_shadow_tile(_GLFWwindow *window) {
st.segments = 7;
st.stride = st.segments * margin;
st.corner_size = margin * (st.segments - 1) / 2;
uint8_t* mask = create_shadow_mask(st.stride, st.stride, margin, 2 * margin + 1, 255, 16.f);
uint8_t* mask = create_shadow_mask(st.stride, st.stride, margin, 2 * margin + 1, 255, 32 * margin);
st.data = malloc(sizeof(uint32_t) * st.stride * st.stride);
if (st.data) for (size_t i = 0; i < st.stride * st.stride; i++) st.data[i] = mask[i] << 24;
free(mask);