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

/* Copyright 2016 Software Freedom Conservancy Inc.
 *
 * This software is licensed under the GNU LGPL (version 2.1 or later).
 * See the COPYING file in this distribution.
 */

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

#define MIN_SCALED_WIDTH 10
#define MIN_SCALED_HEIGHT 10
#define DEGREE (G_PI / 180.0)
#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
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

#define TYPE_DIMENSIONS (dimensions_get_type ())
typedef struct _Dimensions Dimensions;
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))
#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))

#define TYPE_CONFIGURATION_FACADE (configuration_facade_get_type ())
#define CONFIGURATION_FACADE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CONFIGURATION_FACADE, ConfigurationFacade))
#define CONFIGURATION_FACADE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CONFIGURATION_FACADE, ConfigurationFacadeClass))
#define IS_CONFIGURATION_FACADE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CONFIGURATION_FACADE))
#define IS_CONFIGURATION_FACADE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CONFIGURATION_FACADE))
#define CONFIGURATION_FACADE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CONFIGURATION_FACADE, ConfigurationFacadeClass))

typedef struct _ConfigurationFacade ConfigurationFacade;
typedef struct _ConfigurationFacadeClass ConfigurationFacadeClass;

#define CONFIG_TYPE_FACADE (config_facade_get_type ())
#define CONFIG_FACADE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CONFIG_TYPE_FACADE, ConfigFacade))
#define CONFIG_FACADE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CONFIG_TYPE_FACADE, ConfigFacadeClass))
#define CONFIG_IS_FACADE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CONFIG_TYPE_FACADE))
#define CONFIG_IS_FACADE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CONFIG_TYPE_FACADE))
#define CONFIG_FACADE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CONFIG_TYPE_FACADE, ConfigFacadeClass))

typedef struct _ConfigFacade ConfigFacade;
typedef struct _ConfigFacadeClass ConfigFacadeClass;
#define _g_free0(var) (var = (g_free (var), NULL))

#define TYPE_BOX (box_get_type ())
typedef struct _Box Box;
#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 _Dimensions {
	gint width;
	gint height;
};

struct _Box {
	gint left;
	gint top;
	gint right;
	gint bottom;
};

VALA_EXTERN cairo_surface_t* background_surface;
cairo_surface_t* background_surface = NULL;

VALA_EXTERN void parse_color (const gchar* spec,
                  GdkRGBA* result);
VALA_EXTERN void fetch_color (const gchar* spec,
                  GdkRGBA* result);
VALA_EXTERN void set_source_color_from_string (cairo_t* ctx,
                                   const gchar* spec);
VALA_EXTERN GdkPixbuf* get_placeholder_pixbuf (void);
VALA_EXTERN GdkPixbuf* scale_pixbuf (GdkPixbuf* pixbuf,
                         gint scale,
                         GdkInterpType interp,
                         gboolean scale_up);
VALA_EXTERN GType dimensions_get_type (void) G_GNUC_CONST ;
VALA_EXTERN Dimensions* dimensions_dup (const Dimensions* self);
VALA_EXTERN void dimensions_free (Dimensions* self);
VALA_EXTERN void dimensions_for_pixbuf (GdkPixbuf* pixbuf,
                            Dimensions* result);
VALA_EXTERN void dimensions_get_scaled (Dimensions *self,
                            gint scale,
                            gboolean scale_up,
                            Dimensions* result);
VALA_EXTERN void dimensions_with_min (Dimensions *self,
                          gint min_width,
                          gint min_height,
                          Dimensions* result);
VALA_EXTERN GdkPixbuf* resize_pixbuf (GdkPixbuf* pixbuf,
                          Dimensions* resized,
                          GdkInterpType interp);
VALA_EXTERN void draw_rounded_corners_filled (cairo_t* ctx,
                                  Dimensions* dim,
                                  GdkPoint* origin,
                                  gdouble radius_proportion);
VALA_EXTERN void context_rounded_corners (cairo_t* cx,
                              Dimensions* dim,
                              GdkPoint* origin,
                              gdouble radius_proportion);
VALA_EXTERN gint dimensions_minor_axis (Dimensions *self);
VALA_EXTERN guchar shift_color_byte (gint b,
                         gint shift);
VALA_EXTERN void shift_colors (GdkPixbuf* pixbuf,
                   gint red,
                   gint green,
                   gint blue,
                   gint alpha);
VALA_EXTERN gboolean coord_in_rectangle (gint x,
                             gint y,
                             GdkRectangle* rect);
VALA_EXTERN gboolean rectangles_equal (GdkRectangle* a,
                           GdkRectangle* b);
VALA_EXTERN gchar* rectangle_to_string (GdkRectangle* rect);
VALA_EXTERN void clamp_rectangle (GdkRectangle* original,
                      Dimensions* max,
                      GdkRectangle* result);
VALA_EXTERN void scale_point (GdkPoint* p,
                  gdouble factor,
                  GdkPoint* result);
VALA_EXTERN void add_points (GdkPoint* p1,
                 GdkPoint* p2,
                 GdkPoint* result);
VALA_EXTERN void subtract_points (GdkPoint* p1,
                      GdkPoint* p2,
                      GdkPoint* result);
VALA_EXTERN GdkPixbuf* apply_alpha_channel (GdkPixbuf* source,
                                gboolean strip);
VALA_EXTERN void argb2rgba (GdkPixbuf* pixbuf);
VALA_EXTERN void compute_arb_rotated_size (gdouble src_width,
                               gdouble src_height,
                               gdouble angle,
                               gdouble* dest_width,
                               gdouble* dest_height);
VALA_EXTERN gdouble degrees_to_radians (gdouble theta);
VALA_EXTERN GdkPixbuf* rotate_arb (GdkPixbuf* source_pixbuf,
                       gdouble angle);
VALA_EXTERN void rotate_point_arb (GdkPoint* source_point,
                       gint img_w,
                       gint img_h,
                       gdouble angle,
                       gboolean invert,
                       GdkPoint* result);
VALA_EXTERN void derotate_point_arb (GdkPoint* source_point,
                         gint img_w,
                         gint img_h,
                         gdouble angle,
                         GdkPoint* result);
VALA_EXTERN cairo_surface_t* get_background_surface (void);
VALA_EXTERN GType configuration_facade_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ConfigurationFacade, g_object_unref)
VALA_EXTERN GType config_facade_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ConfigFacade, g_object_unref)
VALA_EXTERN ConfigFacade* config_facade_get_instance (void);
VALA_EXTERN gchar* configuration_facade_get_transparent_background_type (ConfigurationFacade* self);
VALA_EXTERN gchar* configuration_facade_get_transparent_background_color (ConfigurationFacade* self);
VALA_EXTERN void invalidate_transparent_background (void);
VALA_EXTERN void paint_pixmap_with_background (cairo_t* ctx,
                                   GdkPixbuf* pixbuf,
                                   gint x,
                                   gint y);
VALA_EXTERN GType box_get_type (void) G_GNUC_CONST ;
VALA_EXTERN Box* box_dup (const Box* self);
VALA_EXTERN void box_free (Box* self);
VALA_EXTERN void clamp_inside_rotated_image (Box* src,
                                 gint img_w,
                                 gint img_h,
                                 gdouble angle_deg,
                                 gboolean preserve_geom,
                                 Box* result);
VALA_EXTERN void box_get_offset (Box *self,
                     gint xofs,
                     gint yofs,
                     Box* result);
VALA_EXTERN void box_init (Box *self,
               gint left,
               gint top,
               gint right,
               gint bottom);

