/* Surface.c generated by valac 0.56.19, the Vala compiler
 * generated from Surface.vala, do not modify */

/**/
/*  Copyright (C) 2011-2012 Robert Dyer, Rico Tzschichholz*/
/**/
/*  This file is part of Plank.*/
/**/
/*  Plank is free software: you can redistribute it and/or modify*/
/*  it under the terms of the GNU General Public License as published by*/
/*  the Free Software Foundation, either version 3 of the License, or*/
/*  (at your option) any later version.*/
/**/
/*  Plank is distributed in the hope that it will be useful,*/
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of*/
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
/*  GNU General Public License for more details.*/
/**/
/*  You should have received a copy of the GNU General Public License*/
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
/**/

#include "plank.h"
#include <cairo-gobject.h>
#include <glib.h>
#include <glib-object.h>
#include <float.h>
#include <math.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdk.h>
#include <string.h>

#define PLANK_SURFACE_EXP_BLUR_ALPHA_PRECISION 16
#define PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION 7
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	PLANK_SURFACE_0_PROPERTY,
	PLANK_SURFACE_INTERNAL_PROPERTY,
	PLANK_SURFACE_WIDTH_PROPERTY,
	PLANK_SURFACE_HEIGHT_PROPERTY,
	PLANK_SURFACE_CONTEXT_PROPERTY,
	PLANK_SURFACE_NUM_PROPERTIES
};
static GParamSpec* plank_surface_properties[PLANK_SURFACE_NUM_PROPERTIES];
#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _Block5Data Block5Data;
#define _g_thread_unref0(var) ((var == NULL) ? NULL : (var = (g_thread_unref (var), NULL)))
typedef struct _Block6Data Block6Data;
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _PlankSurfacePrivate {
	cairo_surface_t* _Internal;
	gint _Width;
	gint _Height;
	cairo_t* _Context;
};

struct _Block5Data {
	int _ref_count_;
	PlankSurface* self;
	gint alpha;
	gint height;
	gint width;
	guint8* pixels;
};

struct _Block6Data {
	int _ref_count_;
	PlankSurface* self;
	gint gaussWidth;
	gdouble* kernel;
	gint kernel_length1;
	gint _kernel_size_;
	gint width;
	gint height;
	gdouble* abuffer;
	gint abuffer_length1;
	gint _abuffer_size_;
	gdouble* bbuffer;
	gint bbuffer_length1;
	gint _bbuffer_size_;
	gint* shiftar;
	gint shiftar_length1;
	gint shiftar_length2;
	gint _shiftar_size_;
};

static gint PlankSurface_private_offset;
static gpointer plank_surface_parent_class = NULL;

static Block5Data* block5_data_ref (Block5Data* _data5_);
static void block5_data_unref (void * _userdata_);
static void* __lambda4_ (Block5Data* _data5_);
static void plank_surface_exponential_blur_rows (guint8* pixels,
                                          gint width,
                                          gint height,
                                          gint startRow,
                                          gint endRow,
                                          gint startX,
                                          gint endX,
                                          gint alpha);
static gpointer ___lambda4__gthread_func (gpointer self);
static void* __lambda5_ (Block5Data* _data5_);
static void plank_surface_exponential_blur_columns (guint8* pixels,
                                             gint width,
                                             gint height,
                                             gint startCol,
                                             gint endCol,
                                             gint startY,
                                             gint endY,
                                             gint alpha);
static gpointer ___lambda5__gthread_func (gpointer self);
static inline void plank_surface_exponential_blur_inner (guint8* pixel,
                                           gint* zA,
                                           gint* zR,
                                           gint* zG,
                                           gint* zB,
                                           gint alpha);
static Block6Data* block6_data_ref (Block6Data* _data6_);
static void block6_data_unref (void * _userdata_);
static gdouble* plank_surface_build_gaussian_kernel (gint gaussWidth,
                                              gint* result_length1);
static void* __lambda6_ (Block6Data* _data6_);
static void plank_surface_gaussian_blur_horizontal (gdouble* src,
                                             gdouble* dest,
                                             gdouble* kernel,
                                             gint gaussWidth,
                                             gint width,
                                             gint height,
                                             gint startRow,
                                             gint endRow,
                                             gint* shift,
                                             gint shift_length1,
                                             gint shift_length2);
static gpointer ___lambda6__gthread_func (gpointer self);
static void* __lambda7_ (Block6Data* _data6_);
static void plank_surface_gaussian_blur_vertical (gdouble* src,
                                           gdouble* dest,
                                           gdouble* kernel,
                                           gint gaussWidth,
                                           gint width,
                                           gint height,
                                           gint startCol,
                                           gint endCol,
                                           gint* shift,
                                           gint shift_length1,
                                           gint shift_length2);
static gpointer ___lambda7__gthread_func (gpointer self);
static GObject * plank_surface_constructor (GType type,
                                     guint n_construct_properties,
                                     GObjectConstructParam * construct_properties);
static void plank_surface_finalize (GObject * obj);
static GType plank_surface_get_type_once (void);
static void _vala_plank_surface_get_property (GObject * object,
                                       guint property_id,
                                       GValue * value,
                                       GParamSpec * pspec);
static void _vala_plank_surface_set_property (GObject * object,
                                       guint property_id,
                                       const GValue * value,
                                       GParamSpec * pspec);

static inline gpointer
plank_surface_get_instance_private (PlankSurface* self)
{
	return G_STRUCT_MEMBER_P (self, PlankSurface_private_offset);
}

/**
 * Creates a new surface.
 *
 * @param width width of the new surface
 * @param height height of the new surface
 */
PlankSurface*
plank_surface_construct (GType object_type,
                         gint width,
                         gint height)
{
	PlankSurface * self = NULL;
	cairo_surface_t* _tmp0_;
	cairo_surface_t* _tmp1_;
	_tmp0_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
	_tmp1_ = _tmp0_;
	self = (PlankSurface*) g_object_new (object_type, "Width", width, "Height", height, "Internal", _tmp1_, NULL);
	_cairo_surface_destroy0 (_tmp1_);
	return self;
}

PlankSurface*
plank_surface_new (gint width,
                   gint height)
{
	return plank_surface_construct (PLANK_TYPE_SURFACE, width, height);
}

/**
 * Creates a new surface compatible with an existing {@link Cairo.Surface}.
 *
 * @param width width of the new surface
 * @param height height of the new surface
 * @param model existing {@link Cairo.Surface} to be similar to
 */
PlankSurface*
plank_surface_construct_with_cairo_surface (GType object_type,
                                            gint width,
                                            gint height,
                                            cairo_surface_t* model)
{
	PlankSurface * self = NULL;
	cairo_surface_t* _tmp0_;
	cairo_surface_t* _tmp1_;
	g_return_val_if_fail (model != NULL, NULL);
	_tmp0_ = cairo_surface_create_similar (model, CAIRO_CONTENT_COLOR_ALPHA, width, height);
	_tmp1_ = _tmp0_;
	self = (PlankSurface*) g_object_new (object_type, "Width", width, "Height", height, "Internal", _tmp1_, NULL);
	_cairo_surface_destroy0 (_tmp1_);
	return self;
}

PlankSurface*
plank_surface_new_with_cairo_surface (gint width,
                                      gint height,
                                      cairo_surface_t* model)
{
	return plank_surface_construct_with_cairo_surface (PLANK_TYPE_SURFACE, width, height, model);
}

/**
 * Creates a new surface compatible with an existing {@link Surface}.
 *
 * @param width width of the new surface
 * @param height height of the new surface
 * @param model existing {@link Surface} to be similar to
 */
PlankSurface*
plank_surface_construct_with_surface (GType object_type,
                                      gint width,
                                      gint height,
                                      PlankSurface* model)
{
	PlankSurface * self = NULL;
	cairo_surface_t* _tmp0_;
	cairo_surface_t* _tmp1_;
	cairo_surface_t* _tmp2_;
	g_return_val_if_fail (model != NULL, NULL);
	_tmp0_ = model->priv->_Internal;
	_tmp1_ = cairo_surface_create_similar (_tmp0_, CAIRO_CONTENT_COLOR_ALPHA, width, height);
	_tmp2_ = _tmp1_;
	self = (PlankSurface*) g_object_new (object_type, "Width", width, "Height", height, "Internal", _tmp2_, NULL);
	_cairo_surface_destroy0 (_tmp2_);
	return self;
}

PlankSurface*
plank_surface_new_with_surface (gint width,
                                gint height,
                                PlankSurface* model)
{
	return plank_surface_construct_with_surface (PLANK_TYPE_SURFACE, width, height, model);
}

/**
 * Creates a new surface with the given {@link Cairo.ImageSurface} as Internal.
 *
 * @param image existing {@link Cairo.ImageSurface} as Internal
 */
PlankSurface*
plank_surface_construct_with_internal (GType object_type,
                                       cairo_surface_t* image)
{
	PlankSurface * self = NULL;
	g_return_val_if_fail (image != NULL, NULL);
	self = (PlankSurface*) g_object_new (object_type, "Width", cairo_image_surface_get_width (image), "Height", cairo_image_surface_get_height (image), "Internal", image, NULL);
	return self;
}

PlankSurface*
plank_surface_new_with_internal (cairo_surface_t* image)
{
	return plank_surface_construct_with_internal (PLANK_TYPE_SURFACE, image);
}

/**
 * Clears the entire surface.
 */
void
plank_surface_clear (PlankSurface* self)
{
	cairo_t* cr = NULL;
	cairo_t* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_Context;
	cr = _tmp0_;
	cairo_save (cr);
	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint (cr);
	cairo_restore (cr);
}

/**
 * Create a copy of the surface
 *
 * @return copy of this surface
 */
PlankSurface*
plank_surface_copy (PlankSurface* self)
{
	PlankSurface* copy = NULL;
	gint _tmp0_;
	gint _tmp1_;
	PlankSurface* _tmp2_;
	cairo_t* cr = NULL;
	cairo_t* _tmp3_;
	cairo_surface_t* _tmp4_;
	PlankSurface* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_Width;
	_tmp1_ = self->priv->_Height;
	_tmp2_ = plank_surface_new_with_surface (_tmp0_, _tmp1_, self);
	copy = _tmp2_;
	_tmp3_ = copy->priv->_Context;
	cr = _tmp3_;
	_tmp4_ = self->priv->_Internal;
	cairo_set_source_surface (cr, _tmp4_, (gdouble) 0, (gdouble) 0);
	cairo_paint (cr);
	result = copy;
	return result;
}

/**
 * Create a scaled copy of the surface
 *
 * @param width the resulting width
 * @param height the resulting height
 * @return scaled copy of this surface
 */
