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

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