void
parse_color (const gchar* spec,
             GdkRGBA* result)
{
	GdkRGBA _tmp0_ = {0};
	g_return_if_fail (spec != NULL);
	fetch_color (spec, &_tmp0_);
	*result = _tmp0_;
	return;
}

void
fetch_color (const gchar* spec,
             GdkRGBA* result)
{
	GdkRGBA rgba = {0};
	g_return_if_fail (spec != NULL);
	memset (&rgba, 0, sizeof (GdkRGBA));
	if (!gdk_rgba_parse (&rgba, spec)) {
		g_error ("image.vala:14: Can't parse color %s", spec);
	}
	*result = rgba;
	return;
}

void
set_source_color_from_string (cairo_t* ctx,
                              const gchar* spec)
{
	GdkRGBA rgba = {0};
	GdkRGBA _tmp0_ = {0};
	GdkRGBA _tmp1_;
	GdkRGBA _tmp2_;
	GdkRGBA _tmp3_;
	GdkRGBA _tmp4_;
	g_return_if_fail (ctx != NULL);
	g_return_if_fail (spec != NULL);
	fetch_color (spec, &_tmp0_);
	rgba = _tmp0_;
	_tmp1_ = rgba;
	_tmp2_ = rgba;
	_tmp3_ = rgba;
	_tmp4_ = rgba;
	cairo_set_source_rgba (ctx, _tmp1_.red, _tmp2_.green, _tmp3_.blue, _tmp4_.alpha);
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

GdkPixbuf*
get_placeholder_pixbuf (void)
{
	GdkPixbuf* pixbuf = NULL;
	GError* _inner_error0_ = NULL;
	GdkPixbuf* result;
	pixbuf = NULL;
	{
		GtkIconTheme* icon_theme = NULL;
		GtkIconTheme* _tmp0_;
		GtkIconTheme* _tmp1_;
		GdkPixbuf* _tmp2_ = NULL;
		GdkPixbuf* _tmp3_;
		GdkPixbuf* _tmp4_;
		_tmp0_ = gtk_icon_theme_get_default ();
		_tmp1_ = _g_object_ref0 (_tmp0_);
		icon_theme = _tmp1_;
		_tmp3_ = gtk_icon_theme_load_icon (icon_theme, "image-missing", (gint) GTK_ICON_SIZE_DIALOG, 0, &_inner_error0_);
		_tmp2_ = _tmp3_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (icon_theme);
			goto __catch0_g_error;
		}
		_tmp4_ = _tmp2_;
		_tmp2_ = NULL;
		_g_object_unref0 (pixbuf);
		pixbuf = _tmp4_;
		_g_object_unref0 (_tmp2_);
		_g_object_unref0 (icon_theme);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* _error_ = NULL;
		GError* _tmp10_;
		const gchar* _tmp11_;
		_error_ = _inner_error0_;
		_inner_error0_ = NULL;
		{
			GdkPixbuf* _tmp5_ = NULL;
			GdkPixbuf* _tmp6_;
			GdkPixbuf* _tmp7_;
			_tmp6_ = gdk_pixbuf_new_from_resource ("/org/gnome/Shotwell/icons/image-missing.png", &_inner_error0_);
			_tmp5_ = _tmp6_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __catch1_g_error;
			}
			_tmp7_ = _tmp5_;
			_tmp5_ = NULL;
			_g_object_unref0 (pixbuf);
			pixbuf = _tmp7_;
			_g_object_unref0 (_tmp5_);
		}
		goto __finally1;
		__catch1_g_error:
		{
			GError* err = NULL;
			GError* _tmp8_;
			const gchar* _tmp9_;
			err = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp8_ = err;
			_tmp9_ = _tmp8_->message;
			g_warning ("image.vala:39: Could not load fall-back icon: %s", _tmp9_);
			_g_error_free0 (err);
		}
		__finally1:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_error_free0 (_error_);
			_g_object_unref0 (pixbuf);
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp10_ = _error_;
		_tmp11_ = _tmp10_->message;
		g_warning ("image.vala:41: Could not load icon from theme: %s", _tmp11_);
		_g_error_free0 (_error_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (pixbuf);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	result = pixbuf;
	return result;
}

GdkPixbuf*
scale_pixbuf (GdkPixbuf* pixbuf,
              gint scale,
              GdkInterpType interp,
              gboolean scale_up)
{
	Dimensions original = {0};
	Dimensions _tmp0_ = {0};
	Dimensions scaled = {0};
	Dimensions _tmp1_ = {0};
	gboolean _tmp2_ = FALSE;
	Dimensions _tmp3_;
	Dimensions _tmp4_;
	Dimensions _tmp8_ = {0};
	Dimensions _tmp9_;
	Dimensions _tmp10_;
	GdkPixbuf* _tmp11_;
	GdkPixbuf* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (pixbuf, gdk_pixbuf_get_type ()), NULL);
	dimensions_for_pixbuf (pixbuf, &_tmp0_);
	original = _tmp0_;
	dimensions_get_scaled (&original, scale, scale_up, &_tmp1_);
	scaled = _tmp1_;
	_tmp3_ = original;
	_tmp4_ = scaled;
	if (_tmp3_.width == _tmp4_.width) {
		Dimensions _tmp5_;
		Dimensions _tmp6_;
		_tmp5_ = original;
		_tmp6_ = scaled;
		_tmp2_ = _tmp5_.height == _tmp6_.height;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GdkPixbuf* _tmp7_;
		_tmp7_ = _g_object_ref0 (pixbuf);
		result = _tmp7_;
		return result;
	}
	dimensions_with_min (&scaled, MIN_SCALED_WIDTH, MIN_SCALED_HEIGHT, &_tmp8_);
	scaled = _tmp8_;
	_tmp9_ = scaled;
	_tmp10_ = scaled;
	_tmp11_ = gdk_pixbuf_scale_simple (pixbuf, _tmp9_.width, _tmp10_.height, interp);
	result = _tmp11_;
	return result;
}

GdkPixbuf*
resize_pixbuf (GdkPixbuf* pixbuf,
               Dimensions* resized,
               GdkInterpType interp)
{
	Dimensions original = {0};
	Dimensions _tmp0_ = {0};
	gboolean _tmp1_ = FALSE;
	Dimensions _tmp2_;
	Dimensions _tmp3_;
	Dimensions _tmp7_ = {0};
	Dimensions _tmp8_;
	Dimensions _tmp9_;
	GdkPixbuf* _tmp10_;
	GdkPixbuf* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (pixbuf, gdk_pixbuf_get_type ()), NULL);
	g_return_val_if_fail (resized != NULL, NULL);
	dimensions_for_pixbuf (pixbuf, &_tmp0_);
	original = _tmp0_;
	_tmp2_ = original;
	_tmp3_ = *resized;
	if (_tmp2_.width == _tmp3_.width) {
		Dimensions _tmp4_;
		Dimensions _tmp5_;
		_tmp4_ = original;
		_tmp5_ = *resized;
		_tmp1_ = _tmp4_.height == _tmp5_.height;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GdkPixbuf* _tmp6_;
		_tmp6_ = _g_object_ref0 (pixbuf);
		result = _tmp6_;
		return result;
	}
	dimensions_with_min (resized, MIN_SCALED_WIDTH, MIN_SCALED_HEIGHT, &_tmp7_);
	*resized = _tmp7_;
	_tmp8_ = *resized;
	_tmp9_ = *resized;
	_tmp10_ = gdk_pixbuf_scale_simple (pixbuf, _tmp8_.width, _tmp9_.height, interp);
	result = _tmp10_;
	return result;
}