PlankSurface*
plank_surface_scaled_copy (PlankSurface* self,
                           gint width,
                           gint height)
{
	PlankSurface* _result_ = NULL;
	PlankSurface* _tmp0_;
	cairo_t* cr = NULL;
	cairo_t* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	cairo_surface_t* _tmp4_;
	PlankSurface* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = plank_surface_new_with_surface (width, height, self);
	_result_ = _tmp0_;
	_tmp1_ = _result_->priv->_Context;
	cr = _tmp1_;
	cairo_save (cr);
	_tmp2_ = self->priv->_Width;
	_tmp3_ = self->priv->_Height;
	cairo_scale (cr, ((gdouble) width) / _tmp2_, ((gdouble) height) / _tmp3_);
	_tmp4_ = self->priv->_Internal;
	cairo_set_source_surface (cr, _tmp4_, (gdouble) 0, (gdouble) 0);
	cairo_paint (cr);
	cairo_restore (cr);
	result = _result_;
	return result;
}

/**
 * Saves the current surface to a {@link Gdk.Pixbuf}.
 *
 * @return the {@link Gdk.Pixbuf}
 */
GdkPixbuf*
plank_surface_to_pixbuf (PlankSurface* self)
{
	cairo_surface_t* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	GdkPixbuf* _tmp3_;
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_Internal;
	_tmp1_ = self->priv->_Width;
	_tmp2_ = self->priv->_Height;
	_tmp3_ = gdk_pixbuf_get_from_surface (_tmp0_, 0, 0, _tmp1_, _tmp2_);
	result = _tmp3_;
	return result;
}

/**
 * Computes the mask of the surface.
 *
 * @param threshold value defining the minimum opacity [0.0 .. 1.0]
 * @param extent bounding box of the found mask
 * @return a new surface containing the mask
 */
PlankSurface*
plank_surface_create_mask (PlankSurface* self,
                           gdouble threshold,
                           GdkRectangle* extent)
{
	GdkRectangle _vala_extent = {0};
	cairo_surface_t* surface = NULL;
	gint _tmp0_;
	gint _tmp1_;
	cairo_surface_t* _tmp2_;
	cairo_t* cr = NULL;
	cairo_surface_t* _tmp3_;
	cairo_t* _tmp4_;
	cairo_t* _tmp5_;
	cairo_t* _tmp6_;
	cairo_surface_t* _tmp7_;
	cairo_t* _tmp8_;
	gint w = 0;
	cairo_surface_t* _tmp9_;
	gint h = 0;
	cairo_surface_t* _tmp10_;
	guint8 slice = 0U;
	gint left = 0;
	gint right = 0;
	gint top = 0;
	gint bottom = 0;
	guint8* data = NULL;
	cairo_surface_t* _tmp11_;
	guchar* _tmp12_;
	gint src = 0;
	gboolean mask = FALSE;
	GdkRectangle _tmp24_ = {0};
	cairo_surface_t* _tmp25_;
	PlankSurface* _tmp26_;
	PlankSurface* result;
	g_return_val_if_fail (self != NULL, NULL);
	_vala_return_val_if_fail ((threshold >= 0.0) && (threshold <= 1.0), "threshold >= 0.0 && threshold <= 1.0", NULL);
	_tmp0_ = self->priv->_Width;
	_tmp1_ = self->priv->_Height;
	_tmp2_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, _tmp0_, _tmp1_);
	surface = _tmp2_;
	_tmp3_ = surface;
	_tmp4_ = cairo_create (_tmp3_);
	cr = _tmp4_;
	_tmp5_ = cr;
	cairo_set_operator (_tmp5_, CAIRO_OPERATOR_SOURCE);
	_tmp6_ = cr;
	_tmp7_ = self->priv->_Internal;
	cairo_set_source_surface (_tmp6_, _tmp7_, (gdouble) 0, (gdouble) 0);
	_tmp8_ = cr;
	cairo_paint (_tmp8_);
	_tmp9_ = surface;
	w = cairo_image_surface_get_width (_tmp9_);
	_tmp10_ = surface;
	h = cairo_image_surface_get_height (_tmp10_);
	slice = (guint8) (G_MAXUINT8 * threshold);
	left = w;
	right = 0;
	top = h;
	bottom = 0;
	_tmp11_ = surface;
	_tmp12_ = cairo_image_surface_get_data (_tmp11_);
	data = _tmp12_;
	{
		gint y = 0;
		y = 0;
		{
			gboolean _tmp13_ = FALSE;
			_tmp13_ = TRUE;
			while (TRUE) {
				if (!_tmp13_) {
					gint _tmp14_;
					_tmp14_ = y;
					y = _tmp14_ + 1;
				}
				_tmp13_ = FALSE;
				if (!(y < h)) {
					break;
				}
				{
					gint x = 0;
					x = 0;
					{
						gboolean _tmp15_ = FALSE;
						_tmp15_ = TRUE;
						while (TRUE) {
							guint8* _tmp17_;
							guint8 _tmp18_;
							guint8* _tmp19_;
							guint8* _tmp20_;
							guint8* _tmp21_;
							guint8 _tmp22_ = 0U;
							guint8* _tmp23_;
							if (!_tmp15_) {
								gint _tmp16_;
								_tmp16_ = x;
								x = _tmp16_ + 1;
							}
							_tmp15_ = FALSE;
							if (!(x < w)) {
								break;
							}
							src = ((y * w) + x) * 4;
							_tmp17_ = data;
							_tmp18_ = _tmp17_[src + 3];
							mask = _tmp18_ > slice;
							_tmp19_ = data;
							_tmp19_[src + 0] = (guint8) 0;
							_tmp20_ = data;
							_tmp20_[src + 1] = (guint8) 0;
							_tmp21_ = data;
							_tmp21_[src + 2] = (guint8) 0;
							if (mask) {
								_tmp22_ = G_MAXUINT8;
							} else {
								_tmp22_ = (guint8) 0;
							}
							_tmp23_ = data;
							_tmp23_[src + 3] = _tmp22_;
							if (mask) {
								if (y < top) {
									top = y;
								}
								if (y > bottom) {
									bottom = y;
								}
								if (x < left) {
									left = x;
								}
								if (x > right) {
									right = x;
								}
							}
						}
					}
				}
			}
		}
	}
	_tmp24_.x = left;
	_tmp24_.y = top;
	_tmp24_.width = right - left;
	_tmp24_.height = bottom - top;
	_vala_extent = _tmp24_;
	_tmp25_ = surface;
	_tmp26_ = plank_surface_new_with_internal (_tmp25_);
	result = _tmp26_;
	_cairo_destroy0 (cr);
	_cairo_surface_destroy0 (surface);
	if (extent) {
		*extent = _vala_extent;
	}
	return result;
}

/**
 * Computes and returns the average color of the surface.
 *
 * @return the average color of the surface
 */
void
plank_surface_average_color (PlankSurface* self,
                             PlankColor* result)
{
	cairo_surface_t* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	GdkPixbuf* _tmp3_;
	GdkPixbuf* _tmp4_;
	PlankColor _tmp5_ = {0};
	PlankColor _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_Internal;
	_tmp1_ = self->priv->_Width;
	_tmp2_ = self->priv->_Height;
	_tmp3_ = gdk_pixbuf_get_from_surface (_tmp0_, 0, 0, _tmp1_, _tmp2_);
	_tmp4_ = _tmp3_;
	plank_drawing_service_average_color (_tmp4_, &_tmp5_);
	_tmp6_ = _tmp5_;
	_g_object_unref0 (_tmp4_);
	*result = _tmp6_;
	return;
}

/**
 * Performs a fast blur on the surface.
 *
 * @param radius the radius of the blur
 * @param process_count how many iterations to blur
 */
