Esempio n. 1
0
DLL_PUBLIC fastfilters_array3d_t *fastfilters_array3d_alloc(size_t n_x, size_t n_y, size_t n_z, size_t channels)
{
    fastfilters_array3d_t *result = NULL;

    result = fastfilters_memory_alloc(sizeof(*result));
    if (!result)
        goto error_out;

    result->n_x = n_x;
    result->n_y = n_y;
    result->n_z = n_z;
    result->stride_x = channels;
    result->stride_y = channels * n_x;
    result->stride_z = channels * n_x * n_y;
    result->n_channels = channels;
    result->ptr = fastfilters_memory_alloc(channels * n_y * n_x * n_z * sizeof(float));
    if (!result->ptr)
        goto error_out;

    return result;

error_out:
    if (result) {
        if (result->ptr)
            fastfilters_memory_free(result->ptr);
        fastfilters_memory_free(result);
    }
    return NULL;
}
Esempio n. 2
0
void *fastfilters_memory_align(size_t alignment, size_t size)
{
    assert(alignment < 0xff);
    void *ptr = fastfilters_memory_alloc(size + alignment + 8);

    if (!ptr)
        return NULL;

    uintptr_t ptr_i = (uintptr_t)ptr;
    ptr_i += 8 + alignment - 1;
    ptr_i &= ~(alignment - 1);

    uintptr_t ptr_diff = ptr_i - (uintptr_t)ptr;

    void *ptr_aligned = (void *)ptr_i;
    uint64_t *ptr_magic = (uint64_t *)(ptr_i - 8);

    *ptr_magic = ALIGN_MAGIC | (ptr_diff & 0xff);

    return ptr_aligned;
}
Esempio n. 3
0
fastfilters_kernel_fir_t DLL_PUBLIC fastfilters_kernel_fir_gaussian(unsigned int order, double sigma,
                                                                    float window_ratio)
{
    double norm;
    double sigma2 = -0.5 / sigma / sigma;

    if (order > 2)
        return NULL;

    if (sigma < 0)
        return NULL;

    fastfilters_kernel_fir_t kernel = fastfilters_memory_alloc(sizeof(struct _fastfilters_kernel_fir_t));
    if (!kernel)
        return NULL;

    if (window_ratio > 0)
        kernel->len = floor(window_ratio * sigma + 0.5);
    else
        kernel->len = ceil((3.0 + 0.5 * (double)order) * sigma);

    if (fabs(sigma) < 1e-6)
        kernel->len = 0;

    kernel->coefs = fastfilters_memory_alloc(sizeof(float) * (kernel->len + 1));
    if (!kernel->coefs) {
        fastfilters_memory_free(kernel);
        return NULL;
    }

    if (order == 1)
        kernel->is_symmetric = false;
    else
        kernel->is_symmetric = true;

    switch (order) {
    case 1:
    case 2:
        norm = -1.0 / (sqrt(2.0 * M_PI) * pow(sigma, 3));
        break;

    default:
        norm = 1.0 / (sqrt(2.0 * M_PI) * sigma);
        break;
    }

    for (unsigned int x = 0; x <= kernel->len; ++x) {
        double x2 = x * x;
        double g = norm * exp(x2 * sigma2);
        switch (order) {
        case 0:
            kernel->coefs[x] = g;
            break;
        case 1:
            kernel->coefs[x] = x * g;
            break;
        case 2:
            kernel->coefs[x] = (1.0 - (x / sigma) * (x / sigma)) * g;
            break;
        }
    }

    if (order == 2) {
        double dc = kernel->coefs[0];
        for (unsigned int x = 1; x <= kernel->len; ++x)
            dc += 2 * kernel->coefs[x];
        dc /= (2.0 * (double)kernel->len + 1.0);

        for (unsigned int x = 0; x <= kernel->len; ++x)
            kernel->coefs[x] -= dc;
    }

    double sum = 0.0;
    if (order == 0) {
        sum = kernel->coefs[0];
        for (unsigned int x = 1; x <= kernel->len; ++x)
            sum += 2 * kernel->coefs[x];
    } else {
        unsigned int faculty = 1;

        int sign;

        if (kernel->is_symmetric)
            sign = 1;
        else
            sign = -1;

        for (unsigned int i = 2; i <= order; ++i)
            faculty *= i;

        sum = 0.0;
        for (unsigned int x = 1; x <= kernel->len; ++x) {
            sum += kernel->coefs[x] * pow(-(double)x, (int)order) / (double)faculty;
            sum += sign * kernel->coefs[x] * pow((double)x, (int)order) / (double)faculty;
        }
    }

    for (unsigned int x = 0; x <= kernel->len; ++x)
        kernel->coefs[x] /= sum;

    if (!kernel->is_symmetric)
        for (unsigned int x = 0; x <= kernel->len; ++x)
            kernel->coefs[x] *= -1;

    kernel->fn_inner_mirror = NULL;
    kernel->fn_inner_ptr = NULL;
    kernel->fn_inner_optimistic = NULL;
    kernel->fn_outer_mirror = NULL;
    kernel->fn_outer_ptr = NULL;
    kernel->fn_outer_optimistic = NULL;

    return kernel;
}