void
draw_rounded_corners_filled (cairo_t* ctx,
                             Dimensions* dim,
                             GdkPoint* origin,
                             gdouble radius_proportion)
{
	Dimensions _tmp0_;
	GdkPoint _tmp1_;
	g_return_if_fail (ctx != NULL);
	g_return_if_fail (dim != NULL);
	g_return_if_fail (origin != NULL);
	_tmp0_ = *dim;
	_tmp1_ = *origin;
	context_rounded_corners (ctx, &_tmp0_, &_tmp1_, radius_proportion);
	cairo_paint (ctx);
}

void
context_rounded_corners (cairo_t* cx,
                         Dimensions* dim,
                         GdkPoint* origin,
                         gdouble radius_proportion)
{
	gdouble left = 0.0;
	GdkPoint _tmp0_;
	gdouble top = 0.0;
	GdkPoint _tmp1_;
	gdouble right = 0.0;
	GdkPoint _tmp2_;
	Dimensions _tmp3_;
	gdouble bottom = 0.0;
	GdkPoint _tmp4_;
	Dimensions _tmp5_;
	gdouble radius = 0.0;
	g_return_if_fail (cx != NULL);
	g_return_if_fail (dim != NULL);
	g_return_if_fail (origin != NULL);
	radius_proportion = CLAMP (radius_proportion, 2.0, 100.0);
	_tmp0_ = *origin;
	left = (gdouble) _tmp0_.x;
	_tmp1_ = *origin;
	top = (gdouble) _tmp1_.y;
	_tmp2_ = *origin;
	_tmp3_ = *dim;
	right = (gdouble) (_tmp2_.x + _tmp3_.width);
	_tmp4_ = *origin;
	_tmp5_ = *dim;
	bottom = (gdouble) (_tmp4_.y + _tmp5_.height);
	radius = ((gdouble) dimensions_minor_axis (dim)) / radius_proportion;
	cairo_move_to (cx, left, top);
	cairo_arc (cx, right - radius, top + radius, radius, -90 * DEGREE, 0 * DEGREE);
	cairo_arc (cx, right - radius, bottom - radius, radius, 0 * DEGREE, 90 * DEGREE);
	cairo_arc (cx, left + radius, bottom - radius, radius, 90 * DEGREE, 180 * DEGREE);
	cairo_arc (cx, left + radius, top + radius, radius, 180 * DEGREE, 270 * DEGREE);
	cairo_clip (cx);
}

inline guchar
shift_color_byte (gint b,
                  gint shift)
{
	guchar result;
	result = (guchar) CLAMP (b + shift, 0, 255);
	return result;
}

void
shift_colors (GdkPixbuf* pixbuf,
              gint red,
              gint green,
              gint blue,
              gint alpha)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gint width = 0;
	gint height = 0;
	gint rowstride = 0;
	gint channels = 0;
	guchar* pixels = NULL;
	guint8* _tmp4_;
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (pixbuf, gdk_pixbuf_get_type ()));
	if (red >= -255) {
		_tmp0_ = red <= 255;
	} else {
		_tmp0_ = FALSE;
	}
	_vala_assert (_tmp0_, "red >= -255 && red <= 255");
	if (green >= -255) {
		_tmp1_ = green <= 255;
	} else {
		_tmp1_ = FALSE;
	}
	_vala_assert (_tmp1_, "green >= -255 && green <= 255");
	if (blue >= -255) {
		_tmp2_ = blue <= 255;
	} else {
		_tmp2_ = FALSE;
	}
	_vala_assert (_tmp2_, "blue >= -255 && blue <= 255");
	if (alpha >= -255) {
		_tmp3_ = alpha <= 255;
	} else {
		_tmp3_ = FALSE;
	}
	_vala_assert (_tmp3_, "alpha >= -255 && alpha <= 255");
	width = gdk_pixbuf_get_width (pixbuf);
	height = gdk_pixbuf_get_height (pixbuf);
	rowstride = gdk_pixbuf_get_rowstride (pixbuf);
	channels = gdk_pixbuf_get_n_channels (pixbuf);
	_tmp4_ = gdk_pixbuf_get_pixels (pixbuf);
	pixels = _tmp4_;
	_vala_assert (channels >= 3, "channels >= 3");
	_vala_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB, "pixbuf.get_colorspace() == Gdk.Colorspace.RGB");
	_vala_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8, "pixbuf.get_bits_per_sample() == 8");
	{
		gint y = 0;
		y = 0;
		{
			gboolean _tmp5_ = FALSE;
			_tmp5_ = TRUE;
			while (TRUE) {
				gint y_offset = 0;
				if (!_tmp5_) {
					gint _tmp6_;
					_tmp6_ = y;
					y = _tmp6_ + 1;
				}
				_tmp5_ = FALSE;
				if (!(y < height)) {
					break;
				}
				y_offset = y * rowstride;
				{
					gint x = 0;
					x = 0;
					{
						gboolean _tmp7_ = FALSE;
						_tmp7_ = TRUE;
						while (TRUE) {
							gint offset = 0;
							gboolean _tmp18_ = FALSE;
							if (!_tmp7_) {
								gint _tmp8_;
								_tmp8_ = x;
								x = _tmp8_ + 1;
							}
							_tmp7_ = FALSE;
							if (!(x < width)) {
								break;
							}
							offset = y_offset + (x * channels);
							if (red != 0) {
								guchar* _tmp9_;
								guchar* _tmp10_;
								guchar _tmp11_;
								_tmp9_ = pixels;
								_tmp10_ = pixels;
								_tmp11_ = _tmp10_[offset];
								_tmp9_[offset] = shift_color_byte ((gint) _tmp11_, red);
							}
							if (green != 0) {
								guchar* _tmp12_;
								guchar* _tmp13_;
								guchar _tmp14_;
								_tmp12_ = pixels;
								_tmp13_ = pixels;
								_tmp14_ = _tmp13_[offset + 1];
								_tmp12_[offset + 1] = shift_color_byte ((gint) _tmp14_, green);
							}
							if (blue != 0) {
								guchar* _tmp15_;
								guchar* _tmp16_;
								guchar _tmp17_;
								_tmp15_ = pixels;
								_tmp16_ = pixels;
								_tmp17_ = _tmp16_[offset + 2];
								_tmp15_[offset + 2] = shift_color_byte ((gint) _tmp17_, blue);
							}
							if (alpha != 0) {
								_tmp18_ = channels >= 4;
							} else {
								_tmp18_ = FALSE;
							}
							if (_tmp18_) {
								guchar* _tmp19_;
								guchar* _tmp20_;
								guchar _tmp21_;
								_tmp19_ = pixels;
								_tmp20_ = pixels;
								_tmp21_ = _tmp20_[offset + 3];
								_tmp19_[offset + 3] = shift_color_byte ((gint) _tmp21_, alpha);
							}
						}
					}
				}
			}
		}
	}
}

