Changeset 2743
- Timestamp:
- 08/21/08 00:00:01 (5 years ago)
- File:
-
- 1 edited
-
libpipi/trunk/pipi/filter/blur.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libpipi/trunk/pipi/filter/blur.c
r2737 r2743 116 116 } 117 117 118 /* FIXME: box blur would be incredibly faster using an accumulator instead119 * of a convolution filter... */120 118 pipi_image_t *pipi_box_blur(pipi_image_t *src, int size) 121 119 { … … 123 121 } 124 122 123 /* FIXME: split this into templates for wrap-around and proper gray support */ 125 124 pipi_image_t *pipi_box_blur_ext(pipi_image_t *src, int m, int n) 126 125 { 127 pipi_image_t *ret; 128 double *kernel; 129 int i; 130 131 kernel = malloc(m * n * sizeof(double)); 132 for(i = 0; i < m * n; i++) 133 kernel[i] = 1. / (m * n); 134 135 ret = pipi_convolution(src, m, n, kernel); 136 137 free(kernel); 138 139 return ret; 140 } 141 126 pipi_image_t *dst; 127 pipi_pixels_t *srcp, *dstp; 128 float *srcdata, *dstdata; 129 double *acc; 130 int x, y, w, h, i, j, size, gray; 131 132 w = src->w; 133 h = src->h; 134 size = (2 * m + 1) * (2 * n + 1); 135 136 gray = (src->last_modified == PIPI_PIXELS_Y_F); 137 138 srcp = gray ? pipi_getpixels(src, PIPI_PIXELS_Y_F) 139 : pipi_getpixels(src, PIPI_PIXELS_RGBA_F); 140 srcdata = (float *)srcp->pixels; 141 142 dst = pipi_new(w, h); 143 dstp = gray ? pipi_getpixels(dst, PIPI_PIXELS_Y_F) 144 : pipi_getpixels(dst, PIPI_PIXELS_RGBA_F); 145 dstdata = (float *)dstp->pixels; 146 147 acc = malloc(w * (gray ? 1 : 4) * sizeof(double)); 148 149 /* Step 1: fill the accumulator */ 150 for(x = 0; x < w; x++) 151 { 152 if(gray) 153 { 154 double t = 0.; 155 156 for(j = -n; j <= n; j++) 157 { 158 int j2 = (j < 0) ? h - 1 - ((-j - 1) % h) : j % h; 159 t += srcdata[j2 * w + x]; 160 } 161 162 acc[x] = t; 163 } 164 else 165 { 166 double r = 0., g = 0., b = 0., a = 0.; 167 168 for(j = -n; j <= n; j++) 169 { 170 int j2 = (j < 0) ? h - 1 - ((-j - 1) % h) : j % h; 171 r += srcdata[4 * (j2 * w + x)]; 172 g += srcdata[4 * (j2 * w + x) + 1]; 173 b += srcdata[4 * (j2 * w + x) + 2]; 174 a += srcdata[4 * (j2 * w + x) + 3]; 175 } 176 177 acc[4 * x] = r; 178 acc[4 * x + 1] = g; 179 acc[4 * x + 2] = b; 180 acc[4 * x + 3] = a; 181 } 182 } 183 184 /* Step 2: blur the image, line by line */ 185 for(y = 0; y < h; y++) 186 { 187 double r = 0., g = 0., b = 0., a = 0.; 188 double t = 0.; 189 190 /* 2.1: compute the first pixel */ 191 if(gray) 192 { 193 for(i = -m; i <= m; i++) 194 { 195 int i2 = (i < 0) ? w - 1 - ((-i - 1) % w) : i % w; 196 t += acc[i2]; 197 } 198 } 199 else 200 { 201 for(i = -m; i <= m; i++) 202 { 203 int i2 = (i < 0) ? w - 1 - ((-i - 1) % w) : i % w; 204 r += acc[4 * i2]; 205 g += acc[4 * i2 + 1]; 206 b += acc[4 * i2 + 2]; 207 a += acc[4 * i2 + 3]; 208 } 209 } 210 211 /* 2.2: iterate on the whole line */ 212 for(x = 0; x < w; x++) 213 { 214 int u, u2, v, v2; 215 216 if(gray) 217 { 218 dstdata[y * w + x] = t / size; 219 } 220 else 221 { 222 dstdata[4 * (y * w + x)] = r / size; 223 dstdata[4 * (y * w + x) + 1] = g / size; 224 dstdata[4 * (y * w + x) + 2] = b / size; 225 dstdata[4 * (y * w + x) + 3] = a / size; 226 } 227 228 u = x - m; 229 u2 = (u < 0) ? w - 1 - ((-u - 1) % w) : u % w; 230 v = x + m + 1; 231 v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w; 232 if(gray) 233 { 234 t = t - acc[u2] + acc[v2]; 235 } 236 else 237 { 238 r = r - acc[4 * u2] + acc[4 * v2]; 239 g = g - acc[4 * u2 + 1] + acc[4 * v2 + 1]; 240 b = b - acc[4 * u2 + 2] + acc[4 * v2 + 2]; 241 a = a - acc[4 * u2 + 3] + acc[4 * v2 + 3]; 242 } 243 } 244 245 /* 2.3: update the accumulator */ 246 for(x = 0; x < w; x++) 247 { 248 int u, u2, v, v2; 249 250 u = y - n; 251 u2 = (u < 0) ? w - 1 - ((-u - 1) % w) : u % w; 252 v = y + n + 1; 253 v2 = (v < 0) ? w - 1 - ((-v - 1) % w) : v % w; 254 if(gray) 255 { 256 acc[x] += srcdata[v2 * w + x] - srcdata[u2 * w + x]; 257 } 258 else 259 { 260 int uoff = 4 * (u2 * w + x); 261 int voff = 4 * (v2 * w + x); 262 263 acc[4 * x] += srcdata[voff] - srcdata[uoff]; 264 acc[4 * x + 1] += srcdata[voff + 1] - srcdata[uoff + 1]; 265 acc[4 * x + 2] += srcdata[voff + 2] - srcdata[uoff + 2]; 266 acc[4 * x + 3] += srcdata[voff + 3] - srcdata[uoff + 3]; 267 } 268 } 269 } 270 271 free(acc); 272 273 return dst; 274 } 275
Note: See TracChangeset
for help on using the changeset viewer.