void
plank_surface_fast_blur (PlankSurface* self,
                         gint radius,
                         gint process_count)
{
	gboolean _tmp0_ = FALSE;
	gint w = 0;
	gint _tmp1_;
	gint h = 0;
	gint _tmp2_;
	gint channels = 0;
	gboolean _tmp3_ = FALSE;
	cairo_surface_t* original = NULL;
	cairo_surface_t* _tmp4_;
	cairo_t* cr = NULL;
	cairo_surface_t* _tmp5_;
	cairo_t* _tmp6_;
	cairo_t* _tmp7_;
	cairo_t* _tmp8_;
	cairo_surface_t* _tmp9_;
	cairo_t* _tmp10_;
	guint8* pixels = NULL;
	cairo_surface_t* _tmp11_;
	guchar* _tmp12_;
	guint8* buffer = NULL;
	guint8* _tmp13_;
	gint buffer_length1;
	gint _buffer_size_;
	gint* vmin = NULL;
	gint* _tmp14_;
	gint vmin_length1;
	gint _vmin_size_;
	gint* vmax = NULL;
	gint* _tmp15_;
	gint vmax_length1;
	gint _vmax_size_;
	gint div = 0;
	guint8* dv = NULL;
	guint8* _tmp16_;
	gint dv_length1;
	gint _dv_size_;
	cairo_surface_t* _tmp138_;
	cairo_t* target_cr = NULL;
	cairo_t* _tmp139_;
	cairo_t* _tmp140_;
	cairo_t* _tmp141_;
	cairo_t* _tmp142_;
	cairo_surface_t* _tmp143_;
	cairo_t* _tmp144_;
	cairo_t* _tmp145_;
	g_return_if_fail (self != NULL);
	if (radius < 1) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = process_count < 1;
	}
	if (_tmp0_) {
		return;
	}
	_tmp1_ = self->priv->_Width;
	w = _tmp1_;
	_tmp2_ = self->priv->_Height;
	h = _tmp2_;
	channels = 4;
	if (radius > (w - 1)) {
		_tmp3_ = TRUE;
	} else {
		_tmp3_ = radius > (h - 1);
	}
	if (_tmp3_) {
		return;
	}
	_tmp4_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
	original = _tmp4_;
	_tmp5_ = original;
	_tmp6_ = cairo_create (_tmp5_);
	cr = _tmp6_;
	_tmp7_ = cr;
	cairo_set_operator (_tmp7_, CAIRO_OPERATOR_SOURCE);
	_tmp8_ = cr;
	_tmp9_ = self->priv->_Internal;
	cairo_set_source_surface (_tmp8_, _tmp9_, (gdouble) 0, (gdouble) 0);
	_tmp10_ = cr;
	cairo_paint (_tmp10_);
	_tmp11_ = original;
	_tmp12_ = cairo_image_surface_get_data (_tmp11_);
	pixels = _tmp12_;
	_tmp13_ = g_new0 (guint8, (w * h) * channels);
	buffer = _tmp13_;
	buffer_length1 = (w * h) * channels;
	_buffer_size_ = buffer_length1;
	_tmp14_ = g_new0 (gint, MAX (w, h));
	vmin = _tmp14_;
	vmin_length1 = MAX (w, h);
	_vmin_size_ = vmin_length1;
	_tmp15_ = g_new0 (gint, MAX (w, h));
	vmax = _tmp15_;
	vmax_length1 = MAX (w, h);
	_vmax_size_ = vmax_length1;
	div = (2 * radius) + 1;
	_tmp16_ = g_new0 (guint8, 256 * div);
	dv = _tmp16_;
	dv_length1 = 256 * div;
	_dv_size_ = dv_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp17_ = FALSE;
			_tmp17_ = TRUE;
			while (TRUE) {
				guint8* _tmp19_;
				gint _tmp19__length1;
				guint8* _tmp20_;
				gint _tmp20__length1;
				if (!_tmp17_) {
					gint _tmp18_;
					_tmp18_ = i;
					i = _tmp18_ + 1;
				}
				_tmp17_ = FALSE;
				_tmp19_ = dv;
				_tmp19__length1 = dv_length1;
				if (!(i < _tmp19__length1)) {
					break;
				}
				_tmp20_ = dv;
				_tmp20__length1 = dv_length1;
				_tmp20_[i] = (guint8) (i / div);
			}
		}
	}
	while (TRUE) {
		gint _tmp21_;
		_tmp21_ = process_count;
		process_count = _tmp21_ - 1;
		if (!(_tmp21_ > 0)) {
			break;
		}
		{
			gint x = 0;
			x = 0;
			{
				gboolean _tmp22_ = FALSE;
				_tmp22_ = TRUE;
				while (TRUE) {
					gint* _tmp24_;
					gint _tmp24__length1;
					gint* _tmp25_;
					gint _tmp25__length1;
					if (!_tmp22_) {
						gint _tmp23_;
						_tmp23_ = x;
						x = _tmp23_ + 1;
					}
					_tmp22_ = FALSE;
					if (!(x < w)) {
						break;
					}
					_tmp24_ = vmin;
					_tmp24__length1 = vmin_length1;
					_tmp24_[x] = MIN ((x + radius) + 1, w - 1);
					_tmp25_ = vmax;
					_tmp25__length1 = vmax_length1;
					_tmp25_[x] = MAX (x - radius, 0);
				}
			}
		}
		{
			gint y = 0;
			y = 0;
			{
				gboolean _tmp26_ = FALSE;
				_tmp26_ = TRUE;
				while (TRUE) {
					gint asum = 0;
					gint rsum = 0;
					gint gsum = 0;
					gint bsum = 0;
					guint32 cur_pixel = 0U;
					guint8* _tmp28_;
					guint8 _tmp29_;
					guint8* _tmp30_;
					guint8 _tmp31_;
					guint8* _tmp32_;
					guint8 _tmp33_;
					guint8* _tmp34_;
					guint8 _tmp35_;
					if (!_tmp26_) {
						gint _tmp27_;
						_tmp27_ = y;
						y = _tmp27_ + 1;
					}
					_tmp26_ = FALSE;
					if (!(y < h)) {
						break;
					}
					asum = 0;
					rsum = 0;
					gsum = 0;
					bsum = 0;
					cur_pixel = (guint32) ((y * w) * channels);
					_tmp28_ = pixels;
					_tmp29_ = _tmp28_[cur_pixel + 0];
					asum += radius * _tmp29_;
					_tmp30_ = pixels;
					_tmp31_ = _tmp30_[cur_pixel + 1];
					rsum += radius * _tmp31_;
					_tmp32_ = pixels;
					_tmp33_ = _tmp32_[cur_pixel + 2];
					gsum += radius * _tmp33_;
					_tmp34_ = pixels;
					_tmp35_ = _tmp34_[cur_pixel + 3];
					bsum += radius * _tmp35_;
					{
						gint i = 0;
						i = 0;
						{
							gboolean _tmp36_ = FALSE;
							_tmp36_ = TRUE;
							while (TRUE) {
								guint8* _tmp38_;
								guint8 _tmp39_;
								guint8* _tmp40_;
								guint8 _tmp41_;
								guint8* _tmp42_;
								guint8 _tmp43_;
								guint8* _tmp44_;
								guint8 _tmp45_;
								if (!_tmp36_) {
									gint _tmp37_;
									_tmp37_ = i;
									i = _tmp37_ + 1;
								}
								_tmp36_ = FALSE;
								if (!(i <= radius)) {
									break;
								}
								_tmp38_ = pixels;
								_tmp39_ = _tmp38_[cur_pixel + 0];
								asum += (gint) _tmp39_;
								_tmp40_ = pixels;
								_tmp41_ = _tmp40_[cur_pixel + 1];
								rsum += (gint) _tmp41_;
								_tmp42_ = pixels;
								_tmp43_ = _tmp42_[cur_pixel + 2];
								gsum += (gint) _tmp43_;
								_tmp44_ = pixels;
								_tmp45_ = _tmp44_[cur_pixel + 3];
								bsum += (gint) _tmp45_;
								cur_pixel += (guint32) channels;
							}
						}
					}
					cur_pixel = (guint32) ((y * w) * channels);
					{
						gint x = 0;
						x = 0;
						{
							gboolean _tmp46_ = FALSE;
							_tmp46_ = TRUE;
							while (TRUE) {
								guint32 p1 = 0U;
								gint* _tmp48_;
								gint _tmp48__length1;
								gint _tmp49_;
								guint32 p2 = 0U;
								gint* _tmp50_;
								gint _tmp50__length1;
								gint _tmp51_;
								guint8* _tmp52_;
								gint _tmp52__length1;
								guint8* _tmp53_;
								gint _tmp53__length1;
								guint8 _tmp54_;
								guint8* _tmp55_;
								gint _tmp55__length1;
								guint8* _tmp56_;
								gint _tmp56__length1;
								guint8 _tmp57_;
								guint8* _tmp58_;
								gint _tmp58__length1;
								guint8* _tmp59_;
								gint _tmp59__length1;
								guint8 _tmp60_;
								guint8* _tmp61_;
								gint _tmp61__length1;
								guint8* _tmp62_;
								gint _tmp62__length1;
								guint8 _tmp63_;
								guint8* _tmp64_;
								guint8 _tmp65_;
								guint8* _tmp66_;
								guint8 _tmp67_;
								guint8* _tmp68_;
								guint8 _tmp69_;
								guint8* _tmp70_;
								guint8 _tmp71_;
								guint8* _tmp72_;
								guint8 _tmp73_;
								guint8* _tmp74_;
								guint8 _tmp75_;
								guint8* _tmp76_;
								guint8 _tmp77_;
								guint8* _tmp78_;
								guint8 _tmp79_;
								if (!_tmp46_) {
									gint _tmp47_;
									_tmp47_ = x;
									x = _tmp47_ + 1;
								}
								_tmp46_ = FALSE;
								if (!(x < w)) {
									break;
								}
								_tmp48_ = vmin;
								_tmp48__length1 = vmin_length1;
								_tmp49_ = _tmp48_[x];
								p1 = (guint32) (((y * w) + _tmp49_) * channels);
								_tmp50_ = vmax;
								_tmp50__length1 = vmax_length1;
								_tmp51_ = _tmp50_[x];
								p2 = (guint32) (((y * w) + _tmp51_) * channels);
								_tmp52_ = buffer;
								_tmp52__length1 = buffer_length1;
								_tmp53_ = dv;
								_tmp53__length1 = dv_length1;
								_tmp54_ = _tmp53_[asum];
								_tmp52_[cur_pixel + 0] = _tmp54_;
								_tmp55_ = buffer;
								_tmp55__length1 = buffer_length1;
								_tmp56_ = dv;
								_tmp56__length1 = dv_length1;
								_tmp57_ = _tmp56_[rsum];
								_tmp55_[cur_pixel + 1] = _tmp57_;
								_tmp58_ = buffer;
								_tmp58__length1 = buffer_length1;
								_tmp59_ = dv;
								_tmp59__length1 = dv_length1;
								_tmp60_ = _tmp59_[gsum];
								_tmp58_[cur_pixel + 2] = _tmp60_;
								_tmp61_ = buffer;
								_tmp61__length1 = buffer_length1;
								_tmp62_ = dv;
								_tmp62__length1 = dv_length1;
								_tmp63_ = _tmp62_[bsum];
								_tmp61_[cur_pixel + 3] = _tmp63_;
								_tmp64_ = pixels;
								_tmp65_ = _tmp64_[p1 + 0];
								_tmp66_ = pixels;
								_tmp67_ = _tmp66_[p2 + 0];
								asum += (gint) (_tmp65_ - _tmp67_);
								_tmp68_ = pixels;
								_tmp69_ = _tmp68_[p1 + 1];
								_tmp70_ = pixels;
								_tmp71_ = _tmp70_[p2 + 1];
								rsum += (gint) (_tmp69_ - _tmp71_);
								_tmp72_ = pixels;
								_tmp73_ = _tmp72_[p1 + 2];
								_tmp74_ = pixels;
								_tmp75_ = _tmp74_[p2 + 2];
								gsum += (gint) (_tmp73_ - _tmp75_);
								_tmp76_ = pixels;
								_tmp77_ = _tmp76_[p1 + 3];
								_tmp78_ = pixels;
								_tmp79_ = _tmp78_[p2 + 3];
								bsum += (gint) (_tmp77_ - _tmp79_);
								cur_pixel += (guint32) channels;
							}
						}
					}
				}
			}
		}
		{
			gint y = 0;
			y = 0;
			{
				gboolean _tmp80_ = FALSE;
				_tmp80_ = TRUE;
				while (TRUE) {
					gint* _tmp82_;
					gint _tmp82__length1;
					gint* _tmp83_;
					gint _tmp83__length1;
					if (!_tmp80_) {
						gint _tmp81_;
						_tmp81_ = y;
						y = _tmp81_ + 1;
					}
					_tmp80_ = FALSE;
					if (!(y < h)) {
						break;
					}
					_tmp82_ = vmin;
					_tmp82__length1 = vmin_length1;
					_tmp82_[y] = MIN ((y + radius) + 1, h - 1) * w;
					_tmp83_ = vmax;
					_tmp83__length1 = vmax_length1;
					_tmp83_[y] = MAX (y - radius, 0) * w;
				}
			}
		}
		{
			gint x = 0;
			x = 0;
			{
				gboolean _tmp84_ = FALSE;
				_tmp84_ = TRUE;
				while (TRUE) {
					gint asum = 0;
					gint rsum = 0;
					gint gsum = 0;
					gint bsum = 0;
					guint32 cur_pixel = 0U;
					guint8* _tmp86_;
					gint _tmp86__length1;
					guint8 _tmp87_;
					guint8* _tmp88_;
					gint _tmp88__length1;
					guint8 _tmp89_;
					guint8* _tmp90_;
					gint _tmp90__length1;
					guint8 _tmp91_;
					guint8* _tmp92_;
					gint _tmp92__length1;
					guint8 _tmp93_;
					if (!_tmp84_) {
						gint _tmp85_;
						_tmp85_ = x;
						x = _tmp85_ + 1;
					}
					_tmp84_ = FALSE;
					if (!(x < w)) {
						break;
					}
					asum = 0;
					rsum = 0;
					gsum = 0;
					bsum = 0;
					cur_pixel = (guint32) (x * channels);
					_tmp86_ = buffer;
					_tmp86__length1 = buffer_length1;
					_tmp87_ = _tmp86_[cur_pixel + 0];
					asum += radius * _tmp87_;
					_tmp88_ = buffer;
					_tmp88__length1 = buffer_length1;
					_tmp89_ = _tmp88_[cur_pixel + 1];
					rsum += radius * _tmp89_;
					_tmp90_ = buffer;
					_tmp90__length1 = buffer_length1;
					_tmp91_ = _tmp90_[cur_pixel + 2];
					gsum += radius * _tmp91_;
					_tmp92_ = buffer;
					_tmp92__length1 = buffer_length1;
					_tmp93_ = _tmp92_[cur_pixel + 3];
					bsum += radius * _tmp93_;
					{
						gint i = 0;
						i = 0;
						{
							gboolean _tmp94_ = FALSE;
							_tmp94_ = TRUE;
							while (TRUE) {
								guint8* _tmp96_;
								gint _tmp96__length1;
								guint8 _tmp97_;
								guint8* _tmp98_;
								gint _tmp98__length1;
								guint8 _tmp99_;
								guint8* _tmp100_;
								gint _tmp100__length1;
								guint8 _tmp101_;
								guint8* _tmp102_;
								gint _tmp102__length1;
								guint8 _tmp103_;
								if (!_tmp94_) {
									gint _tmp95_;
									_tmp95_ = i;
									i = _tmp95_ + 1;
								}
								_tmp94_ = FALSE;
								if (!(i <= radius)) {
									break;
								}
								_tmp96_ = buffer;
								_tmp96__length1 = buffer_length1;
								_tmp97_ = _tmp96_[cur_pixel + 0];
								asum += (gint) _tmp97_;
								_tmp98_ = buffer;
								_tmp98__length1 = buffer_length1;
								_tmp99_ = _tmp98_[cur_pixel + 1];
								rsum += (gint) _tmp99_;
								_tmp100_ = buffer;
								_tmp100__length1 = buffer_length1;
								_tmp101_ = _tmp100_[cur_pixel + 2];
								gsum += (gint) _tmp101_;
								_tmp102_ = buffer;
								_tmp102__length1 = buffer_length1;
								_tmp103_ = _tmp102_[cur_pixel + 3];
								bsum += (gint) _tmp103_;
								cur_pixel += (guint32) (w * channels);
							}
						}
					}
					cur_pixel = (guint32) (x * channels);
					{
						gint y = 0;
						y = 0;
						{
							gboolean _tmp104_ = FALSE;
							_tmp104_ = TRUE;
							while (TRUE) {
								guint32 p1 = 0U;
								gint* _tmp106_;
								gint _tmp106__length1;
								gint _tmp107_;
								guint32 p2 = 0U;
								gint* _tmp108_;
								gint _tmp108__length1;
								gint _tmp109_;
								guint8* _tmp110_;
								guint8* _tmp111_;
								gint _tmp111__length1;
								guint8 _tmp112_;
								guint8* _tmp113_;
								guint8* _tmp114_;
								gint _tmp114__length1;
								guint8 _tmp115_;
								guint8* _tmp116_;
								guint8* _tmp117_;
								gint _tmp117__length1;
								guint8 _tmp118_;
								guint8* _tmp119_;
								guint8* _tmp120_;
								gint _tmp120__length1;
								guint8 _tmp121_;
								guint8* _tmp122_;
								gint _tmp122__length1;
								guint8 _tmp123_;
								guint8* _tmp124_;
								gint _tmp124__length1;
								guint8 _tmp125_;
								guint8* _tmp126_;
								gint _tmp126__length1;
								guint8 _tmp127_;
								guint8* _tmp128_;
								gint _tmp128__length1;
								guint8 _tmp129_;
								guint8* _tmp130_;
								gint _tmp130__length1;
								guint8 _tmp131_;
								guint8* _tmp132_;
								gint _tmp132__length1;
								guint8 _tmp133_;
								guint8* _tmp134_;
								gint _tmp134__length1;
								guint8 _tmp135_;
								guint8* _tmp136_;
								gint _tmp136__length1;
								guint8 _tmp137_;
								if (!_tmp104_) {
									gint _tmp105_;
									_tmp105_ = y;
									y = _tmp105_ + 1;
								}
								_tmp104_ = FALSE;
								if (!(y < h)) {
									break;
								}
								_tmp106_ = vmin;
								_tmp106__length1 = vmin_length1;
								_tmp107_ = _tmp106_[y];
								p1 = (guint32) ((x + _tmp107_) * channels);
								_tmp108_ = vmax;
								_tmp108__length1 = vmax_length1;
								_tmp109_ = _tmp108_[y];
								p2 = (guint32) ((x + _tmp109_) * channels);
								_tmp110_ = pixels;
								_tmp111_ = dv;
								_tmp111__length1 = dv_length1;
								_tmp112_ = _tmp111_[asum];
								_tmp110_[cur_pixel + 0] = _tmp112_;
								_tmp113_ = pixels;
								_tmp114_ = dv;
								_tmp114__length1 = dv_length1;
								_tmp115_ = _tmp114_[rsum];
								_tmp113_[cur_pixel + 1] = _tmp115_;
								_tmp116_ = pixels;
								_tmp117_ = dv;
								_tmp117__length1 = dv_length1;
								_tmp118_ = _tmp117_[gsum];
								_tmp116_[cur_pixel + 2] = _tmp118_;
								_tmp119_ = pixels;
								_tmp120_ = dv;
								_tmp120__length1 = dv_length1;
								_tmp121_ = _tmp120_[bsum];
								_tmp119_[cur_pixel + 3] = _tmp121_;
								_tmp122_ = buffer;
								_tmp122__length1 = buffer_length1;
								_tmp123_ = _tmp122_[p1 + 0];
								_tmp124_ = buffer;
								_tmp124__length1 = buffer_length1;
								_tmp125_ = _tmp124_[p2 + 0];
								asum += (gint) (_tmp123_ - _tmp125_);
								_tmp126_ = buffer;
								_tmp126__length1 = buffer_length1;
								_tmp127_ = _tmp126_[p1 + 1];
								_tmp128_ = buffer;
								_tmp128__length1 = buffer_length1;
								_tmp129_ = _tmp128_[p2 + 1];
								rsum += (gint) (_tmp127_ - _tmp129_);
								_tmp130_ = buffer;
								_tmp130__length1 = buffer_length1;
								_tmp131_ = _tmp130_[p1 + 2];
								_tmp132_ = buffer;
								_tmp132__length1 = buffer_length1;
								_tmp133_ = _tmp132_[p2 + 2];
								gsum += (gint) (_tmp131_ - _tmp133_);
								_tmp134_ = buffer;
								_tmp134__length1 = buffer_length1;
								_tmp135_ = _tmp134_[p1 + 3];
								_tmp136_ = buffer;
								_tmp136__length1 = buffer_length1;
								_tmp137_ = _tmp136_[p2 + 3];
								bsum += (gint) (_tmp135_ - _tmp137_);
								cur_pixel += (guint32) (w * channels);
							}
						}
					}
				}
			}
		}
	}
	_tmp138_ = original;
	cairo_surface_mark_dirty (_tmp138_);
	_tmp139_ = self->priv->_Context;
	target_cr = _tmp139_;
	_tmp140_ = target_cr;
	cairo_save (_tmp140_);
	_tmp141_ = target_cr;
	cairo_set_operator (_tmp141_, CAIRO_OPERATOR_SOURCE);
	_tmp142_ = target_cr;
	_tmp143_ = original;
	cairo_set_source_surface (_tmp142_, _tmp143_, (gdouble) 0, (gdouble) 0);
	_tmp144_ = target_cr;
	cairo_paint (_tmp144_);
	_tmp145_ = target_cr;
	cairo_restore (_tmp145_);
	dv = (g_free (dv), NULL);
	vmax = (g_free (vmax), NULL);
	vmin = (g_free (vmin), NULL);
	buffer = (g_free (buffer), NULL);
	_cairo_destroy0 (cr);
	_cairo_surface_destroy0 (original);
}

