source: libpipi/trunk/pipi/filter/convolution_template.h @ 2710

Revision 2710, 6.6 KB checked in by sam, 5 years ago (diff)
  • convolution.c: move local function prototypes to convolution_template.h.
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_template.h: convolution templates
17 * required macros:
18 *   FUNC1  standard function name
19 *   FUNC2  separable function name
20 *   PIXEL  pixel type
21 *   FLAGS  1 (grayscale)
22 *          2 (loop)
23 */
24
25static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[]);
26static pipi_image_t *FUNC2(pipi_image_t *src, int m, double hvec[],
27                                              int n, double vvec[]);
28
29static pipi_image_t *FUNC1(pipi_image_t *src, int m, int n, double mat[])
30{
31    pipi_image_t *dst;
32    pipi_pixels_t *srcp, *dstp;
33    PIXEL *srcdata, *dstdata;
34    int x, y, i, j, w, h;
35
36    w = src->w;
37    h = src->h;
38
39    srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
40                     : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
41    srcdata = (PIXEL *)srcp->pixels;
42
43    dst = pipi_new(w, h);
44    dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
45                     : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
46    dstdata = (PIXEL *)dstp->pixels;
47
48    for(y = 0; y < h; y++)
49    {
50        for(x = 0; x < w; x++)
51        {
52            if(FLAG_GRAY)
53            {
54                double Y = 0.;
55                int x2, y2;
56
57                for(j = 0; j < n; j++)
58                {
59                    y2 = y + j - n / 2;
60                    if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
61                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
62
63                    for(i = 0; i < m; i++)
64                    {
65                        x2 = x + i - m / 2;
66                        if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
67                        else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
68
69                        Y += mat[j * m + i] * srcdata[y2 * w + x2];
70                    }
71                }
72
73                dstdata[y * w + x] = Y;
74            }
75            else
76            {
77                double R = 0., G = 0., B = 0.;
78                int x2, y2, off = 4 * (y * w + x);
79
80                for(j = 0; j < n; j++)
81                {
82                    y2 = y + j - n / 2;
83                    if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
84                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
85
86                    for(i = 0; i < m; i++)
87                    {
88                        double f = mat[j * m + i];
89
90                        x2 = x + i - m / 2;
91                        if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
92                        else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
93
94                        R += f * srcdata[(y2 * w + x2) * 4];
95                        G += f * srcdata[(y2 * w + x2) * 4 + 1];
96                        B += f * srcdata[(y2 * w + x2) * 4 + 2];
97                    }
98                }
99
100                dstdata[off] = R;
101                dstdata[off + 1] = G;
102                dstdata[off + 2] = B;
103            }
104        }
105    }
106
107    return dst;
108}
109
110static pipi_image_t *FUNC2(pipi_image_t *src,
111                           int m, double hvec[], int n, double vvec[])
112{
113    pipi_image_t *dst;
114    pipi_pixels_t *srcp, *dstp;
115    PIXEL *srcdata, *dstdata;
116    double *buffer;
117    int x, y, i, j, w, h;
118
119    w = src->w;
120    h = src->h;
121
122    srcp = FLAG_GRAY ? pipi_getpixels(src, PIPI_PIXELS_Y_F)
123                     : pipi_getpixels(src, PIPI_PIXELS_RGBA_F);
124    srcdata = (PIXEL *)srcp->pixels;
125
126    dst = pipi_new(w, h);
127    dstp = FLAG_GRAY ? pipi_getpixels(dst, PIPI_PIXELS_Y_F)
128                     : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F);
129    dstdata = (PIXEL *)dstp->pixels;
130
131    buffer = malloc(w * h * (FLAG_GRAY ? 1 : 4) * sizeof(double));
132
133    for(y = 0; y < h; y++)
134    {
135        for(x = 0; x < w; x++)
136        {
137            if(FLAG_GRAY)
138            {
139                double Y = 0.;
140                int x2;
141
142                for(i = 0; i < m; i++)
143                {
144                    x2 = x + i - m / 2;
145                    if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
146                    else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
147
148                    Y += hvec[i] * srcdata[y * w + x2];
149                }
150
151                buffer[y * w + x] = Y;
152            }
153            else
154            {
155                double R = 0., G = 0., B = 0.;
156                int x2, off = 4 * (y * w + x);
157
158                for(i = 0; i < m; i++)
159                {
160                    double f = hvec[i];
161
162                    x2 = x + i - m / 2;
163                    if(x2 < 0) x2 = FLAG_WRAP ? (w - 1 - (-x2 - 1) % w) : 0;
164                    else if(x2 >= w) x2 = FLAG_WRAP ? x2 % w : w - 1;
165
166                    R += f * srcdata[(y * w + x2) * 4];
167                    G += f * srcdata[(y * w + x2) * 4 + 1];
168                    B += f * srcdata[(y * w + x2) * 4 + 2];
169                }
170
171                buffer[off] = R;
172                buffer[off + 1] = G;
173                buffer[off + 2] = B;
174            }
175        }
176    }
177
178    for(y = 0; y < h; y++)
179    {
180        for(x = 0; x < w; x++)
181        {
182            if(FLAG_GRAY)
183            {
184                double Y = 0.;
185                int y2;
186
187                for(j = 0; j < n; j++)
188                {
189                    y2 = y + j - n / 2;
190                    if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
191                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
192
193                    Y += vvec[j] * buffer[y2 * w + x];
194                }
195
196                dstdata[y * w + x] = Y;
197            }
198            else
199            {
200                double R = 0., G = 0., B = 0.;
201                int y2, off = 4 * (y * w + x);
202
203                for(j = 0; j < n; j++)
204                {
205                    double f = vvec[j];
206
207                    y2 = y + j - n / 2;
208                    if(y2 < 0) y2 = FLAG_WRAP ? (h - 1 - (-y2 - 1) % h) : 0;
209                    else if(y2 >= h) y2 = FLAG_WRAP ? y2 % h : h - 1;
210
211                    R += f * buffer[(y2 * w + x) * 4];
212                    G += f * buffer[(y2 * w + x) * 4 + 1];
213                    B += f * buffer[(y2 * w + x) * 4 + 2];
214                }
215
216                dstdata[off] = R;
217                dstdata[off + 1] = G;
218                dstdata[off + 2] = B;
219            }
220        }
221    }
222
223    free(buffer);
224
225    return dst;
226}
227
Note: See TracBrowser for help on using the repository browser.