mirror of
https://github.com/quelsolaar/MergeSource
synced 2025-02-08 11:08:41 -05:00
173 lines
5.6 KiB
C
173 lines
5.6 KiB
C
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "hxa.h"
|
|
#include "hxa_utils.h"
|
|
|
|
#define FALSE 0
|
|
#define TRUE !FALSE
|
|
|
|
void hxa_util_blur_node_line_uint8(unsigned char *layer, unsigned long long *buffer, unsigned int buffer_length, unsigned long long *weights, unsigned int weight_length, unsigned int stride)
|
|
{
|
|
unsigned char *b;
|
|
unsigned int i, j, k, half_length;
|
|
unsigned long long sum, weight_sum;
|
|
half_length = weight_length / 2;
|
|
|
|
b = layer;
|
|
for(i = j = 0; i < buffer_length; j += stride)
|
|
buffer[i++] = layer[j];
|
|
for(i = j = 0; i < half_length; i++)
|
|
{
|
|
sum = weight_sum = 0;
|
|
for(k = 0; k < half_length + i; k++)
|
|
{
|
|
weight_sum += weights[half_length - i + k];
|
|
sum += buffer[k] * weights[half_length - i + k];
|
|
}
|
|
layer[j] = sum / weight_sum;
|
|
j += stride;
|
|
}
|
|
for(; i < buffer_length - half_length; i++)
|
|
{
|
|
sum = weight_sum = 0;
|
|
for(k = 0; k < weight_length; k++)
|
|
{
|
|
weight_sum += weights[k];
|
|
sum += buffer[i + k - half_length] * weights[k];
|
|
}
|
|
layer[j] = sum / weight_sum;
|
|
j += stride;
|
|
}
|
|
for(; i < buffer_length; i++)
|
|
{
|
|
sum = weight_sum = 0;
|
|
for(k = 0; i + k - half_length < buffer_length; k++)
|
|
{
|
|
weight_sum += weights[k];
|
|
sum += buffer[i + k - half_length] * weights[k];
|
|
}
|
|
layer[j] = sum / weight_sum;
|
|
j += stride;
|
|
}
|
|
}
|
|
|
|
|
|
void hxa_util_blur_node_line(HXALayer *layer, unsigned long long *buffer, unsigned int start, unsigned int buffer_length, unsigned long long *weights, unsigned int weight_length, unsigned int stride)
|
|
{
|
|
switch(layer->type)
|
|
{
|
|
case HXA_LDT_UINT8 :
|
|
hxa_util_blur_node_line_uint8(&layer->data.uint8_data[start], buffer, buffer_length, weights, weight_length, stride);
|
|
break;
|
|
case HXA_LDT_INT32 :
|
|
break;
|
|
case HXA_LDT_FLOAT :
|
|
break;
|
|
case HXA_LDT_DOUBLE :
|
|
break;
|
|
}
|
|
}
|
|
|
|
void *hxa_util_blur_init(HXANode *node, HXALayer *layer, float blur_size, unsigned int *size_output, void **buffer)
|
|
{
|
|
unsigned int size, blur_size_half, blur_size_full, i;
|
|
double f, min, *weight_d;
|
|
unsigned long long *weight_l;
|
|
size = node->content.image.resolution[0];
|
|
switch(node->content.image.type)
|
|
{
|
|
case HXA_IT_CUBE_IMAGE :
|
|
if(size < node->content.image.resolution[1])
|
|
size = node->content.image.resolution[1];
|
|
break;
|
|
case HXA_IT_1D_IMAGE :
|
|
break;
|
|
case HXA_IT_2D_IMAGE :
|
|
if(size < node->content.image.resolution[1])
|
|
size = node->content.image.resolution[1];
|
|
break;
|
|
case HXA_IT_3D_IMAGE :
|
|
if(size < node->content.image.resolution[1])
|
|
size = node->content.image.resolution[1];
|
|
if(size < node->content.image.resolution[2])
|
|
size = node->content.image.resolution[2];
|
|
break;
|
|
}
|
|
blur_size_half = 1 + blur_size + 0.999;
|
|
*size_output = blur_size_full = blur_size_half + blur_size_half - 1;
|
|
if(layer->type == HXA_LDT_UINT8 || layer->type == HXA_LDT_INT32)
|
|
{
|
|
*buffer = malloc(sizeof(unsigned long long) * size);
|
|
min = 256.0 / (5.0);
|
|
weight_l = malloc(sizeof(double) * *size_output);
|
|
for(i = 0; i < blur_size_half; i++)
|
|
{
|
|
f = 2.0 * (double)i / blur_size;
|
|
weight_l[blur_size_half - 1 - i] = weight_l[blur_size_half - 1 + i] = (unsigned long long)(256.0 * 256.0 / (1.0 + f * f) - min);
|
|
}
|
|
return weight_l;
|
|
}else
|
|
{
|
|
*buffer = malloc(sizeof(double) * size);
|
|
min = 256.0 * 256.0 / (5.0);
|
|
weight_d = malloc(sizeof(double) * *size_output);
|
|
for(i = 0; i < blur_size_half; i++)
|
|
{
|
|
f = 2.0 * (double)i / blur_size;
|
|
weight_d[i] = weight_d[blur_size_full - 1 - i] = 256.0 / (1.0 + f * f) - min;
|
|
}
|
|
return weight_d;
|
|
}
|
|
}
|
|
|
|
void hxa_util_blur_layer(HXANode *node, HXALayer *layer, float blur_size)
|
|
{
|
|
void *buffer, *weights;
|
|
unsigned int i, j, k, weight_length;
|
|
weights = hxa_util_blur_init(node, layer, blur_size, &weight_length, &buffer);
|
|
switch(node->content.image.type)
|
|
{
|
|
case HXA_IT_CUBE_IMAGE :
|
|
for(k = 0; k < layer->components * 6 * node->content.image.resolution[0] * node->content.image.resolution[1]; k < layer->components * node->content.image.resolution[0] * node->content.image.resolution[1])
|
|
{
|
|
for(i = 0; i < layer->components; i++)
|
|
{
|
|
for(j = 0; j < node->content.image.resolution[0]; j++)
|
|
hxa_util_blur_node_line(layer, buffer, k + i + layer->components * j, node->content.image.resolution[1], weights, weight_length, node->content.image.resolution[0] * (hxa_uint32)layer->components);
|
|
for(j = 0; j < node->content.image.resolution[1]; j++)
|
|
hxa_util_blur_node_line(layer, buffer, k + i + layer->components * j * node->content.image.resolution[0], node->content.image.resolution[0], weights, weight_length, (hxa_uint32)layer->components);
|
|
}
|
|
}
|
|
break;
|
|
case HXA_IT_1D_IMAGE :
|
|
for(i = 0; i < layer->components; i++)
|
|
{
|
|
hxa_util_blur_node_line(layer, buffer, i, node->content.image.resolution[0], weights, weight_length, (hxa_uint32)layer->components);
|
|
}
|
|
break;
|
|
case HXA_IT_2D_IMAGE :
|
|
for(i = 0; i < layer->components; i++)
|
|
{
|
|
for(j = 0; j < node->content.image.resolution[0]; j++)
|
|
hxa_util_blur_node_line(layer, buffer, i + layer->components * j, node->content.image.resolution[1], weights, weight_length, node->content.image.resolution[0] * (hxa_uint32)layer->components);
|
|
for(j = 0; j < node->content.image.resolution[1]; j++)
|
|
hxa_util_blur_node_line(layer, buffer, i + layer->components * j * node->content.image.resolution[0], node->content.image.resolution[0], weights, weight_length, (hxa_uint32)layer->components);
|
|
}
|
|
break;
|
|
case HXA_IT_3D_IMAGE :
|
|
break;
|
|
}
|
|
free(buffer);
|
|
free(weights);
|
|
}
|
|
|
|
void hxa_util_blur_node(HXANode *node, float blur_size)
|
|
{
|
|
unsigned int i;
|
|
if(node->type != HXA_NT_IMAGE)
|
|
return;
|
|
for(i = 0; i < node->content.image.image_stack.layer_count; i++)
|
|
hxa_util_blur_layer(node, &node->content.image.image_stack.layers[i], blur_size);
|
|
|
|
} |