/**
 * Performs an exponential blur on the surface.
 *
 * @param radius the radius of the blur
 */
static Block5Data*
block5_data_ref (Block5Data* _data5_)
{
	g_atomic_int_inc (&_data5_->_ref_count_);
	return _data5_;
}

static void
block5_data_unref (void * _userdata_)
{
	Block5Data* _data5_;
	_data5_ = (Block5Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data5_->_ref_count_)) {
		PlankSurface* self;
		self = _data5_->self;
		_g_object_unref0 (self);
		g_slice_free (Block5Data, _data5_);
	}
}

static void*
__lambda4_ (Block5Data* _data5_)
{
	PlankSurface* self;
	guint8* _tmp0_;
	void* result;
	self = _data5_->self;
	_tmp0_ = _data5_->pixels;
	plank_surface_exponential_blur_rows (_tmp0_, _data5_->width, _data5_->height, 0, _data5_->height / 2, 0, _data5_->width, _data5_->alpha);
	result = NULL;
	return result;
}

static gpointer
___lambda4__gthread_func (gpointer self)
{
	gpointer result;
	result = __lambda4_ (self);
	block5_data_unref (self);
	return result;
}

static void*
__lambda5_ (Block5Data* _data5_)
{
	PlankSurface* self;
	guint8* _tmp0_;
	void* result;
	self = _data5_->self;
	_tmp0_ = _data5_->pixels;
	plank_surface_exponential_blur_columns (_tmp0_, _data5_->width, _data5_->height, 0, _data5_->width / 2, 0, _data5_->height, _data5_->alpha);
	result = NULL;
	return result;
}

static gpointer
___lambda5__gthread_func (gpointer self)
{
	gpointer result;
	result = __lambda5_ (self);
	block5_data_unref (self);
	return result;
}