gboolean
coord_in_rectangle (gint x,
                    gint y,
                    GdkRectangle* rect)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	GdkRectangle _tmp3_;
	gboolean result;
	g_return_val_if_fail (rect != NULL, FALSE);
	_tmp3_ = *rect;
	if (x >= _tmp3_.x) {
		GdkRectangle _tmp4_;
		GdkRectangle _tmp5_;
		_tmp4_ = *rect;
		_tmp5_ = *rect;
		_tmp2_ = x < (_tmp4_.x + _tmp5_.width);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GdkRectangle _tmp6_;
		_tmp6_ = *rect;
		_tmp1_ = y >= _tmp6_.y;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GdkRectangle _tmp7_;
		GdkRectangle _tmp8_;
		_tmp7_ = *rect;
		_tmp8_ = *rect;
		_tmp0_ = y <= (_tmp7_.y + _tmp8_.height);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

gboolean
rectangles_equal (GdkRectangle* a,
                  GdkRectangle* b)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	GdkRectangle _tmp3_;
	GdkRectangle _tmp4_;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	_tmp3_ = *a;
	_tmp4_ = *b;
	if (_tmp3_.x == _tmp4_.x) {
		GdkRectangle _tmp5_;
		GdkRectangle _tmp6_;
		_tmp5_ = *a;
		_tmp6_ = *b;
		_tmp2_ = _tmp5_.y == _tmp6_.y;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		GdkRectangle _tmp7_;
		GdkRectangle _tmp8_;
		_tmp7_ = *a;
		_tmp8_ = *b;
		_tmp1_ = _tmp7_.width == _tmp8_.width;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		GdkRectangle _tmp9_;
		GdkRectangle _tmp10_;
		_tmp9_ = *a;
		_tmp10_ = *b;
		_tmp0_ = _tmp9_.height == _tmp10_.height;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

gchar*
rectangle_to_string (GdkRectangle* rect)
{
	GdkRectangle _tmp0_;
	GdkRectangle _tmp1_;
	GdkRectangle _tmp2_;
	GdkRectangle _tmp3_;
	gchar* _tmp4_;
	gchar* result;
	g_return_val_if_fail (rect != NULL, NULL);
	_tmp0_ = *rect;
	_tmp1_ = *rect;
	_tmp2_ = *rect;
	_tmp3_ = *rect;
	_tmp4_ = g_strdup_printf ("%d,%d %dx%d", _tmp0_.x, _tmp1_.y, _tmp2_.width, _tmp3_.height);
	result = _tmp4_;
	return result;
}

void
clamp_rectangle (GdkRectangle* original,
                 Dimensions* max,
                 GdkRectangle* result)
{
	GdkRectangle rect = {0};
	GdkRectangle _tmp0_;
	Dimensions _tmp1_;
	GdkRectangle _tmp2_;
	Dimensions _tmp3_;
	GdkRectangle _tmp4_;
	Dimensions _tmp5_;
	GdkRectangle _tmp6_;
	Dimensions _tmp7_;
	g_return_if_fail (original != NULL);
	g_return_if_fail (max != NULL);
	memset (&rect, 0, sizeof (GdkRectangle));
	_tmp0_ = *original;
	_tmp1_ = *max;
	rect.x = CLAMP (_tmp0_.x, 0, _tmp1_.width);
	_tmp2_ = *original;
	_tmp3_ = *max;
	rect.y = CLAMP (_tmp2_.y, 0, _tmp3_.height);
	_tmp4_ = *original;
	_tmp5_ = *max;
	rect.width = CLAMP (_tmp4_.width, 0, _tmp5_.width);
	_tmp6_ = *original;
	_tmp7_ = *max;
	rect.height = CLAMP (_tmp6_.height, 0, _tmp7_.height);
	*result = rect;
	return;
}

void
scale_point (GdkPoint* p,
             gdouble factor,
             GdkPoint* result)
{
	GdkPoint _result_ = {0};
	GdkPoint _tmp0_ = {0};
	GdkPoint _tmp1_;
	GdkPoint _tmp2_;
	g_return_if_fail (p != NULL);
	_tmp0_.x = 0;
	_result_ = _tmp0_;
	_tmp1_ = *p;
	_result_.x = (gint) ((factor * _tmp1_.x) + 0.5);
	_tmp2_ = *p;
	_result_.y = (gint) ((factor * _tmp2_.y) + 0.5);
	*result = _result_;
	return;
}

void
add_points (GdkPoint* p1,
            GdkPoint* p2,
            GdkPoint* result)
{
	GdkPoint _result_ = {0};
	GdkPoint _tmp0_ = {0};
	GdkPoint _tmp1_;
	GdkPoint _tmp2_;
	GdkPoint _tmp3_;
	GdkPoint _tmp4_;
	g_return_if_fail (p1 != NULL);
	g_return_if_fail (p2 != NULL);
	_tmp0_.x = 0;
	_result_ = _tmp0_;
	_tmp1_ = *p1;
	_tmp2_ = *p2;
	_result_.x = _tmp1_.x + _tmp2_.x;
	_tmp3_ = *p1;
	_tmp4_ = *p2;
	_result_.y = _tmp3_.y + _tmp4_.y;
	*result = _result_;
	return;
}

void
subtract_points (GdkPoint* p1,
                 GdkPoint* p2,
                 GdkPoint* result)
{
	GdkPoint _result_ = {0};
	GdkPoint _tmp0_ = {0};
	GdkPoint _tmp1_;
	GdkPoint _tmp2_;
	GdkPoint _tmp3_;
	GdkPoint _tmp4_;
	g_return_if_fail (p1 != NULL);
	g_return_if_fail (p2 != NULL);
	_tmp0_.x = 0;
	_result_ = _tmp0_;
	_tmp1_ = *p1;
	_tmp2_ = *p2;
	_result_.x = _tmp1_.x - _tmp2_.x;
	_tmp3_ = *p1;
	_tmp4_ = *p2;
	_result_.y = _tmp3_.y - _tmp4_.y;
	*result = _result_;
	return;
}

GdkPixbuf*
apply_alpha_channel (GdkPixbuf* source,
                     gboolean strip)
{
	GdkPixbuf* dest = NULL;
	GdkColorspace _tmp0_;
	GdkColorspace _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	GdkPixbuf* _tmp8_;
	guchar* sp = NULL;
	void* _tmp9_;
	void* _tmp10_;
	guchar* dp = NULL;
	GdkPixbuf* _tmp11_;
	void* _tmp12_;
	void* _tmp13_;
	GdkPixbuf* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (source, gdk_pixbuf_get_type ()), NULL);
	_tmp0_ = gdk_pixbuf_get_colorspace (source);
	_tmp1_ = _tmp0_;
	_tmp2_ = gdk_pixbuf_get_bits_per_sample (source);
	_tmp3_ = _tmp2_;
	_tmp4_ = gdk_pixbuf_get_width (source);
	_tmp5_ = _tmp4_;
	_tmp6_ = gdk_pixbuf_get_height (source);
	_tmp7_ = _tmp6_;
	_tmp8_ = gdk_pixbuf_new (_tmp1_, FALSE, _tmp3_, _tmp5_, _tmp7_);
	dest = _tmp8_;
	_tmp9_ = gdk_pixbuf_get_pixels (source);
	_tmp10_ = _tmp9_;
	sp = _tmp10_;
	_tmp11_ = dest;
	_tmp12_ = gdk_pixbuf_get_pixels (_tmp11_);
	_tmp13_ = _tmp12_;
	dp = _tmp13_;
	{
		gint j = 0;
		j = 0;
		{
			gboolean _tmp14_ = FALSE;
			_tmp14_ = TRUE;
			while (TRUE) {
				gint _tmp16_;
				gint _tmp17_;
				guchar* s = NULL;
				guchar* _tmp18_;
				guchar* d = NULL;
				guchar* _tmp19_;
				guchar* end = NULL;
				guchar* _tmp20_;
				gint _tmp21_;
				gint _tmp22_;
				guchar* _tmp47_;
				gint _tmp48_;
				gint _tmp49_;
				guchar* _tmp50_;
				GdkPixbuf* _tmp51_;
				gint _tmp52_;
				gint _tmp53_;
				if (!_tmp14_) {
					gint _tmp15_;
					_tmp15_ = j;
					j = _tmp15_ + 1;
				}
				_tmp14_ = FALSE;
				_tmp16_ = gdk_pixbuf_get_height (source);
				_tmp17_ = _tmp16_;
				if (!(j < _tmp17_)) {
					break;
				}
				_tmp18_ = sp;
				s = _tmp18_;
				_tmp19_ = dp;
				d = _tmp19_;
				_tmp20_ = s;
				_tmp21_ = gdk_pixbuf_get_width (source);
				_tmp22_ = _tmp21_;
				end = _tmp20_ + (4 * _tmp22_);
				while (TRUE) {
					guchar* _tmp23_;
					guchar* _tmp24_;
					guchar* _tmp45_;
					guchar* _tmp46_;
					_tmp23_ = s;
					_tmp24_ = end;
					if (!(_tmp23_ < _tmp24_)) {
						break;
					}
					if (strip) {
						guchar* _tmp25_;
						guchar* _tmp26_;
						guchar _tmp27_;
						guchar* _tmp28_;
						guchar* _tmp29_;
						guchar _tmp30_;
						guchar* _tmp31_;
						guchar* _tmp32_;
						guchar _tmp33_;
						_tmp25_ = d;
						_tmp26_ = s;
						_tmp27_ = _tmp26_[0];
						_tmp25_[0] = _tmp27_;
						_tmp28_ = d;
						_tmp29_ = s;
						_tmp30_ = _tmp29_[1];
						_tmp28_[1] = _tmp30_;
						_tmp31_ = d;
						_tmp32_ = s;
						_tmp33_ = _tmp32_[2];
						_tmp31_[2] = _tmp33_;
					} else {
						gdouble alpha = 0.0;
						guchar* _tmp34_;
						guchar _tmp35_;
						guchar* _tmp36_;
						guchar* _tmp37_;
						guchar _tmp38_;
						guchar* _tmp39_;
						guchar* _tmp40_;
						guchar _tmp41_;
						guchar* _tmp42_;
						guchar* _tmp43_;
						guchar _tmp44_;
						_tmp34_ = s;
						_tmp35_ = _tmp34_[3];
						alpha = _tmp35_ / 255.0;
						_tmp36_ = d;
						_tmp37_ = s;
						_tmp38_ = _tmp37_[0];
						_tmp36_[0] = (guchar) round ((255.0 * (1.0 - alpha)) + (_tmp38_ * alpha));
						_tmp39_ = d;
						_tmp40_ = s;
						_tmp41_ = _tmp40_[1];
						_tmp39_[1] = (guchar) round ((255.0 * (1.0 - alpha)) + (_tmp41_ * alpha));
						_tmp42_ = d;
						_tmp43_ = s;
						_tmp44_ = _tmp43_[2];
						_tmp42_[2] = (guchar) round ((255.0 * (1.0 - alpha)) + (_tmp44_ * alpha));
					}
					_tmp45_ = s;
					s = _tmp45_ + 4;
					_tmp46_ = d;
					d = _tmp46_ + 3;
				}
				_tmp47_ = sp;
				_tmp48_ = gdk_pixbuf_get_rowstride (source);
				_tmp49_ = _tmp48_;
				sp = _tmp47_ + _tmp49_;
				_tmp50_ = dp;
				_tmp51_ = dest;
				_tmp52_ = gdk_pixbuf_get_rowstride (_tmp51_);
				_tmp53_ = _tmp52_;
				dp = _tmp50_ + _tmp53_;
			}
		}
	}
	result = dest;
	return result;
}

void
argb2rgba (GdkPixbuf* pixbuf)
{
	guchar* gdk_pixels = NULL;
	void* _tmp0_;
	void* _tmp1_;
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (pixbuf, gdk_pixbuf_get_type ()));
	_tmp0_ = gdk_pixbuf_get_pixels (pixbuf);
	_tmp1_ = _tmp0_;
	gdk_pixels = _tmp1_;
	{
		gint j = 0;
		j = 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				gint _tmp4_;
				gint _tmp5_;
				guchar* p = NULL;
				guchar* _tmp6_;
				guchar* end = NULL;
				guchar* _tmp7_;
				gint _tmp8_;
				gint _tmp9_;
				guchar* _tmp19_;
				gint _tmp20_;
				gint _tmp21_;
				if (!_tmp2_) {
					gint _tmp3_;
					j = j + 1;
					_tmp3_ = j;
				}
				_tmp2_ = FALSE;
				_tmp4_ = gdk_pixbuf_get_height (pixbuf);
				_tmp5_ = _tmp4_;
				if (!(j < _tmp5_)) {
					break;
				}
				_tmp6_ = gdk_pixels;
				p = _tmp6_;
				_tmp7_ = p;
				_tmp8_ = gdk_pixbuf_get_width (pixbuf);
				_tmp9_ = _tmp8_;
				end = _tmp7_ + (4 * _tmp9_);
				while (TRUE) {
					guchar* _tmp10_;
					guchar* _tmp11_;
					guchar tmp = '\0';
					guchar* _tmp12_;
					guchar _tmp13_;
					guchar* _tmp14_;
					guchar* _tmp15_;
					guchar _tmp16_;
					guchar* _tmp17_;
					guchar* _tmp18_;
					_tmp10_ = p;
					_tmp11_ = end;
					if (!(_tmp10_ < _tmp11_)) {
						break;
					}
					_tmp12_ = p;
					_tmp13_ = _tmp12_[0];
					tmp = _tmp13_;
					_tmp14_ = p;
					_tmp15_ = p;
					_tmp16_ = _tmp15_[2];
					_tmp14_[0] = _tmp16_;
					_tmp17_ = p;
					_tmp17_[2] = tmp;
					_tmp18_ = p;
					p = _tmp18_ + 4;
				}
				_tmp19_ = gdk_pixels;
				_tmp20_ = gdk_pixbuf_get_rowstride (pixbuf);
				_tmp21_ = _tmp20_;
				gdk_pixels = _tmp19_ + _tmp21_;
			}
		}
	}
}

