/* cairo-blur.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from cairo-blur.vala, do not modify */

/* This file is part of GNOME Games. License: GPL-3.0+.*/

#include "gnome-games.h"
#include <cairo-gobject.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <string.h>

#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

#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))

VALA_EXTERN void games_cairo_blur_exp_blur (guchar* pixels,
                                gint pixels_length1,
                                gint width,
                                gint height,
                                gint rowstride,
                                gint channels,
                                gfloat radius,
                                gint aprec,
                                gint zprec);
VALA_EXTERN void games_cairo_blur_blur_row (guchar* pixels,
                                gint pixels_length1,
                                gint width,
                                gint height,
                                gint rowstride,
                                gint channels,
                                gint line,
                                gint alpha,
                                gint aprec,
                                gint zprec);
VALA_EXTERN void games_cairo_blur_blur_col (guchar* pixels,
                                gint pixels_length1,
                                gint width,
                                gint height,
                                gint rowstride,
                                gint channels,
                                gint x,
                                gint alpha,
                                gint aprec,
                                gint zprec);
VALA_EXTERN void games_cairo_blur_blur_inner (guchar* pixel,
                                  gint pixel_length1,
                                  gint offset,
                                  gint* zR,
                                  gint* zG,
                                  gint* zB,
                                  gint* zA,
                                  gint alpha,
                                  gint aprec,
                                  gint zprec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

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

void
games_cairo_blur_blur_surface (cairo_surface_t* surface,
                               gfloat radius)
{
	cairo_surface_t* image_surface = NULL;
	cairo_surface_t* _tmp0_;
	cairo_format_t format = 0;
	cairo_surface_t* _tmp1_;
	gboolean _tmp2_ = FALSE;
	guchar* data = NULL;
	cairo_surface_t* _tmp3_;
	guchar* _tmp4_;
	gint data_length1;
	gint _data_size_;
	gint width = 0;
	cairo_surface_t* _tmp5_;
	gint height = 0;
	cairo_surface_t* _tmp6_;
	gint stride = 0;
	cairo_surface_t* _tmp7_;
	guchar* _tmp8_;
	gint _tmp8__length1;
	g_return_if_fail (surface != NULL);
	if (surface == NULL) {
		return;
	}
	if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE) {
		return;
	}
	_tmp0_ = _cairo_surface_reference0 ((cairo_surface_t*) surface);
	image_surface = _tmp0_;
	_tmp1_ = image_surface;
	format = cairo_image_surface_get_format (_tmp1_);
	if (format != CAIRO_FORMAT_RGB24) {
		_tmp2_ = format != CAIRO_FORMAT_ARGB32;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		_cairo_surface_destroy0 (image_surface);
		return;
	}
	if (radius == ((gfloat) 0)) {
		_cairo_surface_destroy0 (image_surface);
		return;
	}
	cairo_surface_flush (surface);
	_tmp3_ = image_surface;
	_tmp4_ = cairo_image_surface_get_data (_tmp3_);
	data = _tmp4_;
	data_length1 = -1;
	_data_size_ = data_length1;
	_tmp5_ = image_surface;
	width = cairo_image_surface_get_width (_tmp5_);
	_tmp6_ = image_surface;
	height = cairo_image_surface_get_height (_tmp6_);
	_tmp7_ = image_surface;
	stride = cairo_image_surface_get_stride (_tmp7_);
	_tmp8_ = data;
	_tmp8__length1 = data_length1;
	games_cairo_blur_exp_blur (_tmp8_, (gint) _tmp8__length1, width, height, stride, 4, radius, 16, 7);
	cairo_surface_mark_dirty (surface);
	_cairo_surface_destroy0 (image_surface);
}

void
games_cairo_blur_exp_blur (guchar* pixels,
                           gint pixels_length1,
                           gint width,
                           gint height,
                           gint rowstride,
                           gint channels,
                           gfloat radius,
                           gint aprec,
                           gint zprec)
{
	gint alpha = 0;
	alpha = (gint) ((1 << aprec) * (1.0f - expf ((-2.3f) / (radius + 1.0f))));
	{
		gint row = 0;
		row = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = row;
					row = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(row < height)) {
					break;
				}
				games_cairo_blur_blur_row (pixels, (gint) pixels_length1, width, height, rowstride, channels, row, alpha, aprec, zprec);
			}
		}
	}
	{
		gint col = 0;
		col = 0;
		{
			gboolean _tmp2_ = FALSE;
			_tmp2_ = TRUE;
			while (TRUE) {
				if (!_tmp2_) {
					gint _tmp3_;
					_tmp3_ = col;
					col = _tmp3_ + 1;
				}
				_tmp2_ = FALSE;
				if (!(col < width)) {
					break;
				}
				games_cairo_blur_blur_col (pixels, (gint) pixels_length1, width, height, rowstride, channels, col, alpha, aprec, zprec);
			}
		}
	}
}