void
plank_surface_exponential_blur (PlankSurface* self,
                                gint radius)
{
	Block5Data* _data5_;
	gint _tmp0_;
	gint _tmp1_;
	cairo_surface_t* original = NULL;
	cairo_surface_t* _tmp2_;
	cairo_t* cr = NULL;
	cairo_surface_t* _tmp3_;
	cairo_t* _tmp4_;
	cairo_t* _tmp5_;
	cairo_t* _tmp6_;
	cairo_surface_t* _tmp7_;
	cairo_t* _tmp8_;
	cairo_surface_t* _tmp9_;
	guchar* _tmp10_;
	GThread* th = NULL;
	GThread* _tmp11_;
	guint8* _tmp12_;
	GThread* _tmp13_;
	GThread* th2 = NULL;
	GThread* _tmp14_;
	guint8* _tmp15_;
	GThread* _tmp16_;
	cairo_surface_t* _tmp17_;
	cairo_t* target_cr = NULL;
	cairo_t* _tmp18_;
	cairo_t* _tmp19_;
	cairo_t* _tmp20_;
	cairo_t* _tmp21_;
	cairo_surface_t* _tmp22_;
	cairo_t* _tmp23_;
	cairo_t* _tmp24_;
	g_return_if_fail (self != NULL);
	_data5_ = g_slice_new0 (Block5Data);
	_data5_->_ref_count_ = 1;
	_data5_->self = g_object_ref (self);
	if (radius < 1) {
		block5_data_unref (_data5_);
		_data5_ = NULL;
		return;
	}
	_data5_->alpha = (gint) ((1 << PLANK_SURFACE_EXP_BLUR_ALPHA_PRECISION) * (1.0 - exp ((-2.3) / (radius + 1.0))));
	_tmp0_ = self->priv->_Height;
	_data5_->height = _tmp0_;
	_tmp1_ = self->priv->_Width;
	_data5_->width = _tmp1_;
	_tmp2_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, _data5_->width, _data5_->height);
	original = _tmp2_;
	_tmp3_ = original;
	_tmp4_ = cairo_create (_tmp3_);
	cr = _tmp4_;
	_tmp5_ = cr;
	cairo_set_operator (_tmp5_, CAIRO_OPERATOR_SOURCE);
	_tmp6_ = cr;
	_tmp7_ = self->priv->_Internal;
	cairo_set_source_surface (_tmp6_, _tmp7_, (gdouble) 0, (gdouble) 0);
	_tmp8_ = cr;
	cairo_paint (_tmp8_);
	_tmp9_ = original;
	_tmp10_ = cairo_image_surface_get_data (_tmp9_);
	_data5_->pixels = _tmp10_;
	_tmp11_ = g_thread_new (NULL, ___lambda4__gthread_func, block5_data_ref (_data5_));
	th = _tmp11_;
	_tmp12_ = _data5_->pixels;
	plank_surface_exponential_blur_rows (_tmp12_, _data5_->width, _data5_->height, _data5_->height / 2, _data5_->height, 0, _data5_->width, _data5_->alpha);
	_tmp13_ = th;
	th = NULL;
	g_thread_join (_tmp13_);
	_tmp14_ = g_thread_new (NULL, ___lambda5__gthread_func, block5_data_ref (_data5_));
	th2 = _tmp14_;
	_tmp15_ = _data5_->pixels;
	plank_surface_exponential_blur_columns (_tmp15_, _data5_->width, _data5_->height, _data5_->width / 2, _data5_->width, 0, _data5_->height, _data5_->alpha);
	_tmp16_ = th2;
	th2 = NULL;
	g_thread_join (_tmp16_);
	_tmp17_ = original;
	cairo_surface_mark_dirty (_tmp17_);
	_tmp18_ = self->priv->_Context;
	target_cr = _tmp18_;
	_tmp19_ = target_cr;
	cairo_save (_tmp19_);
	_tmp20_ = target_cr;
	cairo_set_operator (_tmp20_, CAIRO_OPERATOR_SOURCE);
	_tmp21_ = target_cr;
	_tmp22_ = original;
	cairo_set_source_surface (_tmp21_, _tmp22_, (gdouble) 0, (gdouble) 0);
	_tmp23_ = target_cr;
	cairo_paint (_tmp23_);
	_tmp24_ = target_cr;
	cairo_restore (_tmp24_);
	_g_thread_unref0 (th2);
	_g_thread_unref0 (th);
	_cairo_destroy0 (cr);
	_cairo_surface_destroy0 (original);
	block5_data_unref (_data5_);
	_data5_ = NULL;
}

static void
plank_surface_exponential_blur_columns (guint8* pixels,
                                        gint width,
                                        gint height,
                                        gint startCol,
                                        gint endCol,
                                        gint startY,
                                        gint endY,
                                        gint alpha)
{
	{
		gint columnIndex = 0;
		columnIndex = startCol;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8* column = NULL;
				gint zA = 0;
				guint8* _tmp2_;
				guint8 _tmp3_;
				gint zR = 0;
				guint8* _tmp4_;
				guint8 _tmp5_;
				gint zG = 0;
				guint8* _tmp6_;
				guint8 _tmp7_;
				gint zB = 0;
				guint8* _tmp8_;
				guint8 _tmp9_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = columnIndex;
					columnIndex = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(columnIndex < endCol)) {
					break;
				}
				column = pixels + (columnIndex * 4);
				_tmp2_ = column;
				_tmp3_ = _tmp2_[0];
				zA = _tmp3_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				_tmp4_ = column;
				_tmp5_ = _tmp4_[1];
				zR = _tmp5_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				_tmp6_ = column;
				_tmp7_ = _tmp6_[2];
				zG = _tmp7_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				_tmp8_ = column;
				_tmp9_ = _tmp8_[3];
				zB = _tmp9_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				{
					gint index = 0;
					index = width * (startY + 1);
					{
						gboolean _tmp10_ = FALSE;
						_tmp10_ = TRUE;
						while (TRUE) {
							guint8* _tmp11_;
							if (!_tmp10_) {
								index += width;
							}
							_tmp10_ = FALSE;
							if (!(index < ((endY - 1) * width))) {
								break;
							}
							_tmp11_ = column;
							plank_surface_exponential_blur_inner (&_tmp11_[index * 4], &zA, &zR, &zG, &zB, alpha);
						}
					}
				}
				{
					gint index = 0;
					index = (endY - 2) * width;
					{
						gboolean _tmp12_ = FALSE;
						_tmp12_ = TRUE;
						while (TRUE) {
							guint8* _tmp13_;
							if (!_tmp12_) {
								index -= width;
							}
							_tmp12_ = FALSE;
							if (!(index >= startY)) {
								break;
							}
							_tmp13_ = column;
							plank_surface_exponential_blur_inner (&_tmp13_[index * 4], &zA, &zR, &zG, &zB, alpha);
						}
					}
				}
			}
		}
	}
}

static void
plank_surface_exponential_blur_rows (guint8* pixels,
                                     gint width,
                                     gint height,
                                     gint startRow,
                                     gint endRow,
                                     gint startX,
                                     gint endX,
                                     gint alpha)
{
	{
		gint rowIndex = 0;
		rowIndex = startRow;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint8* row = NULL;
				gint zA = 0;
				guint8* _tmp2_;
				guint8 _tmp3_;
				gint zR = 0;
				guint8* _tmp4_;
				guint8 _tmp5_;
				gint zG = 0;
				guint8* _tmp6_;
				guint8 _tmp7_;
				gint zB = 0;
				guint8* _tmp8_;
				guint8 _tmp9_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = rowIndex;
					rowIndex = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(rowIndex < endRow)) {
					break;
				}
				row = pixels + ((rowIndex * width) * 4);
				_tmp2_ = row;
				_tmp3_ = _tmp2_[startX + 0];
				zA = _tmp3_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				_tmp4_ = row;
				_tmp5_ = _tmp4_[startX + 1];
				zR = _tmp5_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				_tmp6_ = row;
				_tmp7_ = _tmp6_[startX + 2];
				zG = _tmp7_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				_tmp8_ = row;
				_tmp9_ = _tmp8_[startX + 3];
				zB = _tmp9_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION;
				{
					gint index = 0;
					index = startX + 1;
					{
						gboolean _tmp10_ = FALSE;
						_tmp10_ = TRUE;
						while (TRUE) {
							guint8* _tmp12_;
							if (!_tmp10_) {
								gint _tmp11_;
								_tmp11_ = index;
								index = _tmp11_ + 1;
							}
							_tmp10_ = FALSE;
							if (!(index < endX)) {
								break;
							}
							_tmp12_ = row;
							plank_surface_exponential_blur_inner (&_tmp12_[index * 4], &zA, &zR, &zG, &zB, alpha);
						}
					}
				}
				{
					gint index = 0;
					index = endX - 2;
					{
						gboolean _tmp13_ = FALSE;
						_tmp13_ = TRUE;
						while (TRUE) {
							guint8* _tmp15_;
							if (!_tmp13_) {
								gint _tmp14_;
								_tmp14_ = index;
								index = _tmp14_ - 1;
							}
							_tmp13_ = FALSE;
							if (!(index >= startX)) {
								break;
							}
							_tmp15_ = row;
							plank_surface_exponential_blur_inner (&_tmp15_[index * 4], &zA, &zR, &zG, &zB, alpha);
						}
					}
				}
			}
		}
	}
}

static inline void
plank_surface_exponential_blur_inner (guint8* pixel,
                                      gint* zA,
                                      gint* zR,
                                      gint* zG,
                                      gint* zB,
                                      gint alpha)
{
	guint8 _tmp0_;
	guint8 _tmp1_;
	guint8 _tmp2_;
	guint8 _tmp3_;
	_tmp0_ = pixel[0];
	*zA = (*zA) + ((alpha * ((_tmp0_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION) - (*zA))) >> PLANK_SURFACE_EXP_BLUR_ALPHA_PRECISION);
	_tmp1_ = pixel[1];
	*zR = (*zR) + ((alpha * ((_tmp1_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION) - (*zR))) >> PLANK_SURFACE_EXP_BLUR_ALPHA_PRECISION);
	_tmp2_ = pixel[2];
	*zG = (*zG) + ((alpha * ((_tmp2_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION) - (*zG))) >> PLANK_SURFACE_EXP_BLUR_ALPHA_PRECISION);
	_tmp3_ = pixel[3];
	*zB = (*zB) + ((alpha * ((_tmp3_ << PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION) - (*zB))) >> PLANK_SURFACE_EXP_BLUR_ALPHA_PRECISION);
	pixel[0] = (guint8) ((*zA) >> PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION);
	pixel[1] = (guint8) ((*zR) >> PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION);
	pixel[2] = (guint8) ((*zG) >> PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION);
	pixel[3] = (guint8) ((*zB) >> PLANK_SURFACE_EXP_BLUR_PARAM_PRECISION);
}

/**
 * Performs a gaussian blur on the surface.
 * ''Note: This method is wickedly slow''
 *
 * @param radius the radius of the blur
 */
static Block6Data*
block6_data_ref (Block6Data* _data6_)
{
	g_atomic_int_inc (&_data6_->_ref_count_);
	return _data6_;
}