/**
 * Finds the size of the smallest axially-aligned rectangle that could contain
 * a rectangle src_width by src_height, rotated by angle.
 *
 * @param src_width The width of the incoming rectangle.
 * @param src_height The height of the incoming rectangle.
 * @param angle The amount to rotate by, given in degrees.
 * @param dest_width The width of the computed rectangle.
 * @param dest_height The height of the computed rectangle.
 */
void
compute_arb_rotated_size (gdouble src_width,
                          gdouble src_height,
                          gdouble angle,
                          gdouble* dest_width,
                          gdouble* dest_height)
{
	gdouble _vala_dest_width = 0.0;
	gdouble _vala_dest_height = 0.0;
	angle = fabs (degrees_to_radians (angle));
	_vala_assert (angle <= G_PI_2, "angle <= Math.PI_2");
	_vala_dest_width = (src_width * cos (angle)) + (src_height * sin (angle));
	_vala_dest_height = (src_height * cos (angle)) + (src_width * sin (angle));
	if (dest_width) {
		*dest_width = _vala_dest_width;
	}
	if (dest_height) {
		*dest_height = _vala_dest_height;
	}
}

/**
 * @brief Rotates a pixbuf to an arbitrary angle, given in degrees, and returns the rotated pixbuf.
 *
 * @param source_pixbuf The source image that needs to be angled.
 * @param angle The angle the source image should be rotated by.
 */
