1
/* The Unico Theming Engine for Gtk+.
2
* Copyright (C) 2009 Canonical Ltd
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free
16
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19
* Authored by Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
22
* based on exponential-blur algorithm by Jani Huhtanen
26
/* FIXME: not working yet, unfinished */
30
#include "exponential-blur.h"
33
_blurinner (guchar* pixel,
43
_blurrow (guchar* pixels,
53
_blurcol (guchar* pixels,
63
_expblur (guchar* pixels,
72
surface_exponential_blur (cairo_surface_t* surface,
78
cairo_format_t format;
80
/* sanity checks are done in raico-blur.c */
82
/* before we mess with the surface execute any pending drawing */
83
cairo_surface_flush (surface);
85
pixels = cairo_image_surface_get_data (surface);
86
width = cairo_image_surface_get_width (surface);
87
height = cairo_image_surface_get_height (surface);
88
format = cairo_image_surface_get_format (surface);
92
case CAIRO_FORMAT_ARGB32:
93
_expblur (pixels, width, height, 4, radius, 16, 7);
95
case CAIRO_FORMAT_RGB24:
96
_expblur (pixels, width, height, 3, radius, 16, 7);
99
_expblur (pixels, width, height, 1, radius, 16, 7);
105
/* inform cairo we altered the surfaces contents */
106
cairo_surface_mark_dirty (surface);
112
* height image-height
113
* channels image-channels
115
* in-place blur of image 'img' with kernel of approximate radius 'radius'
117
* blurs with two sided exponential impulse response
119
* aprec = precision of alpha parameter in fixed-point format 0.aprec
121
* zprec = precision of state parameters zR,zG,zB and zA in fp format 8.zprec
124
_expblur (guchar* pixels,
139
/* calculate the alpha such that 90% of
140
* the kernel is within the radius.
141
* (Kernel extends to infinity) */
142
alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f))));
144
for (; row < height; row++)
154
for(; col < width; col++)
168
_blurinner (guchar* pixel,
187
*zR += (alpha * ((R << zprec) - *zR)) >> aprec;
188
*zG += (alpha * ((G << zprec) - *zG)) >> aprec;
189
*zB += (alpha * ((B << zprec) - *zB)) >> aprec;
190
*zA += (alpha * ((A << zprec) - *zA)) >> aprec;
192
*pixel = *zR >> zprec;
193
*(pixel + 1) = *zG >> zprec;
194
*(pixel + 2) = *zB >> zprec;
195
*(pixel + 3) = *zA >> zprec;
199
_blurrow (guchar* pixels,
215
scanline = &(pixels[line * width * channels]);
217
zR = *scanline << zprec;
218
zG = *(scanline + 1) << zprec;
219
zB = *(scanline + 2) << zprec;
220
zA = *(scanline + 3) << zprec;
222
for (index = 0; index < width; index ++)
223
_blurinner (&scanline[index * channels],
232
for (index = width - 2; index >= 0; index--)
233
_blurinner (&scanline[index * channels],
244
_blurcol (guchar* pixels,
264
zR = *((guchar*) ptr ) << zprec;
265
zG = *((guchar*) ptr + 1) << zprec;
266
zB = *((guchar*) ptr + 2) << zprec;
267
zA = *((guchar*) ptr + 3) << zprec;
269
for (index = width; index < (height - 1) * width; index += width)
270
_blurinner ((guchar*) &ptr[index * channels],
279
for (index = (height - 2) * width; index >= 0; index -= width)
280
_blurinner ((guchar*) &ptr[index * channels],