static void
block6_data_unref (void * _userdata_)
{
	Block6Data* _data6_;
	_data6_ = (Block6Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data6_->_ref_count_)) {
		PlankSurface* self;
		self = _data6_->self;
		_data6_->shiftar = (g_free (_data6_->shiftar), NULL);
		_data6_->bbuffer = (g_free (_data6_->bbuffer), NULL);
		_data6_->abuffer = (g_free (_data6_->abuffer), NULL);
		_data6_->kernel = (g_free (_data6_->kernel), NULL);
		_g_object_unref0 (self);
		g_slice_free (Block6Data, _data6_);
	}
}

static void*
__lambda6_ (Block6Data* _data6_)
{
	PlankSurface* self;
	gdouble* _tmp0_;
	gint _tmp0__length1;
	gdouble* _tmp1_;
	gint _tmp1__length1;
	gdouble* _tmp2_;
	gint _tmp2__length1;
	gint* _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	void* result;
	self = _data6_->self;
	_tmp0_ = _data6_->abuffer;
	_tmp0__length1 = _data6_->abuffer_length1;
	_tmp1_ = _data6_->bbuffer;
	_tmp1__length1 = _data6_->bbuffer_length1;
	_tmp2_ = _data6_->kernel;
	_tmp2__length1 = _data6_->kernel_length1;
	_tmp3_ = _data6_->shiftar;
	_tmp3__length1 = _data6_->shiftar_length1;
	_tmp3__length2 = _data6_->shiftar_length2;
	plank_surface_gaussian_blur_horizontal (_tmp0_, _tmp1_, _tmp2_, _data6_->gaussWidth, _data6_->width, _data6_->height, 0, _data6_->height / 2, _tmp3_, (gint) _tmp3__length1, (gint) _tmp3__length2);
	result = NULL;
	return result;
}

static gpointer
___lambda6__gthread_func (gpointer self)
{
	gpointer result;
	result = __lambda6_ (self);
	block6_data_unref (self);
	return result;
}

static void*
__lambda7_ (Block6Data* _data6_)
{
	PlankSurface* self;
	gdouble* _tmp0_;
	gint _tmp0__length1;
	gdouble* _tmp1_;
	gint _tmp1__length1;
	gdouble* _tmp2_;
	gint _tmp2__length1;
	gint* _tmp3_;
	gint _tmp3__length1;
	gint _tmp3__length2;
	void* result;
	self = _data6_->self;
	_tmp0_ = _data6_->bbuffer;
	_tmp0__length1 = _data6_->bbuffer_length1;
	_tmp1_ = _data6_->abuffer;
	_tmp1__length1 = _data6_->abuffer_length1;
	_tmp2_ = _data6_->kernel;
	_tmp2__length1 = _data6_->kernel_length1;
	_tmp3_ = _data6_->shiftar;
	_tmp3__length1 = _data6_->shiftar_length1;
	_tmp3__length2 = _data6_->shiftar_length2;
	plank_surface_gaussian_blur_vertical (_tmp0_, _tmp1_, _tmp2_, _data6_->gaussWidth, _data6_->width, _data6_->height, 0, _data6_->width / 2, _tmp3_, (gint) _tmp3__length1, (gint) _tmp3__length2);
	result = NULL;
	return result;
}

static gpointer
___lambda7__gthread_func (gpointer self)
{
	gpointer result;
	result = __lambda7_ (self);
	block6_data_unref (self);
	return result;
}

void
plank_surface_gaussian_blur (PlankSurface* self,
                             gint radius)
{
	Block6Data* _data6_;
	gint _tmp0_ = 0;
	gdouble* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	cairo_surface_t* original = NULL;
	cairo_surface_t* _tmp4_;
	cairo_t* cr = NULL;
	cairo_surface_t* _tmp5_;
	cairo_t* _tmp6_;
	cairo_t* _tmp7_;
	cairo_t* _tmp8_;
	cairo_surface_t* _tmp9_;
	cairo_t* _tmp10_;
	guint8* src = NULL;
	cairo_surface_t* _tmp11_;
	guchar* _tmp12_;
	gint size = 0;
	cairo_surface_t* _tmp13_;
	gdouble* _tmp14_;
	gdouble* _tmp15_;
	gint* _tmp21_;
	GThread* th = NULL;
	GThread* _tmp29_;
	gdouble* _tmp30_;
	gint _tmp30__length1;
	gdouble* _tmp31_;
	gint _tmp31__length1;
	gdouble* _tmp32_;
	gint _tmp32__length1;
	gint* _tmp33_;
	gint _tmp33__length1;
	gint _tmp33__length2;
	GThread* _tmp34_;
	gdouble* _tmp35_;
	gint _tmp35__length1;
	gint* _tmp36_;
	GThread* th2 = NULL;
	GThread* _tmp44_;
	gdouble* _tmp45_;
	gint _tmp45__length1;
	gdouble* _tmp46_;
	gint _tmp46__length1;
	gdouble* _tmp47_;
	gint _tmp47__length1;
	gint* _tmp48_;
	gint _tmp48__length1;
	gint _tmp48__length2;
	GThread* _tmp49_;
	cairo_surface_t* _tmp55_;
	cairo_t* target_cr = NULL;
	cairo_t* _tmp56_;
	cairo_t* _tmp57_;
	cairo_t* _tmp58_;
	cairo_t* _tmp59_;
	cairo_surface_t* _tmp60_;
	cairo_t* _tmp61_;
	cairo_t* _tmp62_;
	g_return_if_fail (self != NULL);
	_data6_ = g_slice_new0 (Block6Data);
	_data6_->_ref_count_ = 1;
	_data6_->self = g_object_ref (self);
	if (radius < 1) {
		block6_data_unref (_data6_);
		_data6_ = NULL;
		return;
	}
	_data6_->gaussWidth = (radius * 2) + 1;
	_tmp1_ = plank_surface_build_gaussian_kernel (_data6_->gaussWidth, &_tmp0_);
	_data6_->kernel = _tmp1_;
	_data6_->kernel_length1 = _tmp0_;
	_data6_->_kernel_size_ = _data6_->kernel_length1;
	_tmp2_ = self->priv->_Width;
	_data6_->width = _tmp2_;
	_tmp3_ = self->priv->_Height;
	_data6_->height = _tmp3_;
	_tmp4_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, _data6_->width, _data6_->height);
	original = _tmp4_;
	_tmp5_ = original;
	_tmp6_ = cairo_create (_tmp5_);
	cr = _tmp6_;
	_tmp7_ = cr;
	cairo_set_operator (_tmp7_, CAIRO_OPERATOR_SOURCE);
	_tmp8_ = cr;
	_tmp9_ = self->priv->_Internal;
	cairo_set_source_surface (_tmp8_, _tmp9_, (gdouble) 0, (gdouble) 0);
	_tmp10_ = cr;
	cairo_paint (_tmp10_);
	_tmp11_ = original;
	_tmp12_ = cairo_image_surface_get_data (_tmp11_);
	src = _tmp12_;
	_tmp13_ = original;
	size = _data6_->height * cairo_image_surface_get_stride (_tmp13_);
	_tmp14_ = g_new0 (gdouble, size);
	_data6_->abuffer = _tmp14_;
	_data6_->abuffer_length1 = size;
	_data6_->_abuffer_size_ = _data6_->abuffer_length1;
	_tmp15_ = g_new0 (gdouble, size);
	_data6_->bbuffer = _tmp15_;
	_data6_->bbuffer_length1 = size;
	_data6_->_bbuffer_size_ = _data6_->bbuffer_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp16_ = FALSE;
			_tmp16_ = TRUE;
			while (TRUE) {
				gdouble* _tmp18_;
				gint _tmp18__length1;
				guint8* _tmp19_;
				guint8 _tmp20_;
				if (!_tmp16_) {
					gint _tmp17_;
					_tmp17_ = i;
					i = _tmp17_ + 1;
				}
				_tmp16_ = FALSE;
				if (!(i < size)) {
					break;
				}
				_tmp18_ = _data6_->abuffer;
				_tmp18__length1 = _data6_->abuffer_length1;
				_tmp19_ = src;
				_tmp20_ = _tmp19_[i];
				_tmp18_[i] = (gdouble) _tmp20_;
			}
		}
	}
	_tmp21_ = g_new0 (gint, MAX (_data6_->width, _data6_->height) * _data6_->gaussWidth);
	_data6_->shiftar = _tmp21_;
	_data6_->shiftar_length1 = MAX (_data6_->width, _data6_->height);
	_data6_->shiftar_length2 = _data6_->gaussWidth;
	{
		gint x = 0;
		x = 0;
		{
			gboolean _tmp22_ = FALSE;
			_tmp22_ = TRUE;
			while (TRUE) {
				if (!_tmp22_) {
					gint _tmp23_;
					_tmp23_ = x;
					x = _tmp23_ + 1;
				}
				_tmp22_ = FALSE;
				if (!(x < _data6_->width)) {
					break;
				}
				{
					gint k = 0;
					k = 0;
					{
						gboolean _tmp24_ = FALSE;
						_tmp24_ = TRUE;
						while (TRUE) {
							gint shift = 0;
							gboolean _tmp26_ = FALSE;
							if (!_tmp24_) {
								gint _tmp25_;
								_tmp25_ = k;
								k = _tmp25_ + 1;
							}
							_tmp24_ = FALSE;
							if (!(k < _data6_->gaussWidth)) {
								break;
							}
							shift = k - radius;
							if ((x + shift) <= 0) {
								_tmp26_ = TRUE;
							} else {
								_tmp26_ = (x + shift) >= _data6_->width;
							}
							if (_tmp26_) {
								gint* _tmp27_;
								gint _tmp27__length1;
								gint _tmp27__length2;
								_tmp27_ = _data6_->shiftar;
								_tmp27__length1 = _data6_->shiftar_length1;
								_tmp27__length2 = _data6_->shiftar_length2;
								_tmp27_[(x * _tmp27__length2) + k] = 0;
							} else {
								gint* _tmp28_;
								gint _tmp28__length1;
								gint _tmp28__length2;
								_tmp28_ = _data6_->shiftar;
								_tmp28__length1 = _data6_->shiftar_length1;
								_tmp28__length2 = _data6_->shiftar_length2;
								_tmp28_[(x * _tmp28__length2) + k] = shift * 4;
							}
						}
					}
				}
			}
		}
	}
	_tmp29_ = g_thread_new (NULL, ___lambda6__gthread_func, block6_data_ref (_data6_));
	th = _tmp29_;
	_tmp30_ = _data6_->abuffer;
	_tmp30__length1 = _data6_->abuffer_length1;
	_tmp31_ = _data6_->bbuffer;
	_tmp31__length1 = _data6_->bbuffer_length1;
	_tmp32_ = _data6_->kernel;
	_tmp32__length1 = _data6_->kernel_length1;
	_tmp33_ = _data6_->shiftar;
	_tmp33__length1 = _data6_->shiftar_length1;
	_tmp33__length2 = _data6_->shiftar_length2;
	plank_surface_gaussian_blur_horizontal (_tmp30_, _tmp31_, _tmp32_, _data6_->gaussWidth, _data6_->width, _data6_->height, _data6_->height / 2, _data6_->height, _tmp33_, (gint) _tmp33__length1, (gint) _tmp33__length2);
	_tmp34_ = th;
	th = NULL;
	g_thread_join (_tmp34_);
	_tmp35_ = _data6_->abuffer;
	_tmp35__length1 = _data6_->abuffer_length1;
	memset (_tmp35_, 0, (gsize) (sizeof (gdouble) * size));
	_tmp36_ = g_new0 (gint, MAX (_data6_->width, _data6_->height) * _data6_->gaussWidth);
	_data6_->shiftar = (g_free (_data6_->shiftar), NULL);
	_data6_->shiftar = _tmp36_;
	_data6_->shiftar_length1 = MAX (_data6_->width, _data6_->height);
	_data6_->shiftar_length2 = _data6_->gaussWidth;
	{
		gint y = 0;
		y = 0;
		{
			gboolean _tmp37_ = FALSE;
			_tmp37_ = TRUE;
			while (TRUE) {
				if (!_tmp37_) {
					gint _tmp38_;
					_tmp38_ = y;
					y = _tmp38_ + 1;
				}
				_tmp37_ = FALSE;
				if (!(y < _data6_->height)) {
					break;
				}
				{
					gint k = 0;
					k = 0;
					{
						gboolean _tmp39_ = FALSE;
						_tmp39_ = TRUE;
						while (TRUE) {
							gint shift = 0;
							gboolean _tmp41_ = FALSE;
							if (!_tmp39_) {
								gint _tmp40_;
								_tmp40_ = k;
								k = _tmp40_ + 1;
							}
							_tmp39_ = FALSE;
							if (!(k < _data6_->gaussWidth)) {
								break;
							}
							shift = k - radius;
							if ((y + shift) <= 0) {
								_tmp41_ = TRUE;
							} else {
								_tmp41_ = (y + shift) >= _data6_->height;
							}
							if (_tmp41_) {
								gint* _tmp42_;
								gint _tmp42__length1;
								gint _tmp42__length2;
								_tmp42_ = _data6_->shiftar;
								_tmp42__length1 = _data6_->shiftar_length1;
								_tmp42__length2 = _data6_->shiftar_length2;
								_tmp42_[(y * _tmp42__length2) + k] = 0;
							} else {
								gint* _tmp43_;
								gint _tmp43__length1;
								gint _tmp43__length2;
								_tmp43_ = _data6_->shiftar;
								_tmp43__length1 = _data6_->shiftar_length1;
								_tmp43__length2 = _data6_->shiftar_length2;
								_tmp43_[(y * _tmp43__length2) + k] = (shift * _data6_->width) * 4;
							}
						}
					}
				}
			}
		}
	}
	_tmp44_ = g_thread_new (NULL, ___lambda7__gthread_func, block6_data_ref (_data6_));
	th2 = _tmp44_;
	_tmp45_ = _data6_->bbuffer;
	_tmp45__length1 = _data6_->bbuffer_length1;
	_tmp46_ = _data6_->abuffer;
	_tmp46__length1 = _data6_->abuffer_length1;
	_tmp47_ = _data6_->kernel;
	_tmp47__length1 = _data6_->kernel_length1;
	_tmp48_ = _data6_->shiftar;
	_tmp48__length1 = _data6_->shiftar_length1;
	_tmp48__length2 = _data6_->shiftar_length2;
	plank_surface_gaussian_blur_vertical (_tmp45_, _tmp46_, _tmp47_, _data6_->gaussWidth, _data6_->width, _data6_->height, _data6_->width / 2, _data6_->width, _tmp48_, (gint) _tmp48__length1, (gint) _tmp48__length2);
	_tmp49_ = th2;
	th2 = NULL;
	g_thread_join (_tmp49_);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp50_ = FALSE;
			_tmp50_ = TRUE;
			while (TRUE) {
				guint8* _tmp52_;
				gdouble* _tmp53_;
				gint _tmp53__length1;
				gdouble _tmp54_;
				if (!_tmp50_) {
					gint _tmp51_;
					_tmp51_ = i;
					i = _tmp51_ + 1;
				}
				_tmp50_ = FALSE;
				if (!(i < size)) {
					break;
				}
				_tmp52_ = src;
				_tmp53_ = _data6_->abuffer;
				_tmp53__length1 = _data6_->abuffer_length1;
				_tmp54_ = _tmp53_[i];
				_tmp52_[i] = (guint8) _tmp54_;
			}
		}
	}
	_tmp55_ = original;
	cairo_surface_mark_dirty (_tmp55_);
	_tmp56_ = self->priv->_Context;
	target_cr = _tmp56_;
	_tmp57_ = target_cr;
	cairo_save (_tmp57_);
	_tmp58_ = target_cr;
	cairo_set_operator (_tmp58_, CAIRO_OPERATOR_SOURCE);
	_tmp59_ = target_cr;
	_tmp60_ = original;
	cairo_set_source_surface (_tmp59_, _tmp60_, (gdouble) 0, (gdouble) 0);
	_tmp61_ = target_cr;
	cairo_paint (_tmp61_);
	_tmp62_ = target_cr;
	cairo_restore (_tmp62_);
	_g_thread_unref0 (th2);
	_g_thread_unref0 (th);
	_cairo_destroy0 (cr);
	_cairo_surface_destroy0 (original);
	block6_data_unref (_data6_);
	_data6_ = NULL;
}