void
games_cairo_blur_blur_row (guchar* pixels,
                           gint pixels_length1,
                           gint width,
                           gint height,
                           gint rowstride,
                           gint channels,
                           gint line,
                           gint alpha,
                           gint aprec,
                           gint zprec)
{
	gint offset = 0;
	gint zR = 0;
	guchar _tmp0_;
	gint zG = 0;
	guchar _tmp1_;
	gint zB = 0;
	guchar _tmp2_;
	gint zA = 0;
	guchar _tmp3_;
	offset = line * rowstride;
	_tmp0_ = pixels[offset];
	zR = _tmp0_ << zprec;
	_tmp1_ = pixels[offset + 1];
	zG = _tmp1_ << zprec;
	_tmp2_ = pixels[offset + 2];
	zB = _tmp2_ << zprec;
	_tmp3_ = pixels[offset + 3];
	zA = _tmp3_ << zprec;
	{
		gint index = 0;
		index = 0;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				if (!_tmp4_) {
					gint _tmp5_;
					_tmp5_ = index;
					index = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (!(index < width)) {
					break;
				}
				games_cairo_blur_blur_inner (pixels, (gint) pixels_length1, offset + (index * channels), &zR, &zG, &zB, &zA, alpha, aprec, zprec);
			}
		}
	}
	{
		gint index = 0;
		index = width - 2;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = index;
					index = _tmp7_ - 1;
				}
				_tmp6_ = FALSE;
				if (!(index >= 0)) {
					break;
				}
				games_cairo_blur_blur_inner (pixels, (gint) pixels_length1, offset + (index * channels), &zR, &zG, &zB, &zA, alpha, aprec, zprec);
			}
		}
	}
}

void
games_cairo_blur_blur_col (guchar* pixels,
                           gint pixels_length1,
                           gint width,
                           gint height,
                           gint rowstride,
                           gint channels,
                           gint x,
                           gint alpha,
                           gint aprec,
                           gint zprec)
{
	gint offset = 0;
	gint zR = 0;
	guchar _tmp0_;
	gint zG = 0;
	guchar _tmp1_;
	gint zB = 0;
	guchar _tmp2_;
	gint zA = 0;
	guchar _tmp3_;
	offset = x * channels;
	_tmp0_ = pixels[offset];
	zR = _tmp0_ << zprec;
	_tmp1_ = pixels[offset + 1];
	zG = _tmp1_ << zprec;
	_tmp2_ = pixels[offset + 2];
	zB = _tmp2_ << zprec;
	_tmp3_ = pixels[offset + 3];
	zA = _tmp3_ << zprec;
	{
		gint index = 0;
		index = 0;
		{
			gboolean _tmp4_ = FALSE;
			_tmp4_ = TRUE;
			while (TRUE) {
				if (!_tmp4_) {
					gint _tmp5_;
					_tmp5_ = index;
					index = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (!(index < height)) {
					break;
				}
				games_cairo_blur_blur_inner (pixels, (gint) pixels_length1, offset + (index * rowstride), &zR, &zG, &zB, &zA, alpha, aprec, zprec);
			}
		}
	}
	{
		gint index = 0;
		index = height - 2;
		{
			gboolean _tmp6_ = FALSE;
			_tmp6_ = TRUE;
			while (TRUE) {
				if (!_tmp6_) {
					gint _tmp7_;
					_tmp7_ = index;
					index = _tmp7_ - 1;
				}
				_tmp6_ = FALSE;
				if (!(index >= 0)) {
					break;
				}
				games_cairo_blur_blur_inner (pixels, (gint) pixels_length1, offset + (index * rowstride), &zR, &zG, &zB, &zA, alpha, aprec, zprec);
			}
		}
	}
}

void
games_cairo_blur_blur_inner (guchar* pixel,
                             gint pixel_length1,
                             gint offset,
                             gint* zR,
                             gint* zG,
                             gint* zB,
                             gint* zA,
                             gint alpha,
                             gint aprec,
                             gint zprec)
{
	gint R = 0;
	guchar _tmp0_;
	gint G = 0;
	guchar _tmp1_;
	gint B = 0;
	guchar _tmp2_;
	gint A = 0;
	guchar _tmp3_;
	_tmp0_ = pixel[offset];
	R = (gint) _tmp0_;
	_tmp1_ = pixel[offset + 1];
	G = (gint) _tmp1_;
	_tmp2_ = pixel[offset + 2];
	B = (gint) _tmp2_;
	_tmp3_ = pixel[offset + 3];
	A = (gint) _tmp3_;
	*zR = (*zR) + ((alpha * ((R << zprec) - (*zR))) >> aprec);
	*zG = (*zG) + ((alpha * ((G << zprec) - (*zG))) >> aprec);
	*zB = (*zB) + ((alpha * ((B << zprec) - (*zB))) >> aprec);
	*zA = (*zA) + ((alpha * ((A << zprec) - (*zA))) >> aprec);
	pixel[offset] = (guchar) ((*zR) >> zprec);
	pixel[offset + 1] = (guchar) ((*zG) >> zprec);
	pixel[offset + 2] = (guchar) ((*zB) >> zprec);
	pixel[offset + 3] = (guchar) ((*zA) >> zprec);
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

