source: libpipi/trunk/pipi/filter/convolution.c @ 2710

Last change on this file since 2710 was 2710, checked in by sam, 6 years ago
  • convolution.c: move local function prototypes to convolution_template.h.
File size: 3.7 KB
Line 
1/*
2 *  libpipi       Proper image processing implementation library
3 *  Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id$
7 *
8 *  This library is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 * convolution.c: generic convolution functions
17 */
18
19#include "config.h"
20#include "common.h"
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <math.h>
26
27#include "pipi.h"
28#include "pipi_internals.h"
29
30#define FLAG_GRAY ((FLAGS) & SET_FLAG_GRAY)
31#define FLAG_WRAP ((FLAGS) & SET_FLAG_WRAP)
32
33#define SET_FLAG_GRAY 0x01
34#define SET_FLAG_WRAP 0x02
35
36#undef FUNC1
37#undef FUNC2
38#undef PIXEL
39#undef FLAGS
40#define FUNC1 conv_std_rgba_f
41#define FUNC2 conv_sep_rgba_f
42#define PIXEL float
43#define FLAGS 0
44#include "convolution_template.h"
45
46#undef FUNC1
47#undef FUNC2
48#undef PIXEL
49#undef FLAGS
50#define FUNC1 conv_std_y_f
51#define FUNC2 conv_sep_y_f
52#define PIXEL float
53#define FLAGS SET_FLAG_GRAY
54#include "convolution_template.h"
55
56#undef FUNC1
57#undef FUNC2
58#undef PIXEL
59#undef FLAGS
60#define FUNC1 wrap_std_rgba_f
61#define FUNC2 wrap_sep_rgba_f
62#define PIXEL float
63#define FLAGS SET_FLAG_WRAP
64#include "convolution_template.h"
65
66#undef FUNC1
67#undef FUNC2
68#undef PIXEL
69#undef FLAGS
70#define FUNC1 wrap_std_y_f
71#define FUNC2 wrap_sep_y_f
72#define PIXEL float
73#define FLAGS SET_FLAG_GRAY|SET_FLAG_WRAP
74#include "convolution_template.h"
75
76pipi_image_t *pipi_convolution(pipi_image_t *src, int m, int n, double mat[])
77{
78    pipi_image_t *ret;
79    double tmp;
80    double *hvec, *vvec;
81    int i, j, besti = -1, bestj = -1;
82
83    /* Find the cell with the largest value */
84    tmp = 0.0;
85    for(i = 0; i < m * n; i++)
86        if(mat[i] * mat[i] > tmp)
87        {
88            tmp = mat[i] * mat[i];
89            besti = i % m;
90            bestj = i / m;
91        }
92
93    /* If the kernel is empty, return an empty picture */
94    if(tmp == 0.0)
95        return pipi_new(src->w, src->h);
96
97    /* Check whether the matrix rank is 1 */
98    for(j = 0; j < n; j++)
99    {
100        if(j == bestj)
101            continue;
102
103        for(i = 0; i < m; i++)
104        {
105            double p, q;
106
107            if(i == besti)
108                continue;
109
110            p = mat[j * m + i] * mat[bestj * m + besti];
111            q = mat[bestj * m + i] * mat[j * m + besti];
112
113            if(fabs(p - q) > 0.0001 * 0.0001)
114            {
115                if(src->last_modified == PIPI_PIXELS_Y_F)
116                {
117                    if(src->wrap)
118                        return wrap_std_y_f(src, m, n, mat);
119                    return conv_std_y_f(src, m, n, mat);
120                }
121                else
122                {
123                    if(src->wrap)
124                        return wrap_std_rgba_f(src, m, n, mat);
125                    return conv_std_rgba_f(src, m, n, mat);
126                }
127            }
128        }
129    }
130
131    /* Matrix rank is 1! Separate the filter */
132    hvec = malloc(m * sizeof(double));
133    vvec = malloc(n * sizeof(double));
134
135    tmp = sqrt(fabs(mat[bestj * m + besti]));
136    for(i = 0; i < m; i++)
137        hvec[i] = mat[bestj * m + i] / tmp;
138    for(j = 0; j < n; j++)
139        vvec[j] = mat[j * m + besti] / tmp;
140
141    if(src->last_modified == PIPI_PIXELS_Y_F)
142        ret = src->wrap ? wrap_sep_y_f(src, m, hvec, n, vvec)
143                        : conv_sep_y_f(src, m, hvec, n, vvec);
144    else
145        ret = src->wrap ? wrap_sep_rgba_f(src, m, hvec, n, vvec)
146                        : conv_sep_rgba_f(src, m, hvec, n, vvec);
147
148    free(hvec);
149    free(vvec);
150
151    return ret;
152}
153
Note: See TracBrowser for help on using the repository browser.