GdkPixbuf*
rotate_arb (GdkPixbuf* source_pixbuf,
            gdouble angle)
{
	gdouble x_tmp = 0.0;
	gdouble y_tmp = 0.0;
	gint _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	gdouble _tmp5_ = 0.0;
	gdouble _tmp6_ = 0.0;
	GdkPixbuf* dest_pixbuf = NULL;
	GdkPixbuf* _tmp7_;
	cairo_format_t _tmp8_ = 0;
	gboolean _tmp9_;
	gboolean _tmp10_;
	cairo_surface_t* surface = NULL;
	GdkPixbuf* _tmp11_;
	void* _tmp12_;
	void* _tmp13_;
	GdkPixbuf* _tmp14_;
	gint _tmp15_;
	gint _tmp16_;
	GdkPixbuf* _tmp17_;
	gint _tmp18_;
	gint _tmp19_;
	GdkPixbuf* _tmp20_;
	gint _tmp21_;
	gint _tmp22_;
	cairo_surface_t* _tmp23_;
	cairo_t* context = NULL;
	cairo_surface_t* _tmp24_;
	cairo_t* _tmp25_;
	cairo_t* _tmp26_;
	cairo_t* _tmp27_;
	GdkPixbuf* _tmp28_;
	gint _tmp29_;
	gint _tmp30_;
	GdkPixbuf* _tmp31_;
	gint _tmp32_;
	gint _tmp33_;
	cairo_t* _tmp34_;
	cairo_t* _tmp35_;
	GdkPixbuf* _tmp36_;
	gint _tmp37_;
	gint _tmp38_;
	GdkPixbuf* _tmp39_;
	gint _tmp40_;
	gint _tmp41_;
	cairo_t* _tmp42_;
	cairo_t* _tmp43_;
	gint _tmp44_;
	gint _tmp45_;
	gint _tmp46_;
	gint _tmp47_;
	cairo_t* _tmp48_;
	cairo_t* _tmp49_;
	cairo_pattern_t* _tmp50_;
	cairo_t* _tmp51_;
	GdkPixbuf* _tmp52_;
	GdkPixbuf* _tmp53_;
	GdkPixbuf* _tmp54_;
	GdkPixbuf* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (source_pixbuf, gdk_pixbuf_get_type ()), NULL);
	if (angle == 0.0) {
		GdkPixbuf* _tmp0_;
		_tmp0_ = _g_object_ref0 (source_pixbuf);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = gdk_pixbuf_get_width (source_pixbuf);
	_tmp2_ = _tmp1_;
	_tmp3_ = gdk_pixbuf_get_height (source_pixbuf);
	_tmp4_ = _tmp3_;
	compute_arb_rotated_size ((gdouble) _tmp2_, (gdouble) _tmp4_, angle, &_tmp5_, &_tmp6_);
	x_tmp = _tmp5_;
	y_tmp = _tmp6_;
	_tmp7_ = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, (gint) round (x_tmp), (gint) round (y_tmp));
	dest_pixbuf = _tmp7_;
	_tmp9_ = gdk_pixbuf_get_has_alpha (source_pixbuf);
	_tmp10_ = _tmp9_;
	if (_tmp10_) {
		_tmp8_ = CAIRO_FORMAT_ARGB32;
	} else {
		_tmp8_ = CAIRO_FORMAT_RGB24;
	}
	_tmp11_ = dest_pixbuf;
	_tmp12_ = gdk_pixbuf_get_pixels (_tmp11_);
	_tmp13_ = _tmp12_;
	_tmp14_ = dest_pixbuf;
	_tmp15_ = gdk_pixbuf_get_width (_tmp14_);
	_tmp16_ = _tmp15_;
	_tmp17_ = dest_pixbuf;
	_tmp18_ = gdk_pixbuf_get_height (_tmp17_);
	_tmp19_ = _tmp18_;
	_tmp20_ = dest_pixbuf;
	_tmp21_ = gdk_pixbuf_get_rowstride (_tmp20_);
	_tmp22_ = _tmp21_;
	_tmp23_ = cairo_image_surface_create_for_data ((guchar*) _tmp13_, _tmp8_, _tmp16_, _tmp19_, _tmp22_);
	surface = _tmp23_;
	_tmp24_ = surface;
	_tmp25_ = cairo_create (_tmp24_);
	context = _tmp25_;
	_tmp26_ = context;
	cairo_set_source_rgb (_tmp26_, (gdouble) 0, (gdouble) 0, (gdouble) 0);
	_tmp27_ = context;
	_tmp28_ = dest_pixbuf;
	_tmp29_ = gdk_pixbuf_get_width (_tmp28_);
	_tmp30_ = _tmp29_;
	_tmp31_ = dest_pixbuf;
	_tmp32_ = gdk_pixbuf_get_height (_tmp31_);
	_tmp33_ = _tmp32_;
	cairo_rectangle (_tmp27_, (gdouble) 0, (gdouble) 0, (gdouble) _tmp30_, (gdouble) _tmp33_);
	_tmp34_ = context;
	cairo_fill (_tmp34_);
	_tmp35_ = context;
	_tmp36_ = dest_pixbuf;
	_tmp37_ = gdk_pixbuf_get_width (_tmp36_);
	_tmp38_ = _tmp37_;
	_tmp39_ = dest_pixbuf;
	_tmp40_ = gdk_pixbuf_get_height (_tmp39_);
	_tmp41_ = _tmp40_;
	cairo_translate (_tmp35_, (gdouble) (_tmp38_ / 2), (gdouble) (_tmp41_ / 2));
	_tmp42_ = context;
	cairo_rotate (_tmp42_, degrees_to_radians (angle));
	_tmp43_ = context;
	_tmp44_ = gdk_pixbuf_get_width (source_pixbuf);
	_tmp45_ = _tmp44_;
	_tmp46_ = gdk_pixbuf_get_height (source_pixbuf);
	_tmp47_ = _tmp46_;
	cairo_translate (_tmp43_, (gdouble) ((-_tmp45_) / 2), (gdouble) ((-_tmp47_) / 2));
	_tmp48_ = context;
	gdk_cairo_set_source_pixbuf (_tmp48_, source_pixbuf, (gdouble) 0, (gdouble) 0);
	_tmp49_ = context;
	_tmp50_ = cairo_get_source (_tmp49_);
	cairo_pattern_set_filter (_tmp50_, CAIRO_FILTER_BEST);
	_tmp51_ = context;
	cairo_paint (_tmp51_);
	_tmp52_ = dest_pixbuf;
	argb2rgba (_tmp52_);
	_tmp53_ = dest_pixbuf;
	_tmp54_ = apply_alpha_channel (_tmp53_, TRUE);
	result = _tmp54_;
	_cairo_destroy0 (context);
	_cairo_surface_destroy0 (surface);
	_g_object_unref0 (dest_pixbuf);
	return result;
}

/**
 * @brief Rotates a point around the upper left corner of an image to an arbitrary angle,
 * given in degrees, and returns the rotated point, translated such that it, along with its attendant
 * image, are in positive x, positive y.
 *
 * @note May be subject to slight inaccuracy as Gdk points' coordinates may only be in whole pixels,
 * so the fractional component is lost.
 *
 * @param source_point The point to be rotated and scaled.
 * @param img_w The width of the source image (unrotated).
 * @param img_h The height of the source image (unrotated).
 * @param angle The angle the source image is to be rotated by to straighten it.
 */
