+/** Blurs \param src horizontally. \See funtion blur. */
+void blurHorizontal( uint8_t *src, uint8_t *dst, int width, int height, int radius)
+{
+ int x, y, kx, yOff, total, amount, amountInit;
+ amountInit = radius * 2 + 1;
+ for (y = 0; y < height; ++y)
+ {
+ total = 0;
+ yOff = y * width;
+ // Process entire window for first pixel
+ int size = MIN(radius + 1, width);
+ for ( kx = 0; kx < size; ++kx )
+ total += src[yOff + kx];
+ dst[yOff] = total / ( radius + 1 );
+ // Subsequent pixels just update window total
+ for ( x = 1; x < width; ++x )
+ {
+ amount = amountInit;
+ // Subtract pixel leaving window
+ if ( x - radius - 1 >= 0 )
+ total -= src[yOff + x - radius - 1];
+ else
+ amount -= radius - x;
+ // Add pixel entering window
+ if ( x + radius < width )
+ total += src[yOff + x + radius];
+ else
+ amount -= radius - width + x;
+ dst[yOff + x] = total / amount;
+ }
+ }
+}
+
+/** Blurs \param src vertically. \See funtion blur. */
+void blurVertical( uint8_t *src, uint8_t *dst, int width, int height, int radius)
+{
+ int x, y, ky, total, amount, amountInit;
+ amountInit = radius * 2 + 1;
+ for (x = 0; x < width; ++x)
+ {
+ total = 0;
+ int size = MIN(radius + 1, height);
+ for ( ky = 0; ky < size; ++ky )
+ total += src[x + ky * width];
+ dst[x] = total / ( radius + 1 );
+ for ( y = 1; y < height; ++y )
+ {
+ amount = amountInit;
+ if ( y - radius - 1 >= 0 )
+ total -= src[( y - radius - 1 ) * width + x];
+ else
+ amount -= radius - y;
+ if ( y + radius < height )
+ total += src[( y + radius ) * width + x];
+ else
+ amount -= radius - height + y;
+ dst[y * width + x] = total / amount;
+ }
+ }
+}
+
+/**
+ * Blurs the \param map using a simple "average" blur.
+ * \param map Will be blured; 1bpp
+ * \param width x dimension of channel stored in \param map
+ * \param height y dimension of channel stored in \param map
+ * \param radius blur radius
+ * \param passes blur passes
+ */
+void blur( uint8_t *map, int width, int height, int radius, int passes )
+{
+ uint8_t *src = mlt_pool_alloc( width * height );
+ uint8_t *tmp = mlt_pool_alloc( width * height );
+
+ int i;
+ for ( i = 0; i < passes; ++i )
+ {
+ memcpy( src, map, width * height );
+ blurHorizontal( src, tmp, width, height, radius );
+ blurVertical( tmp, map, width, height, radius );
+ }
+
+ mlt_pool_release(src);
+ mlt_pool_release(tmp);
+}
+