static void
plank_surface_gaussian_blur_horizontal (gdouble* src,
                                        gdouble* dest,
                                        gdouble* kernel,
                                        gint gaussWidth,
                                        gint width,
                                        gint height,
                                        gint startRow,
                                        gint endRow,
                                        gint* shift,
                                        gint shift_length1,
                                        gint shift_length2)
{
	guint32 cur_pixel = 0U;
	cur_pixel = (guint32) ((startRow * width) * 4);
	{
		gint y = 0;
		y = startRow;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = y;
					y = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(y < endRow)) {
					break;
				}
				{
					gint x = 0;
					x = 0;
					{
						gboolean _tmp2_ = FALSE;
						_tmp2_ = TRUE;
						while (TRUE) {
							if (!_tmp2_) {
								gint _tmp3_;
								_tmp3_ = x;
								x = _tmp3_ + 1;
							}
							_tmp2_ = FALSE;
							if (!(x < width)) {
								break;
							}
							{
								gint k = 0;
								k = 0;
								{
									gboolean _tmp4_ = FALSE;
									_tmp4_ = TRUE;
									while (TRUE) {
										guint32 source = 0U;
										gint _tmp6_;
										gdouble kernel_k = 0.0;
										gdouble _tmp7_;
										gdouble _tmp8_;
										gdouble _tmp9_;
										gdouble _tmp10_;
										gdouble _tmp11_;
										if (!_tmp4_) {
											gint _tmp5_;
											_tmp5_ = k;
											k = _tmp5_ + 1;
										}
										_tmp4_ = FALSE;
										if (!(k < gaussWidth)) {
											break;
										}
										_tmp6_ = shift[(x * shift_length2) + k];
										source = cur_pixel + _tmp6_;
										_tmp7_ = kernel[k];
										kernel_k = _tmp7_;
										_tmp8_ = src[source + 0];
										dest[cur_pixel + 0] += _tmp8_ * kernel_k;
										_tmp9_ = src[source + 1];
										dest[cur_pixel + 1] += _tmp9_ * kernel_k;
										_tmp10_ = src[source + 2];
										dest[cur_pixel + 2] += _tmp10_ * kernel_k;
										_tmp11_ = src[source + 3];
										dest[cur_pixel + 3] += _tmp11_ * kernel_k;
									}
								}
							}
							cur_pixel += (guint32) 4;
						}
					}
				}
			}
		}
	}
}

static void
plank_surface_gaussian_blur_vertical (gdouble* src,
                                      gdouble* dest,
                                      gdouble* kernel,
                                      gint gaussWidth,
                                      gint width,
                                      gint height,
                                      gint startCol,
                                      gint endCol,
                                      gint* shift,
                                      gint shift_length1,
                                      gint shift_length2)
{
	guint32 cur_pixel = 0U;
	cur_pixel = (guint32) (startCol * 4);
	{
		gint y = 0;
		y = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = y;
					y = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(y < height)) {
					break;
				}
				{
					gint x = 0;
					x = startCol;
					{
						gboolean _tmp2_ = FALSE;
						_tmp2_ = TRUE;
						while (TRUE) {
							if (!_tmp2_) {
								gint _tmp3_;
								_tmp3_ = x;
								x = _tmp3_ + 1;
							}
							_tmp2_ = FALSE;
							if (!(x < endCol)) {
								break;
							}
							{
								gint k = 0;
								k = 0;
								{
									gboolean _tmp4_ = FALSE;
									_tmp4_ = TRUE;
									while (TRUE) {
										guint32 source = 0U;
										gint _tmp6_;
										gdouble kernel_k = 0.0;
										gdouble _tmp7_;
										gdouble _tmp8_;
										gdouble _tmp9_;
										gdouble _tmp10_;
										gdouble _tmp11_;
										if (!_tmp4_) {
											gint _tmp5_;
											_tmp5_ = k;
											k = _tmp5_ + 1;
										}
										_tmp4_ = FALSE;
										if (!(k < gaussWidth)) {
											break;
										}
										_tmp6_ = shift[(y * shift_length2) + k];
										source = cur_pixel + _tmp6_;
										_tmp7_ = kernel[k];
										kernel_k = _tmp7_;
										_tmp8_ = src[source + 0];
										dest[cur_pixel + 0] += _tmp8_ * kernel_k;
										_tmp9_ = src[source + 1];
										dest[cur_pixel + 1] += _tmp9_ * kernel_k;
										_tmp10_ = src[source + 2];
										dest[cur_pixel + 2] += _tmp10_ * kernel_k;
										_tmp11_ = src[source + 3];
										dest[cur_pixel + 3] += _tmp11_ * kernel_k;
									}
								}
							}
							cur_pixel += (guint32) 4;
						}
					}
				}
				cur_pixel += (guint32) (((width - endCol) + startCol) * 4);
			}
		}
	}
}