void
rotate_point_arb (GdkPoint* source_point,
                  gint img_w,
                  gint img_h,
                  gdouble angle,
                  gboolean invert,
                  GdkPoint* result)
{
	gdouble dest_width = 0.0;
	gdouble dest_height = 0.0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	cairo_matrix_t matrix = {0};
	gdouble dest_x = 0.0;
	GdkPoint _tmp3_;
	gdouble dest_y = 0.0;
	GdkPoint _tmp4_;
	GdkPoint _tmp5_ = {0};
	g_return_if_fail (source_point != NULL);
	if (angle == 0.0) {
		GdkPoint _tmp0_;
		_tmp0_ = *source_point;
		*result = _tmp0_;
		return;
	}
	compute_arb_rotated_size ((gdouble) img_w, (gdouble) img_h, angle, &_tmp1_, &_tmp2_);
	dest_width = _tmp1_;
	dest_height = _tmp2_;
	cairo_matrix_init_identity (&matrix);
	cairo_matrix_translate (&matrix, dest_width / 2, dest_height / 2);
	cairo_matrix_rotate (&matrix, degrees_to_radians (angle));
	cairo_matrix_translate (&matrix, (gdouble) ((-img_w) / 2), (gdouble) ((-img_h) / 2));
	if (invert) {
		_vala_assert (cairo_matrix_invert (&matrix) == CAIRO_STATUS_SUCCESS, "matrix.invert() == Cairo.Status.SUCCESS");
	}
	_tmp3_ = *source_point;
	dest_x = (gdouble) _tmp3_.x;
	_tmp4_ = *source_point;
	dest_y = (gdouble) _tmp4_.y;
	cairo_matrix_transform_point (&matrix, &dest_x, &dest_y);
	_tmp5_.x = (gint) dest_x;
	_tmp5_.y = (gint) dest_y;
	*result = _tmp5_;
	return;
}

/**
 * @brief <u>De</u>rotates a point around the upper left corner of an image from an arbitrary angle,
 * given in degrees, and returns the de-rotated point, taking into account any translation necessary
 * to make sure all of the rotated image stays in positive x, positive y.
 *
 * @note May be subject to slight inaccuracy as Gdk points' coordinates may only be in whole pixels,
 * so the fractional component is lost.
 *
 * @param source_point The point to be de-rotated.
 * @param img_w The width of the source image (unrotated).
 * @param img_h The height of the source image (unrotated).
 * @param angle The angle the source image is to be rotated by to straighten it.
 */
void
derotate_point_arb (GdkPoint* source_point,
                    gint img_w,
                    gint img_h,
                    gdouble angle,
                    GdkPoint* result)
{
	GdkPoint _tmp0_;
	GdkPoint _tmp1_ = {0};
	g_return_if_fail (source_point != NULL);
	_tmp0_ = *source_point;
	rotate_point_arb (&_tmp0_, img_w, img_h, angle, TRUE, &_tmp1_);
	*result = _tmp1_;
	return;
}

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

cairo_surface_t*
get_background_surface (void)
{
	cairo_surface_t* _tmp0_;
	cairo_surface_t* _tmp31_;
	cairo_surface_t* _tmp32_;
	cairo_surface_t* result;
	_tmp0_ = background_surface;
	if (_tmp0_ == NULL) {
		gchar* color_a = NULL;
		gchar* color_b = NULL;
		ConfigFacade* config = NULL;
		ConfigFacade* _tmp1_;
		gchar* type = NULL;
		ConfigFacade* _tmp2_;
		gchar* _tmp3_;
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		GQuark _tmp7_ = 0U;
		static GQuark _tmp6_label0 = 0;
		static GQuark _tmp6_label1 = 0;
		cairo_surface_t* _tmp17_;
		cairo_t* ctx = NULL;
		cairo_surface_t* _tmp18_;
		cairo_t* _tmp19_;
		cairo_t* _tmp20_;
		cairo_t* _tmp21_;
		const gchar* _tmp22_;
		cairo_t* _tmp23_;
		cairo_t* _tmp24_;
		cairo_t* _tmp25_;
		cairo_t* _tmp26_;
		const gchar* _tmp27_;
		cairo_t* _tmp28_;
		cairo_t* _tmp29_;
		cairo_t* _tmp30_;
		_tmp1_ = config_facade_get_instance ();
		config = _tmp1_;
		_tmp2_ = config;
		_tmp3_ = configuration_facade_get_transparent_background_type (G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, TYPE_CONFIGURATION_FACADE, ConfigurationFacade));
		type = _tmp3_;
		_tmp4_ = type;
		_tmp5_ = _tmp4_;
		_tmp7_ = (NULL == _tmp5_) ? 0 : g_quark_from_string (_tmp5_);
		if (_tmp7_ == ((0 != _tmp6_label0) ? _tmp6_label0 : (_tmp6_label0 = g_quark_from_static_string ("checkered")))) {
			switch (0) {
				default:
				{
					gchar* _tmp8_;
					gchar* _tmp9_;
					_tmp8_ = g_strdup ("#808080");
					_g_free0 (color_a);
					color_a = _tmp8_;
					_tmp9_ = g_strdup ("#ccc");
					_g_free0 (color_b);
					color_b = _tmp9_;
					break;
				}
			}
		} else if (_tmp7_ == ((0 != _tmp6_label1) ? _tmp6_label1 : (_tmp6_label1 = g_quark_from_static_string ("solid")))) {
			switch (0) {
				default:
				{
					ConfigFacade* _tmp10_;
					gchar* _tmp11_;
					const gchar* _tmp12_;
					gchar* _tmp13_;
					_tmp10_ = config;
					_tmp11_ = configuration_facade_get_transparent_background_color (G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, TYPE_CONFIGURATION_FACADE, ConfigurationFacade));
					_g_free0 (color_b);
					color_b = _tmp11_;
					_tmp12_ = color_b;
					_tmp13_ = g_strdup (_tmp12_);
					_g_free0 (color_a);
					color_a = _tmp13_;
					break;
				}
			}
		} else {
			switch (0) {
				default:
				{
					gchar* _tmp14_;
					const gchar* _tmp15_;
					gchar* _tmp16_;
					_tmp14_ = g_strdup ("#000");
					_g_free0 (color_b);
					color_b = _tmp14_;
					_tmp15_ = color_b;
					_tmp16_ = g_strdup (_tmp15_);
					_g_free0 (color_a);
					color_a = _tmp16_;
					break;
				}
			}
		}
		_tmp17_ = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 16, 16);
		_cairo_surface_destroy0 (background_surface);
		background_surface = _tmp17_;
		_tmp18_ = background_surface;
		_tmp19_ = cairo_create (_tmp18_);
		ctx = _tmp19_;
		_tmp20_ = ctx;
		cairo_set_operator (_tmp20_, CAIRO_OPERATOR_SOURCE);
		_tmp21_ = ctx;
		_tmp22_ = color_a;
		set_source_color_from_string (_tmp21_, _tmp22_);
		_tmp23_ = ctx;
		cairo_rectangle (_tmp23_, (gdouble) 0, (gdouble) 0, (gdouble) 8, (gdouble) 8);
		_tmp24_ = ctx;
		cairo_rectangle (_tmp24_, (gdouble) 8, (gdouble) 8, (gdouble) 8, (gdouble) 8);
		_tmp25_ = ctx;
		cairo_fill (_tmp25_);
		_tmp26_ = ctx;
		_tmp27_ = color_b;
		set_source_color_from_string (_tmp26_, _tmp27_);
		_tmp28_ = ctx;
		cairo_rectangle (_tmp28_, (gdouble) 0, (gdouble) 8, (gdouble) 8, (gdouble) 8);
		_tmp29_ = ctx;
		cairo_rectangle (_tmp29_, (gdouble) 8, (gdouble) 0, (gdouble) 8, (gdouble) 8);
		_tmp30_ = ctx;
		cairo_fill (_tmp30_);
		_cairo_destroy0 (ctx);
		_g_free0 (type);
		_g_object_unref0 (config);
		_g_free0 (color_b);
		_g_free0 (color_a);
	}
	_tmp31_ = background_surface;
	_tmp32_ = _cairo_surface_reference0 (_tmp31_);
	result = _tmp32_;
	return result;
}