static gdouble*
plank_surface_build_gaussian_kernel (gint gaussWidth,
                                     gint* result_length1)
{
	gdouble* kernel = NULL;
	gdouble* _tmp0_;
	gint kernel_length1;
	gint _kernel_size_;
	gdouble sd = 0.0;
	gint range = 0;
	gdouble mean = 0.0;
	gdouble gaussSum = 0.0;
	gdouble* _tmp5_;
	gint _tmp5__length1;
	gdouble* _tmp12_;
	gint _tmp12__length1;
	gdouble* result;
	_vala_return_val_if_fail ((gaussWidth % 2) == 1, "gaussWidth % 2 == 1", NULL);
	_tmp0_ = g_new0 (gdouble, gaussWidth);
	kernel = _tmp0_;
	kernel_length1 = gaussWidth;
	_kernel_size_ = kernel_length1;
	sd = 255.0;
	range = gaussWidth;
	mean = range / sd;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = TRUE;
			while (TRUE) {
				gdouble* _tmp3_;
				gint _tmp3__length1;
				gdouble* _tmp4_;
				gint _tmp4__length1;
				if (!_tmp1_) {
					gint _tmp2_;
					_tmp2_ = i;
					i = _tmp2_ + 1;
				}
				_tmp1_ = FALSE;
				if (!(i < ((gaussWidth / 2) + 1))) {
					break;
				}
				_tmp3_ = kernel;
				_tmp3__length1 = kernel_length1;
				_tmp4_ = kernel;
				_tmp4__length1 = kernel_length1;
				_tmp4_[i] = pow (sin ((((i + 1) * G_PI_2) - mean) / range), (gdouble) 2) * sd;
				_tmp3_[(gaussWidth - i) - 1] = _tmp4_[i];
			}
		}
	}
	gaussSum = 0.0;
	_tmp5_ = kernel;
	_tmp5__length1 = kernel_length1;
	{
		gdouble* d_collection = NULL;
		gint d_collection_length1 = 0;
		gint _d_collection_size_ = 0;
		gint d_it = 0;
		d_collection = _tmp5_;
		d_collection_length1 = _tmp5__length1;
		for (d_it = 0; d_it < d_collection_length1; d_it = d_it + 1) {
			gdouble d = 0.0;
			d = d_collection[d_it];
			{
				gaussSum += d;
			}
		}
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				gdouble* _tmp8_;
				gint _tmp8__length1;
				gdouble* _tmp9_;
				gint _tmp9__length1;
				gdouble* _tmp10_;
				gint _tmp10__length1;
				gdouble _tmp11_;
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = i;
					i = _tmp7_ + 1;
				}
				_tmp6_ = FALSE;
				_tmp8_ = kernel;
				_tmp8__length1 = kernel_length1;
				if (!(i < _tmp8__length1)) {
					break;
				}
				_tmp9_ = kernel;
				_tmp9__length1 = kernel_length1;
				_tmp10_ = kernel;
				_tmp10__length1 = kernel_length1;
				_tmp11_ = _tmp10_[i];
				_tmp9_[i] = _tmp11_ / gaussSum;
			}
		}
	}
	_tmp12_ = kernel;
	_tmp12__length1 = kernel_length1;
	if (result_length1) {
		*result_length1 = _tmp12__length1;
	}
	result = _tmp12_;
	return result;
}

cairo_surface_t*
plank_surface_get_Internal (PlankSurface* self)
{
	cairo_surface_t* result;
	cairo_surface_t* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_Internal;
	result = _tmp0_;
	return result;
}

static gpointer
_cairo_surface_reference0 (gpointer self)
{
	return self ? cairo_surface_reference (self) : NULL;
}

static void
plank_surface_set_Internal (PlankSurface* self,
                            cairo_surface_t* value)
{
	cairo_surface_t* old_value;
	g_return_if_fail (self != NULL);
	old_value = plank_surface_get_Internal (self);
	if (old_value != value) {
		cairo_surface_t* _tmp0_;
		_tmp0_ = _cairo_surface_reference0 (value);
		_cairo_surface_destroy0 (self->priv->_Internal);
		self->priv->_Internal = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, plank_surface_properties[PLANK_SURFACE_INTERNAL_PROPERTY]);
	}
}

gint
plank_surface_get_Width (PlankSurface* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_Width;
	return result;
}

static void
plank_surface_set_Width (PlankSurface* self,
                         gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = plank_surface_get_Width (self);
	if (old_value != value) {
		self->priv->_Width = value;
		g_object_notify_by_pspec ((GObject *) self, plank_surface_properties[PLANK_SURFACE_WIDTH_PROPERTY]);
	}
}

gint
plank_surface_get_Height (PlankSurface* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_Height;
	return result;
}

static void
plank_surface_set_Height (PlankSurface* self,
                          gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = plank_surface_get_Height (self);
	if (old_value != value) {
		self->priv->_Height = value;
		g_object_notify_by_pspec ((GObject *) self, plank_surface_properties[PLANK_SURFACE_HEIGHT_PROPERTY]);
	}
}

cairo_t*
plank_surface_get_Context (PlankSurface* self)
{
	cairo_t* result;
	cairo_t* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_Context;
	result = _tmp0_;
	return result;
}

static gpointer
_cairo_reference0 (gpointer self)
{
	return self ? cairo_reference (self) : NULL;
}

static void
plank_surface_set_Context (PlankSurface* self,
                           cairo_t* value)
{
	cairo_t* old_value;
	g_return_if_fail (self != NULL);
	old_value = plank_surface_get_Context (self);
	if (old_value != value) {
		cairo_t* _tmp0_;
		_tmp0_ = _cairo_reference0 (value);
		_cairo_destroy0 (self->priv->_Context);
		self->priv->_Context = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, plank_surface_properties[PLANK_SURFACE_CONTEXT_PROPERTY]);
	}
}

static GObject *
plank_surface_constructor (GType type,
                           guint n_construct_properties,
                           GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	PlankSurface * self;
	cairo_surface_t* _tmp0_;
	cairo_t* _tmp1_;
	cairo_t* _tmp2_;
	parent_class = G_OBJECT_CLASS (plank_surface_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, PLANK_TYPE_SURFACE, PlankSurface);
	_tmp0_ = self->priv->_Internal;
	_tmp1_ = cairo_create (_tmp0_);
	_tmp2_ = _tmp1_;
	plank_surface_set_Context (self, _tmp2_);
	_cairo_destroy0 (_tmp2_);
	return obj;
}

static void
plank_surface_class_init (PlankSurfaceClass * klass,
                          gpointer klass_data)
{
	plank_surface_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &PlankSurface_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_plank_surface_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_plank_surface_set_property;
	G_OBJECT_CLASS (klass)->constructor = plank_surface_constructor;
	G_OBJECT_CLASS (klass)->finalize = plank_surface_finalize;
	/**
	 * The internal {@link Cairo.Surface} backing the surface.
	 */
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLANK_SURFACE_INTERNAL_PROPERTY, plank_surface_properties[PLANK_SURFACE_INTERNAL_PROPERTY] = g_param_spec_boxed ("Internal", "Internal", "Internal", cairo_gobject_surface_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	/**
	 * The width of the surface.
	 */
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLANK_SURFACE_WIDTH_PROPERTY, plank_surface_properties[PLANK_SURFACE_WIDTH_PROPERTY] = g_param_spec_int ("Width", "Width", "Width", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	/**
	 * The height of the surface.
	 */
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLANK_SURFACE_HEIGHT_PROPERTY, plank_surface_properties[PLANK_SURFACE_HEIGHT_PROPERTY] = g_param_spec_int ("Height", "Height", "Height", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	/**
	 * A {@link Cairo.Context} for the surface.
	 */
	g_object_class_install_property (G_OBJECT_CLASS (klass), PLANK_SURFACE_CONTEXT_PROPERTY, plank_surface_properties[PLANK_SURFACE_CONTEXT_PROPERTY] = g_param_spec_boxed ("Context", "Context", "Context", cairo_gobject_context_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}

static void
plank_surface_instance_init (PlankSurface * self,
                             gpointer klass)
{
	self->priv = plank_surface_get_instance_private (self);
}

static void
plank_surface_finalize (GObject * obj)
{
	PlankSurface * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, PLANK_TYPE_SURFACE, PlankSurface);
	_cairo_surface_destroy0 (self->priv->_Internal);
	_cairo_destroy0 (self->priv->_Context);
	G_OBJECT_CLASS (plank_surface_parent_class)->finalize (obj);
}

/**
 * A surface is a wrapper class for a {@link Cairo.Surface}.
 * It encapsulates a surface/context and provides utility methods.
 */
static GType
plank_surface_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PlankSurfaceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) plank_surface_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PlankSurface), 0, (GInstanceInitFunc) plank_surface_instance_init, NULL };
	GType plank_surface_type_id;
	plank_surface_type_id = g_type_register_static (G_TYPE_OBJECT, "PlankSurface", &g_define_type_info, 0);
	PlankSurface_private_offset = g_type_add_instance_private (plank_surface_type_id, sizeof (PlankSurfacePrivate));
	return plank_surface_type_id;
}

GType
plank_surface_get_type (void)
{
	static volatile gsize plank_surface_type_id__once = 0;
	if (g_once_init_enter (&plank_surface_type_id__once)) {
		GType plank_surface_type_id;
		plank_surface_type_id = plank_surface_get_type_once ();
		g_once_init_leave (&plank_surface_type_id__once, plank_surface_type_id);
	}
	return plank_surface_type_id__once;
}

static void
_vala_plank_surface_get_property (GObject * object,
                                  guint property_id,
                                  GValue * value,
                                  GParamSpec * pspec)
{
	PlankSurface * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, PLANK_TYPE_SURFACE, PlankSurface);
	switch (property_id) {
		case PLANK_SURFACE_INTERNAL_PROPERTY:
		g_value_set_boxed (value, plank_surface_get_Internal (self));
		break;
		case PLANK_SURFACE_WIDTH_PROPERTY:
		g_value_set_int (value, plank_surface_get_Width (self));
		break;
		case PLANK_SURFACE_HEIGHT_PROPERTY:
		g_value_set_int (value, plank_surface_get_Height (self));
		break;
		case PLANK_SURFACE_CONTEXT_PROPERTY:
		g_value_set_boxed (value, plank_surface_get_Context (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_plank_surface_set_property (GObject * object,
                                  guint property_id,
                                  const GValue * value,
                                  GParamSpec * pspec)
{
	PlankSurface * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, PLANK_TYPE_SURFACE, PlankSurface);
	switch (property_id) {
		case PLANK_SURFACE_INTERNAL_PROPERTY:
		plank_surface_set_Internal (self, g_value_get_boxed (value));
		break;
		case PLANK_SURFACE_WIDTH_PROPERTY:
		plank_surface_set_Width (self, g_value_get_int (value));
		break;
		case PLANK_SURFACE_HEIGHT_PROPERTY:
		plank_surface_set_Height (self, g_value_get_int (value));
		break;
		case PLANK_SURFACE_CONTEXT_PROPERTY:
		plank_surface_set_Context (self, g_value_get_boxed (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