void
invalidate_transparent_background (void)
{
	_cairo_surface_destroy0 (background_surface);
	background_surface = NULL;
}

void
paint_pixmap_with_background (cairo_t* ctx,
                              GdkPixbuf* pixbuf,
                              gint x,
                              gint y)
{
	gint _tmp7_;
	gint _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	g_return_if_fail (ctx != NULL);
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (pixbuf, gdk_pixbuf_get_type ()));
	if (gdk_pixbuf_get_has_alpha (pixbuf)) {
		cairo_surface_t* _tmp0_;
		cairo_surface_t* _tmp1_;
		cairo_pattern_t* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		gint _tmp6_;
		_tmp0_ = get_background_surface ();
		_tmp1_ = _tmp0_;
		cairo_set_source_surface (ctx, _tmp1_, (gdouble) 0, (gdouble) 0);
		_cairo_surface_destroy0 (_tmp1_);
		_tmp2_ = cairo_get_source (ctx);
		cairo_pattern_set_extend (_tmp2_, CAIRO_EXTEND_REPEAT);
		_tmp3_ = gdk_pixbuf_get_width (pixbuf);
		_tmp4_ = _tmp3_;
		_tmp5_ = gdk_pixbuf_get_height (pixbuf);
		_tmp6_ = _tmp5_;
		cairo_rectangle (ctx, (gdouble) x, (gdouble) y, (gdouble) _tmp4_, (gdouble) _tmp6_);
		cairo_fill (ctx);
	}
	gdk_cairo_set_source_pixbuf (ctx, pixbuf, (gdouble) x, (gdouble) y);
	_tmp7_ = gdk_pixbuf_get_width (pixbuf);
	_tmp8_ = _tmp7_;
	_tmp9_ = gdk_pixbuf_get_height (pixbuf);
	_tmp10_ = _tmp9_;
	cairo_rectangle (ctx, (gdouble) x, (gdouble) y, (gdouble) _tmp8_, (gdouble) _tmp10_);
	cairo_fill (ctx);
}

void
clamp_inside_rotated_image (Box* src,
                            gint img_w,
                            gint img_h,
                            gdouble angle_deg,
                            gboolean preserve_geom,
                            Box* result)
{
	GdkPoint top_left = {0};
	Box _tmp0_;
	Box _tmp1_;
	GdkPoint _tmp2_ = {0};
	GdkPoint _tmp3_ = {0};
	GdkPoint top_right = {0};
	Box _tmp4_;
	Box _tmp5_;
	GdkPoint _tmp6_ = {0};
	GdkPoint _tmp7_ = {0};
	GdkPoint bottom_left = {0};
	Box _tmp8_;
	Box _tmp9_;
	GdkPoint _tmp10_ = {0};
	GdkPoint _tmp11_ = {0};
	GdkPoint bottom_right = {0};
	Box _tmp12_;
	Box _tmp13_;
	GdkPoint _tmp14_ = {0};
	GdkPoint _tmp15_ = {0};
	gdouble angle = 0.0;
	gint top_offset = 0;
	gint bottom_offset = 0;
	gint left_offset = 0;
	gint right_offset = 0;
	gint top = 0;
	GdkPoint _tmp16_;
	GdkPoint _tmp17_;
	gint bottom = 0;
	GdkPoint _tmp18_;
	GdkPoint _tmp19_;
	gint left = 0;
	GdkPoint _tmp20_;
	GdkPoint _tmp21_;
	gint right = 0;
	GdkPoint _tmp22_;
	GdkPoint _tmp23_;
	Box _tmp24_ = {0};
	g_return_if_fail (src != NULL);
	_tmp0_ = *src;
	_tmp1_ = *src;
	_tmp2_.x = _tmp0_.left;
	_tmp2_.y = _tmp1_.top;
	derotate_point_arb (&_tmp2_, img_w, img_h, angle_deg, &_tmp3_);
	top_left = _tmp3_;
	_tmp4_ = *src;
	_tmp5_ = *src;
	_tmp6_.x = _tmp4_.right;
	_tmp6_.y = _tmp5_.top;
	derotate_point_arb (&_tmp6_, img_w, img_h, angle_deg, &_tmp7_);
	top_right = _tmp7_;
	_tmp8_ = *src;
	_tmp9_ = *src;
	_tmp10_.x = _tmp8_.left;
	_tmp10_.y = _tmp9_.bottom;
	derotate_point_arb (&_tmp10_, img_w, img_h, angle_deg, &_tmp11_);
	bottom_left = _tmp11_;
	_tmp12_ = *src;
	_tmp13_ = *src;
	_tmp14_.x = _tmp12_.right;
	_tmp14_.y = _tmp13_.bottom;
	derotate_point_arb (&_tmp14_, img_w, img_h, angle_deg, &_tmp15_);
	bottom_right = _tmp15_;
	angle = degrees_to_radians (angle_deg);
	top_offset = 0;
	bottom_offset = 0;
	left_offset = 0;
	right_offset = 0;
	_tmp16_ = top_left;
	_tmp17_ = top_right;
	top = MIN (_tmp16_.y, _tmp17_.y);
	if (top < 0) {
		top_offset = (gint) ((0 - top) * cos (angle));
	}
	_tmp18_ = bottom_left;
	_tmp19_ = bottom_right;
	bottom = MAX (_tmp18_.y, _tmp19_.y);
	if (bottom > img_h) {
		bottom_offset = (gint) ((img_h - bottom) * cos (angle));
	}
	_tmp20_ = top_left;
	_tmp21_ = bottom_left;
	left = MIN (_tmp20_.x, _tmp21_.x);
	if (left < 0) {
		left_offset = (gint) ((0 - left) * cos (angle));
	}
	_tmp22_ = top_right;
	_tmp23_ = bottom_right;
	right = MAX (_tmp22_.x, _tmp23_.x);
	if (right > img_w) {
		right_offset = (gint) ((img_w - right) * cos (angle));
	}
	if (preserve_geom) {
		Box _tmp25_ = {0};
		box_get_offset (src, left_offset + right_offset, top_offset + bottom_offset, &_tmp25_);
		_tmp24_ = _tmp25_;
	} else {
		Box _tmp26_;
		Box _tmp27_;
		Box _tmp28_;
		Box _tmp29_;
		_tmp26_ = *src;
		_tmp27_ = *src;
		_tmp28_ = *src;
		_tmp29_ = *src;
		box_init (&_tmp24_, _tmp26_.left + left_offset, _tmp27_.top + top_offset, _tmp28_.right + right_offset, _tmp29_.bottom + bottom_offset);
	}
	*result = _tmp24_;
	return;
}

gdouble
degrees_to_radians (gdouble theta)
{
	gdouble result;
	result = theta * (G_PI / 180.0);
	return result;
}

