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

/*
* Copyright (c) 2009-2013 Yorba Foundation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program 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, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

#include "io.elementary.photos.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib-object.h>
#include <glib.h>
#include <gio/gio.h>
#include <gdk/gdk.h>
#include <cairo-gobject.h>
#include <string.h>

#define ZOOM_BUFFER_MEGAPIXEL 1048576
#define ZOOM_BUFFER_USE_REDUCED_THRESHOLD (((gint) 2.0) * ZOOM_BUFFER_MEGAPIXEL)
#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

typedef enum  {
	ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_LOADED,
	ZOOM_BUFFER_OBJECT_STATE_SOURCE_LOAD_IN_PROGRESS,
	ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_TRANSFORMED,
	ZOOM_BUFFER_OBJECT_STATE_TRANSFORMED_READY
} ZoomBufferObjectState;

#define ZOOM_BUFFER_TYPE_OBJECT_STATE (zoom_buffer_object_state_get_type ())

#define ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB (zoom_buffer_transformation_job_get_type ())
#define ZOOM_BUFFER_TRANSFORMATION_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, ZoomBufferTransformationJob))
#define ZOOM_BUFFER_TRANSFORMATION_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, ZoomBufferTransformationJobClass))
#define ZOOM_BUFFER_IS_TRANSFORMATION_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB))
#define ZOOM_BUFFER_IS_TRANSFORMATION_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB))
#define ZOOM_BUFFER_TRANSFORMATION_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, ZoomBufferTransformationJobClass))

typedef struct _ZoomBufferTransformationJob ZoomBufferTransformationJob;
typedef struct _ZoomBufferTransformationJobClass ZoomBufferTransformationJobClass;
enum  {
	ZOOM_BUFFER_0_PROPERTY,
	ZOOM_BUFFER_NUM_PROPERTIES
};
static GParamSpec* zoom_buffer_properties[ZOOM_BUFFER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _background_job_unref0(var) ((var == NULL) ? NULL : (var = (background_job_unref (var), NULL)))
#define _workers_unref0(var) ((var == NULL) ? NULL : (var = (workers_unref (var), NULL)))

#define ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB (zoom_buffer_iso_source_fetch_job_get_type ())
#define ZOOM_BUFFER_ISO_SOURCE_FETCH_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB, ZoomBufferIsoSourceFetchJob))
#define ZOOM_BUFFER_ISO_SOURCE_FETCH_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB, ZoomBufferIsoSourceFetchJobClass))
#define ZOOM_BUFFER_IS_ISO_SOURCE_FETCH_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB))
#define ZOOM_BUFFER_IS_ISO_SOURCE_FETCH_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB))
#define ZOOM_BUFFER_ISO_SOURCE_FETCH_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB, ZoomBufferIsoSourceFetchJobClass))

typedef struct _ZoomBufferIsoSourceFetchJob ZoomBufferIsoSourceFetchJob;
typedef struct _ZoomBufferIsoSourceFetchJobClass ZoomBufferIsoSourceFetchJobClass;
typedef struct _ZoomBufferIsoSourceFetchJobPrivate ZoomBufferIsoSourceFetchJobPrivate;
#define _pixel_transformer_unref0(var) ((var == NULL) ? NULL : (var = (pixel_transformer_unref (var), NULL)))
typedef struct _ZoomBufferTransformationJobPrivate ZoomBufferTransformationJobPrivate;
#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 _ZoomBufferPrivate {
	GdkPixbuf* iso_source_image;
	GdkPixbuf* reduced_source_image;
	GdkPixbuf* iso_transformed_image;
	GdkPixbuf* reduced_transformed_image;
	GdkPixbuf* preview_image;
	Photo* backing_photo;
	ZoomBufferObjectState object_state;
	GdkPixbuf* demand_transform_cached_pixbuf;
	ZoomState demand_transform_zoom_state;
	ZoomBufferTransformationJob* demand_transform_job;
	Workers* workers;
	SinglePhotoPage* parent_page;
	gboolean is_interactive_redraw_in_progress;
};

struct _ZoomBufferIsoSourceFetchJob {
	BackgroundJob parent_instance;
	ZoomBufferIsoSourceFetchJobPrivate * priv;
	GdkPixbuf* fetched;
};

struct _ZoomBufferIsoSourceFetchJobClass {
	BackgroundJobClass parent_class;
};

struct _ZoomBufferTransformationJob {
	BackgroundJob parent_instance;
	ZoomBufferTransformationJobPrivate * priv;
	GdkPixbuf* transformed;
};

struct _ZoomBufferTransformationJobClass {
	BackgroundJobClass parent_class;
};

struct _ZoomBufferIsoSourceFetchJobPrivate {
	Photo* to_fetch;
};

struct _ZoomBufferTransformationJobPrivate {
	GdkPixbuf* to_transform;
	PixelTransformer* transformer;
	GCancellable* cancellable;
};

static gint ZoomBuffer_private_offset;
static gpointer zoom_buffer_parent_class = NULL;
static gint ZoomBufferIsoSourceFetchJob_private_offset;
static gpointer zoom_buffer_iso_source_fetch_job_parent_class = NULL;
static gint ZoomBufferTransformationJob_private_offset;
static gpointer zoom_buffer_transformation_job_parent_class = NULL;

static GType zoom_buffer_object_state_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GType zoom_buffer_transformation_job_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static void zoom_buffer_on_iso_source_fetch_complete (ZoomBuffer* self,
                                               BackgroundJob* job);
static GType zoom_buffer_iso_source_fetch_job_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static void zoom_buffer_on_iso_transformation_complete (ZoomBuffer* self,
                                                 BackgroundJob* job);
static void _zoom_buffer_on_iso_transformation_complete_completion_callback (BackgroundJob* job,
                                                                      gpointer self);
static ZoomBufferTransformationJob* zoom_buffer_transformation_job_new (ZoomBuffer* owner,
                                                                 GdkPixbuf* to_transform,
                                                                 PixelTransformer* transformer,
                                                                 CompletionCallback completion_callback,
                                                                 gpointer completion_callback_target,
                                                                 GCancellable* cancellable);
static ZoomBufferTransformationJob* zoom_buffer_transformation_job_construct (GType object_type,
                                                                       ZoomBuffer* owner,
                                                                       GdkPixbuf* to_transform,
                                                                       PixelTransformer* transformer,
                                                                       CompletionCallback completion_callback,
                                                                       gpointer completion_callback_target,
                                                                       GCancellable* cancellable);
static void zoom_buffer_on_demand_transform_complete (ZoomBuffer* self,
                                               BackgroundJob* job);
static GdkPixbuf* zoom_buffer_get_view_projection_pixbuf (ZoomBuffer* self,
                                                   ZoomState* zoom_state,
                                                   GdkPixbuf* iso_pixbuf,
                                                   GdkPixbuf* reduced_pixbuf);
static GdkPixbuf* zoom_buffer_get_zoomed_image_source_not_transformed (ZoomBuffer* self,
                                                                ZoomState* zoom_state);
static void _zoom_buffer_on_demand_transform_complete_completion_callback (BackgroundJob* job,
                                                                    gpointer self);
static void _zoom_buffer_on_iso_source_fetch_complete_completion_callback (BackgroundJob* job,
                                                                    gpointer self);
static ZoomBufferIsoSourceFetchJob* zoom_buffer_iso_source_fetch_job_new (ZoomBuffer* owner,
                                                                   Photo* to_fetch,
                                                                   CompletionCallback completion_callback,
                                                                   gpointer completion_callback_target);
static ZoomBufferIsoSourceFetchJob* zoom_buffer_iso_source_fetch_job_construct (GType object_type,
                                                                         ZoomBuffer* owner,
                                                                         Photo* to_fetch,
                                                                         CompletionCallback completion_callback,
                                                                         gpointer completion_callback_target);
static void zoom_buffer_iso_source_fetch_job_real_execute (BackgroundJob* base);
static void zoom_buffer_iso_source_fetch_job_finalize (BackgroundJob * obj);
static GType zoom_buffer_iso_source_fetch_job_get_type_once (void);
static void zoom_buffer_transformation_job_real_execute (BackgroundJob* base);
static void zoom_buffer_transformation_job_finalize (BackgroundJob * obj);
static GType zoom_buffer_transformation_job_get_type_once (void);
static void zoom_buffer_finalize (GObject * obj);
static GType zoom_buffer_get_type_once (void);

static inline gpointer
zoom_buffer_get_instance_private (ZoomBuffer* self)
{
	return G_STRUCT_MEMBER_P (self, ZoomBuffer_private_offset);
}

static GType
zoom_buffer_object_state_get_type_once (void)
{
	static const GEnumValue values[] = {{ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_LOADED, "ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_LOADED", "source-not-loaded"}, {ZOOM_BUFFER_OBJECT_STATE_SOURCE_LOAD_IN_PROGRESS, "ZOOM_BUFFER_OBJECT_STATE_SOURCE_LOAD_IN_PROGRESS", "source-load-in-progress"}, {ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_TRANSFORMED, "ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_TRANSFORMED", "source-not-transformed"}, {ZOOM_BUFFER_OBJECT_STATE_TRANSFORMED_READY, "ZOOM_BUFFER_OBJECT_STATE_TRANSFORMED_READY", "transformed-ready"}, {0, NULL, NULL}};
	GType zoom_buffer_object_state_type_id;
	zoom_buffer_object_state_type_id = g_enum_register_static ("ZoomBufferObjectState", values);
	return zoom_buffer_object_state_type_id;
}

static GType
zoom_buffer_object_state_get_type (void)
{
	static volatile gsize zoom_buffer_object_state_type_id__once = 0;
	if (g_once_init_enter (&zoom_buffer_object_state_type_id__once)) {
		GType zoom_buffer_object_state_type_id;
		zoom_buffer_object_state_type_id = zoom_buffer_object_state_get_type_once ();
		g_once_init_leave (&zoom_buffer_object_state_type_id__once, zoom_buffer_object_state_type_id);
	}
	return zoom_buffer_object_state_type_id__once;
}

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

ZoomBuffer*
zoom_buffer_construct (GType object_type,
                       SinglePhotoPage* parent_page,
                       Photo* backing_photo,
                       GdkPixbuf* preview_image)
{
	ZoomBuffer * self = NULL;
	SinglePhotoPage* _tmp0_;
	GdkPixbuf* _tmp1_;
	Photo* _tmp2_;
	Workers* _tmp3_;
	g_return_val_if_fail (parent_page != NULL, NULL);
	g_return_val_if_fail (backing_photo != NULL, NULL);
	g_return_val_if_fail (preview_image != NULL, NULL);
	self = (ZoomBuffer*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (parent_page);
	_g_object_unref0 (self->priv->parent_page);
	self->priv->parent_page = _tmp0_;
	_tmp1_ = _g_object_ref0 (preview_image);
	_g_object_unref0 (self->priv->preview_image);
	self->priv->preview_image = _tmp1_;
	_tmp2_ = _g_object_ref0 (backing_photo);
	_g_object_unref0 (self->priv->backing_photo);
	self->priv->backing_photo = _tmp2_;
	_tmp3_ = workers_new (2, FALSE);
	_workers_unref0 (self->priv->workers);
	self->priv->workers = _tmp3_;
	return self;
}

ZoomBuffer*
zoom_buffer_new (SinglePhotoPage* parent_page,
                 Photo* backing_photo,
                 GdkPixbuf* preview_image)
{
	return zoom_buffer_construct (TYPE_ZOOM_BUFFER, parent_page, backing_photo, preview_image);
}

static gpointer
_background_job_ref0 (gpointer self)
{
	return self ? background_job_ref (self) : NULL;
}

static void
_zoom_buffer_on_iso_transformation_complete_completion_callback (BackgroundJob* job,
                                                                 gpointer self)
{
	zoom_buffer_on_iso_transformation_complete ((ZoomBuffer*) self, job);
}

static void
zoom_buffer_on_iso_source_fetch_complete (ZoomBuffer* self,
                                          BackgroundJob* job)
{
	ZoomBufferIsoSourceFetchJob* fetch_job = NULL;
	ZoomBufferIsoSourceFetchJob* _tmp0_;
	ZoomBufferIsoSourceFetchJob* _tmp1_;
	GdkPixbuf* _tmp2_;
	ZoomBufferIsoSourceFetchJob* _tmp3_;
	GdkPixbuf* _tmp4_;
	GdkPixbuf* _tmp5_;
	GdkPixbuf* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	GdkPixbuf* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	BackgroundJob* transformation_job = NULL;
	GdkPixbuf* _tmp21_;
	Photo* _tmp22_;
	PixelTransformer* _tmp23_;
	PixelTransformer* _tmp24_;
	GCancellable* _tmp25_;
	GCancellable* _tmp26_;
	ZoomBufferTransformationJob* _tmp27_;
	BackgroundJob* _tmp28_;
	Workers* _tmp29_;
	BackgroundJob* _tmp30_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (job != NULL);
	_tmp0_ = _background_job_ref0 (G_TYPE_CHECK_INSTANCE_CAST (job, ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB, ZoomBufferIsoSourceFetchJob));
	fetch_job = _tmp0_;
	_tmp1_ = fetch_job;
	_tmp2_ = _tmp1_->fetched;
	if (_tmp2_ == NULL) {
		g_critical ("ZoomBuffer.vala:108: ZoomBuffer: iso_source_fetch_complete( ): fetch j" \
"ob has null image member");
		_background_job_unref0 (fetch_job);
		return;
	}
	_tmp3_ = fetch_job;
	_tmp4_ = _tmp3_->fetched;
	_tmp5_ = _g_object_ref0 (_tmp4_);
	_g_object_unref0 (self->priv->iso_source_image);
	self->priv->iso_source_image = _tmp5_;
	_tmp6_ = self->priv->iso_source_image;
	_tmp7_ = gdk_pixbuf_get_width (_tmp6_);
	_tmp8_ = _tmp7_;
	_tmp9_ = self->priv->iso_source_image;
	_tmp10_ = gdk_pixbuf_get_height (_tmp9_);
	_tmp11_ = _tmp10_;
	if ((_tmp8_ * _tmp11_) > ZOOM_BUFFER_USE_REDUCED_THRESHOLD) {
		GdkPixbuf* _tmp12_;
		GdkPixbuf* _tmp13_;
		gint _tmp14_;
		gint _tmp15_;
		GdkPixbuf* _tmp16_;
		gint _tmp17_;
		gint _tmp18_;
		GdkPixbuf* _tmp19_;
		_tmp12_ = self->priv->iso_source_image;
		_tmp13_ = self->priv->iso_source_image;
		_tmp14_ = gdk_pixbuf_get_width (_tmp13_);
		_tmp15_ = _tmp14_;
		_tmp16_ = self->priv->iso_source_image;
		_tmp17_ = gdk_pixbuf_get_height (_tmp16_);
		_tmp18_ = _tmp17_;
		_tmp19_ = gdk_pixbuf_scale_simple (_tmp12_, _tmp15_ / 2, _tmp18_ / 2, GDK_INTERP_BILINEAR);
		_g_object_unref0 (self->priv->reduced_source_image);
		self->priv->reduced_source_image = _tmp19_;
	}
	self->priv->object_state = ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_TRANSFORMED;
	if (!self->priv->is_interactive_redraw_in_progress) {
		SinglePhotoPage* _tmp20_;
		_tmp20_ = self->priv->parent_page;
		single_photo_page_repaint (_tmp20_, NULL);
	}
	_tmp21_ = self->priv->iso_source_image;
	_tmp22_ = self->priv->backing_photo;
	_tmp23_ = photo_get_pixel_transformer (_tmp22_);
	_tmp24_ = _tmp23_;
	_tmp25_ = g_cancellable_new ();
	_tmp26_ = _tmp25_;
	_tmp27_ = zoom_buffer_transformation_job_new (self, _tmp21_, _tmp24_, _zoom_buffer_on_iso_transformation_complete_completion_callback, self, _tmp26_);
	_tmp28_ = (BackgroundJob*) _tmp27_;
	_g_object_unref0 (_tmp26_);
	_pixel_transformer_unref0 (_tmp24_);
	transformation_job = _tmp28_;
	_tmp29_ = self->priv->workers;
	_tmp30_ = transformation_job;
	workers_enqueue (_tmp29_, _tmp30_);
	_background_job_unref0 (transformation_job);
	_background_job_unref0 (fetch_job);
}

static void
zoom_buffer_on_iso_transformation_complete (ZoomBuffer* self,
                                            BackgroundJob* job)
{
	ZoomBufferTransformationJob* transform_job = NULL;
	ZoomBufferTransformationJob* _tmp0_;
	ZoomBufferTransformationJob* _tmp1_;
	GdkPixbuf* _tmp2_;
	ZoomBufferTransformationJob* _tmp3_;
	GdkPixbuf* _tmp4_;
	GdkPixbuf* _tmp5_;
	GdkPixbuf* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	GdkPixbuf* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (job != NULL);
	_tmp0_ = _background_job_ref0 (G_TYPE_CHECK_INSTANCE_CAST (job, ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, ZoomBufferTransformationJob));
	transform_job = _tmp0_;
	_tmp1_ = transform_job;
	_tmp2_ = _tmp1_->transformed;
	if (_tmp2_ == NULL) {
		g_critical ("ZoomBuffer.vala:131: %s", "ZoomBuffer: on_iso_transformation_complete( ): completed job has null " "image");
		_background_job_unref0 (transform_job);
		return;
	}
	_tmp3_ = transform_job;
	_tmp4_ = _tmp3_->transformed;
	_tmp5_ = _g_object_ref0 (_tmp4_);
	_g_object_unref0 (self->priv->iso_transformed_image);
	self->priv->iso_transformed_image = _tmp5_;
	_tmp6_ = self->priv->iso_transformed_image;
	_tmp7_ = gdk_pixbuf_get_width (_tmp6_);
	_tmp8_ = _tmp7_;
	_tmp9_ = self->priv->iso_transformed_image;
	_tmp10_ = gdk_pixbuf_get_height (_tmp9_);
	_tmp11_ = _tmp10_;
	if ((_tmp8_ * _tmp11_) > ZOOM_BUFFER_USE_REDUCED_THRESHOLD) {
		GdkPixbuf* _tmp12_;
		GdkPixbuf* _tmp13_;
		gint _tmp14_;
		gint _tmp15_;
		GdkPixbuf* _tmp16_;
		gint _tmp17_;
		gint _tmp18_;
		GdkPixbuf* _tmp19_;
		_tmp12_ = self->priv->iso_transformed_image;
		_tmp13_ = self->priv->iso_transformed_image;
		_tmp14_ = gdk_pixbuf_get_width (_tmp13_);
		_tmp15_ = _tmp14_;
		_tmp16_ = self->priv->iso_transformed_image;
		_tmp17_ = gdk_pixbuf_get_height (_tmp16_);
		_tmp18_ = _tmp17_;
		_tmp19_ = gdk_pixbuf_scale_simple (_tmp12_, _tmp15_ / 2, _tmp18_ / 2, GDK_INTERP_BILINEAR);
		_g_object_unref0 (self->priv->reduced_transformed_image);
		self->priv->reduced_transformed_image = _tmp19_;
	}
	self->priv->object_state = ZOOM_BUFFER_OBJECT_STATE_TRANSFORMED_READY;
	_background_job_unref0 (transform_job);
}

static void
zoom_buffer_on_demand_transform_complete (ZoomBuffer* self,
                                          BackgroundJob* job)
{
	ZoomBufferTransformationJob* transform_job = NULL;
	ZoomBufferTransformationJob* _tmp0_;
	ZoomBufferTransformationJob* _tmp1_;
	GdkPixbuf* _tmp2_;
	ZoomBufferTransformationJob* _tmp3_;
	GdkPixbuf* _tmp4_;
	GdkPixbuf* _tmp5_;
	SinglePhotoPage* _tmp6_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (job != NULL);
	_tmp0_ = _background_job_ref0 (G_TYPE_CHECK_INSTANCE_CAST (job, ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, ZoomBufferTransformationJob));
	transform_job = _tmp0_;
	_tmp1_ = transform_job;
	_tmp2_ = _tmp1_->transformed;
	if (_tmp2_ == NULL) {
		g_critical ("ZoomBuffer.vala:148: %s", "ZoomBuffer: on_demand_transform_complete( ): completed job has null " "image");
		_background_job_unref0 (transform_job);
		return;
	}
	_tmp3_ = transform_job;
	_tmp4_ = _tmp3_->transformed;
	_tmp5_ = _g_object_ref0 (_tmp4_);
	_g_object_unref0 (self->priv->demand_transform_cached_pixbuf);
	self->priv->demand_transform_cached_pixbuf = _tmp5_;
	_background_job_unref0 (self->priv->demand_transform_job);
	self->priv->demand_transform_job = NULL;
	_tmp6_ = self->priv->parent_page;
	single_photo_page_repaint (_tmp6_, NULL);
	_background_job_unref0 (transform_job);
}

static GdkPixbuf*
zoom_buffer_get_view_projection_pixbuf (ZoomBuffer* self,
                                        ZoomState* zoom_state,
                                        GdkPixbuf* iso_pixbuf,
                                        GdkPixbuf* reduced_pixbuf)
{
	GdkRectangle view_rect = {0};
	GdkRectangle _tmp0_ = {0};
	GdkRectangle view_rect_proj = {0};
	GdkRectangle _tmp1_ = {0};
	GdkPixbuf* sample_source_pixbuf = NULL;
	GdkPixbuf* _tmp2_;
	gboolean _tmp3_ = FALSE;
	GdkRectangle _tmp5_;
	GdkRectangle _tmp6_;
	GdkRectangle _tmp7_;
	GdkRectangle _tmp8_;
	GdkPixbuf* proj_subpixbuf = NULL;
	GdkPixbuf* _tmp9_;
	GdkRectangle _tmp10_;
	GdkRectangle _tmp11_;
	GdkRectangle _tmp12_;
	GdkRectangle _tmp13_;
	GdkPixbuf* _tmp14_;
	GdkPixbuf* zoomed = NULL;
	GdkRectangle _tmp15_;
	GdkRectangle _tmp16_;
	GdkPixbuf* _tmp17_;
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (zoom_state != NULL, NULL);
	g_return_val_if_fail (iso_pixbuf != NULL, NULL);
	zoom_state_get_viewing_rectangle_wrt_content (zoom_state, &_tmp0_);
	view_rect = _tmp0_;
	zoom_state_get_viewing_rectangle_projection (zoom_state, iso_pixbuf, &_tmp1_);
	view_rect_proj = _tmp1_;
	_tmp2_ = _g_object_ref0 (iso_pixbuf);
	sample_source_pixbuf = _tmp2_;
	if (reduced_pixbuf != NULL) {
		_tmp3_ = zoom_state_get_zoom_factor (zoom_state) < 0.5;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		GdkPixbuf* _tmp4_;
		_tmp4_ = _g_object_ref0 (reduced_pixbuf);
		_g_object_unref0 (sample_source_pixbuf);
		sample_source_pixbuf = _tmp4_;
		view_rect_proj.x = view_rect_proj.x / 2;
		view_rect_proj.y = view_rect_proj.y / 2;
		view_rect_proj.width = view_rect_proj.width / 2;
		view_rect_proj.height = view_rect_proj.height / 2;
	}
	_tmp5_ = view_rect_proj;
	view_rect_proj.width = CLAMP (_tmp5_.width, 1, G_MAXINT);
	_tmp6_ = view_rect_proj;
	view_rect_proj.height = CLAMP (_tmp6_.height, 1, G_MAXINT);
	_tmp7_ = view_rect;
	view_rect.width = CLAMP (_tmp7_.width, 1, G_MAXINT);
	_tmp8_ = view_rect;
	view_rect.height = CLAMP (_tmp8_.height, 1, G_MAXINT);
	_tmp9_ = sample_source_pixbuf;
	_tmp10_ = view_rect_proj;
	_tmp11_ = view_rect_proj;
	_tmp12_ = view_rect_proj;
	_tmp13_ = view_rect_proj;
	_tmp14_ = gdk_pixbuf_new_subpixbuf (_tmp9_, _tmp10_.x, _tmp11_.y, _tmp12_.width, _tmp13_.height);
	proj_subpixbuf = _tmp14_;
	_tmp15_ = view_rect;
	_tmp16_ = view_rect;
	_tmp17_ = gdk_pixbuf_scale_simple (proj_subpixbuf, _tmp15_.width, _tmp16_.height, GDK_INTERP_BILINEAR);
	zoomed = _tmp17_;
	_vala_assert (zoomed != NULL, "zoomed != null");
	result = zoomed;
	_g_object_unref0 (proj_subpixbuf);
	_g_object_unref0 (sample_source_pixbuf);
	return result;
}

static void
_zoom_buffer_on_demand_transform_complete_completion_callback (BackgroundJob* job,
                                                               gpointer self)
{
	zoom_buffer_on_demand_transform_complete ((ZoomBuffer*) self, job);
}

static GdkPixbuf*
zoom_buffer_get_zoomed_image_source_not_transformed (ZoomBuffer* self,
                                                     ZoomState* zoom_state)
{
	GdkPixbuf* _tmp0_;
	ZoomBufferTransformationJob* _tmp46_;
	ZoomBufferTransformationJob* _tmp67_;
	ZoomState _tmp84_;
	GdkPixbuf* _tmp85_;
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (zoom_state != NULL, NULL);
	_tmp0_ = self->priv->demand_transform_cached_pixbuf;
	if (_tmp0_ != NULL) {
		ZoomState _tmp1_;
		_tmp1_ = self->priv->demand_transform_zoom_state;
		if (zoom_state_equals (zoom_state, &_tmp1_)) {
			GdkPixbuf* _tmp2_;
			GdkPixbuf* _tmp3_;
			_tmp2_ = self->priv->demand_transform_cached_pixbuf;
			_tmp3_ = _g_object_ref0 (_tmp2_);
			result = _tmp3_;
			return result;
		} else {
			if (zoom_state_get_zoom_factor (zoom_state) == zoom_state_get_zoom_factor (&self->priv->demand_transform_zoom_state)) {
				GdkRectangle curr_rect = {0};
				GdkRectangle _tmp4_ = {0};
				GdkRectangle pre_rect = {0};
				GdkRectangle _tmp5_ = {0};
				GdkRectangle transfer_src_rect = {0};
				GdkRectangle transfer_dest_rect = {0};
				GdkRectangle _tmp6_;
				GdkRectangle _tmp7_;
				GdkRectangle _tmp8_;
				GdkRectangle _tmp9_;
				GdkRectangle _tmp10_;
				GdkRectangle _tmp11_;
				gint transfer_src_right = 0;
				GdkRectangle _tmp12_;
				GdkRectangle _tmp13_;
				GdkRectangle _tmp14_;
				GdkRectangle _tmp15_;
				GdkRectangle _tmp16_;
				gint transfer_src_bottom = 0;
				GdkRectangle _tmp17_;
				GdkRectangle _tmp18_;
				GdkRectangle _tmp19_;
				GdkRectangle _tmp20_;
				GdkRectangle _tmp21_;
				GdkRectangle _tmp22_;
				GdkRectangle _tmp23_;
				GdkRectangle _tmp24_;
				GdkRectangle _tmp25_;
				GdkRectangle _tmp26_;
				GdkRectangle _tmp27_;
				gint transfer_dest_right = 0;
				GdkRectangle _tmp28_;
				GdkRectangle _tmp29_;
				GdkRectangle _tmp30_;
				GdkRectangle _tmp31_;
				gint transfer_dest_bottom = 0;
				GdkRectangle _tmp32_;
				GdkRectangle _tmp33_;
				GdkRectangle _tmp34_;
				GdkRectangle _tmp35_;
				GdkPixbuf* composited_result = NULL;
				ZoomState _tmp36_;
				GdkPixbuf* _tmp37_;
				GdkPixbuf* _tmp38_;
				GdkRectangle _tmp39_;
				GdkRectangle _tmp40_;
				GdkRectangle _tmp41_;
				GdkRectangle _tmp42_;
				GdkPixbuf* _tmp43_;
				GdkRectangle _tmp44_;
				GdkRectangle _tmp45_;
				zoom_state_get_viewing_rectangle_wrt_content (zoom_state, &_tmp4_);
				curr_rect = _tmp4_;
				zoom_state_get_viewing_rectangle_wrt_content (&self->priv->demand_transform_zoom_state, &_tmp5_);
				pre_rect = _tmp5_;
				memset (&transfer_src_rect, 0, sizeof (GdkRectangle));
				memset (&transfer_dest_rect, 0, sizeof (GdkRectangle));
				_tmp6_ = curr_rect;
				_tmp7_ = pre_rect;
				_tmp8_ = pre_rect;
				transfer_src_rect.x = CLAMP (_tmp6_.x - _tmp7_.x, 0, _tmp8_.width);
				_tmp9_ = curr_rect;
				_tmp10_ = pre_rect;
				_tmp11_ = pre_rect;
				transfer_src_rect.y = CLAMP (_tmp9_.y - _tmp10_.y, 0, _tmp11_.height);
				_tmp12_ = curr_rect;
				_tmp13_ = curr_rect;
				_tmp14_ = pre_rect;
				_tmp15_ = pre_rect;
				transfer_src_right = CLAMP ((_tmp12_.x + _tmp13_.width) - _tmp14_.width, 0, _tmp15_.width);
				_tmp16_ = transfer_src_rect;
				transfer_src_rect.width = transfer_src_right - _tmp16_.x;
				_tmp17_ = curr_rect;
				_tmp18_ = curr_rect;
				_tmp19_ = pre_rect;
				_tmp20_ = pre_rect;
				transfer_src_bottom = CLAMP ((_tmp17_.y + _tmp18_.height) - _tmp19_.width, 0, _tmp20_.height);
				_tmp21_ = transfer_src_rect;
				transfer_src_rect.height = transfer_src_bottom - _tmp21_.y;
				_tmp22_ = pre_rect;
				_tmp23_ = curr_rect;
				_tmp24_ = curr_rect;
				transfer_dest_rect.x = CLAMP (_tmp22_.x - _tmp23_.x, 0, _tmp24_.width);
				_tmp25_ = pre_rect;
				_tmp26_ = curr_rect;
				_tmp27_ = curr_rect;
				transfer_dest_rect.y = CLAMP (_tmp25_.y - _tmp26_.y, 0, _tmp27_.height);
				_tmp28_ = transfer_dest_rect;
				_tmp29_ = transfer_src_rect;
				_tmp30_ = curr_rect;
				transfer_dest_right = CLAMP (_tmp28_.x + _tmp29_.width, 0, _tmp30_.width);
				_tmp31_ = transfer_dest_rect;
				transfer_dest_rect.width = transfer_dest_right - _tmp31_.x;
				_tmp32_ = transfer_dest_rect;
				_tmp33_ = transfer_src_rect;
				_tmp34_ = curr_rect;
				transfer_dest_bottom = CLAMP (_tmp32_.y + _tmp33_.height, 0, _tmp34_.height);
				_tmp35_ = transfer_dest_rect;
				transfer_dest_rect.height = transfer_dest_bottom - _tmp35_.y;
				_tmp36_ = *zoom_state;
				_tmp37_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp36_);
				composited_result = _tmp37_;
				_tmp38_ = self->priv->demand_transform_cached_pixbuf;
				_tmp39_ = transfer_src_rect;
				_tmp40_ = transfer_src_rect;
				_tmp41_ = transfer_dest_rect;
				_tmp42_ = transfer_dest_rect;
				_tmp43_ = composited_result;
				_tmp44_ = transfer_dest_rect;
				_tmp45_ = transfer_dest_rect;
				gdk_pixbuf_copy_area (_tmp38_, _tmp39_.x, _tmp40_.y, _tmp41_.width, _tmp42_.height, _tmp43_, _tmp44_.x, _tmp45_.y);
				result = composited_result;
				return result;
			}
		}
	}
	_tmp46_ = self->priv->demand_transform_job;
	if (_tmp46_ != NULL) {
		ZoomState _tmp47_;
		_tmp47_ = self->priv->demand_transform_zoom_state;
		if (zoom_state_equals (zoom_state, &_tmp47_)) {
			ZoomState _tmp48_;
			GdkPixbuf* _tmp49_;
			_tmp48_ = *zoom_state;
			_tmp49_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp48_);
			result = _tmp49_;
			return result;
		} else {
			ZoomBufferTransformationJob* _tmp50_;
			GdkPixbuf* zoomed = NULL;
			ZoomState _tmp51_;
			GdkPixbuf* _tmp52_;
			GdkPixbuf* _tmp53_;
			GdkPixbuf* _tmp54_;
			GdkPixbuf* _tmp55_;
			Photo* _tmp56_;
			PixelTransformer* _tmp57_;
			PixelTransformer* _tmp58_;
			GCancellable* _tmp59_;
			GCancellable* _tmp60_;
			ZoomBufferTransformationJob* _tmp61_;
			ZoomState _tmp62_;
			Workers* _tmp63_;
			ZoomBufferTransformationJob* _tmp64_;
			ZoomState _tmp65_;
			GdkPixbuf* _tmp66_;
			_tmp50_ = self->priv->demand_transform_job;
			background_job_cancel ((BackgroundJob*) _tmp50_);
			_background_job_unref0 (self->priv->demand_transform_job);
			self->priv->demand_transform_job = NULL;
			_tmp51_ = *zoom_state;
			_tmp52_ = self->priv->iso_source_image;
			_tmp53_ = self->priv->reduced_source_image;
			_tmp54_ = zoom_buffer_get_view_projection_pixbuf (self, &_tmp51_, _tmp52_, _tmp53_);
			zoomed = _tmp54_;
			_tmp55_ = zoomed;
			_tmp56_ = self->priv->backing_photo;
			_tmp57_ = photo_get_pixel_transformer (_tmp56_);
			_tmp58_ = _tmp57_;
			_tmp59_ = g_cancellable_new ();
			_tmp60_ = _tmp59_;
			_tmp61_ = zoom_buffer_transformation_job_new (self, _tmp55_, _tmp58_, _zoom_buffer_on_demand_transform_complete_completion_callback, self, _tmp60_);
			_background_job_unref0 (self->priv->demand_transform_job);
			self->priv->demand_transform_job = _tmp61_;
			_g_object_unref0 (_tmp60_);
			_pixel_transformer_unref0 (_tmp58_);
			_tmp62_ = *zoom_state;
			self->priv->demand_transform_zoom_state = _tmp62_;
			_tmp63_ = self->priv->workers;
			_tmp64_ = self->priv->demand_transform_job;
			workers_enqueue (_tmp63_, (BackgroundJob*) _tmp64_);
			_tmp65_ = *zoom_state;
			_tmp66_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp65_);
			result = _tmp66_;
			_g_object_unref0 (zoomed);
			return result;
		}
	}
	_tmp67_ = self->priv->demand_transform_job;
	if (_tmp67_ == NULL) {
		GdkPixbuf* zoomed = NULL;
		ZoomState _tmp68_;
		GdkPixbuf* _tmp69_;
		GdkPixbuf* _tmp70_;
		GdkPixbuf* _tmp71_;
		GdkPixbuf* _tmp72_;
		Photo* _tmp73_;
		PixelTransformer* _tmp74_;
		PixelTransformer* _tmp75_;
		GCancellable* _tmp76_;
		GCancellable* _tmp77_;
		ZoomBufferTransformationJob* _tmp78_;
		ZoomState _tmp79_;
		Workers* _tmp80_;
		ZoomBufferTransformationJob* _tmp81_;
		ZoomState _tmp82_;
		GdkPixbuf* _tmp83_;
		_tmp68_ = *zoom_state;
		_tmp69_ = self->priv->iso_source_image;
		_tmp70_ = self->priv->reduced_source_image;
		_tmp71_ = zoom_buffer_get_view_projection_pixbuf (self, &_tmp68_, _tmp69_, _tmp70_);
		zoomed = _tmp71_;
		_tmp72_ = zoomed;
		_tmp73_ = self->priv->backing_photo;
		_tmp74_ = photo_get_pixel_transformer (_tmp73_);
		_tmp75_ = _tmp74_;
		_tmp76_ = g_cancellable_new ();
		_tmp77_ = _tmp76_;
		_tmp78_ = zoom_buffer_transformation_job_new (self, _tmp72_, _tmp75_, _zoom_buffer_on_demand_transform_complete_completion_callback, self, _tmp77_);
		_background_job_unref0 (self->priv->demand_transform_job);
		self->priv->demand_transform_job = _tmp78_;
		_g_object_unref0 (_tmp77_);
		_pixel_transformer_unref0 (_tmp75_);
		_tmp79_ = *zoom_state;
		self->priv->demand_transform_zoom_state = _tmp79_;
		_tmp80_ = self->priv->workers;
		_tmp81_ = self->priv->demand_transform_job;
		workers_enqueue (_tmp80_, (BackgroundJob*) _tmp81_);
		_tmp82_ = *zoom_state;
		_tmp83_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp82_);
		result = _tmp83_;
		_g_object_unref0 (zoomed);
		return result;
	}
	g_critical ("ZoomBuffer.vala:296: %s", "ZoomBuffer: get_zoomed_image( ): in SOURCE-NOT-TRANSFORMED but can't t" \
"ransform " "on-screen projection on-demand; using preview image");
	_tmp84_ = *zoom_state;
	_tmp85_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp84_);
	result = _tmp85_;
	return result;
}

static void
_zoom_buffer_on_iso_source_fetch_complete_completion_callback (BackgroundJob* job,
                                                               gpointer self)
{
	zoom_buffer_on_iso_source_fetch_complete ((ZoomBuffer*) self, job);
}

GdkPixbuf*
zoom_buffer_get_zoom_preview_image_internal (ZoomBuffer* self,
                                             ZoomState* zoom_state)
{
	GdkRectangle view_rect = {0};
	GdkRectangle _tmp4_ = {0};
	GdkRectangle view_rect_proj = {0};
	GdkPixbuf* _tmp5_;
	GdkRectangle _tmp6_ = {0};
	GdkRectangle _tmp7_;
	GdkRectangle _tmp8_;
	GdkPixbuf* proj_subpixbuf = NULL;
	GdkPixbuf* _tmp9_;
	GdkRectangle _tmp10_;
	GdkRectangle _tmp11_;
	GdkRectangle _tmp12_;
	GdkRectangle _tmp13_;
	GdkPixbuf* _tmp14_;
	GdkPixbuf* zoomed = NULL;
	GdkRectangle _tmp15_;
	GdkRectangle _tmp16_;
	GdkPixbuf* _tmp17_;
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (zoom_state != NULL, NULL);
	if (self->priv->object_state == ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_LOADED) {
		BackgroundJob* iso_source_fetch_job = NULL;
		Photo* _tmp0_;
		ZoomBufferIsoSourceFetchJob* _tmp1_;
		Workers* _tmp2_;
		BackgroundJob* _tmp3_;
		_tmp0_ = self->priv->backing_photo;
		_tmp1_ = zoom_buffer_iso_source_fetch_job_new (self, _tmp0_, _zoom_buffer_on_iso_source_fetch_complete_completion_callback, self);
		iso_source_fetch_job = (BackgroundJob*) _tmp1_;
		_tmp2_ = self->priv->workers;
		_tmp3_ = iso_source_fetch_job;
		workers_enqueue (_tmp2_, _tmp3_);
		self->priv->object_state = ZOOM_BUFFER_OBJECT_STATE_SOURCE_LOAD_IN_PROGRESS;
		_background_job_unref0 (iso_source_fetch_job);
	}
	zoom_state_get_viewing_rectangle_wrt_content (zoom_state, &_tmp4_);
	view_rect = _tmp4_;
	_tmp5_ = self->priv->preview_image;
	zoom_state_get_viewing_rectangle_projection (zoom_state, _tmp5_, &_tmp6_);
	view_rect_proj = _tmp6_;
	_tmp7_ = view_rect_proj;
	view_rect_proj.width = CLAMP (_tmp7_.width, 1, G_MAXINT);
	_tmp8_ = view_rect_proj;
	view_rect_proj.height = CLAMP (_tmp8_.height, 1, G_MAXINT);
	_tmp9_ = self->priv->preview_image;
	_tmp10_ = view_rect_proj;
	_tmp11_ = view_rect_proj;
	_tmp12_ = view_rect_proj;
	_tmp13_ = view_rect_proj;
	_tmp14_ = gdk_pixbuf_new_subpixbuf (_tmp9_, _tmp10_.x, _tmp11_.y, _tmp12_.width, _tmp13_.height);
	proj_subpixbuf = _tmp14_;
	_tmp15_ = view_rect;
	_tmp16_ = view_rect;
	_tmp17_ = gdk_pixbuf_scale_simple (proj_subpixbuf, _tmp15_.width, _tmp16_.height, GDK_INTERP_BILINEAR);
	zoomed = _tmp17_;
	result = zoomed;
	_g_object_unref0 (proj_subpixbuf);
	return result;
}

Photo*
zoom_buffer_get_backing_photo (ZoomBuffer* self)
{
	Photo* _tmp0_;
	Photo* _tmp1_;
	Photo* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->backing_photo;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	result = _tmp1_;
	return result;
}

void
zoom_buffer_update_preview_image (ZoomBuffer* self,
                                  GdkPixbuf* preview_image)
{
	GdkPixbuf* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (preview_image != NULL);
	_tmp0_ = _g_object_ref0 (preview_image);
	_g_object_unref0 (self->priv->preview_image);
	self->priv->preview_image = _tmp0_;
}

void
zoom_buffer_flush_demand_cache (ZoomBuffer* self,
                                ZoomState* initial_zoom_state)
{
	g_return_if_fail (self != NULL);
	_g_object_unref0 (self->priv->demand_transform_cached_pixbuf);
	self->priv->demand_transform_cached_pixbuf = NULL;
	if (initial_zoom_state != NULL) {
		ZoomState _tmp0_;
		GdkPixbuf* _tmp1_;
		GdkPixbuf* _tmp2_;
		_tmp0_ = *initial_zoom_state;
		_tmp1_ = zoom_buffer_get_zoomed_image (self, &_tmp0_);
		_tmp2_ = _tmp1_;
		_g_object_unref0 (_tmp2_);
	}
}

GdkPixbuf*
zoom_buffer_get_zoomed_image (ZoomBuffer* self,
                              ZoomState* zoom_state)
{
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (zoom_state != NULL, NULL);
	self->priv->is_interactive_redraw_in_progress = FALSE;
	if (zoom_state_get_interpolation_factor (zoom_state) == 0.0) {
		ZoomState _tmp0_;
		GdkPixbuf* _tmp1_;
		_tmp0_ = *zoom_state;
		_tmp1_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp0_);
		result = _tmp1_;
		return result;
	}
	switch (self->priv->object_state) {
		case ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_LOADED:
		case ZOOM_BUFFER_OBJECT_STATE_SOURCE_LOAD_IN_PROGRESS:
		{
			ZoomState _tmp2_;
			GdkPixbuf* _tmp3_;
			_tmp2_ = *zoom_state;
			_tmp3_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp2_);
			result = _tmp3_;
			return result;
		}
		case ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_TRANSFORMED:
		{
			ZoomState _tmp4_;
			GdkPixbuf* _tmp5_;
			_tmp4_ = *zoom_state;
			_tmp5_ = zoom_buffer_get_zoomed_image_source_not_transformed (self, &_tmp4_);
			result = _tmp5_;
			return result;
		}
		case ZOOM_BUFFER_OBJECT_STATE_TRANSFORMED_READY:
		{
			ZoomState _tmp6_;
			GdkPixbuf* _tmp7_;
			GdkPixbuf* _tmp8_;
			GdkPixbuf* _tmp9_;
			_tmp6_ = *zoom_state;
			_tmp7_ = self->priv->iso_transformed_image;
			_tmp8_ = self->priv->reduced_transformed_image;
			_tmp9_ = zoom_buffer_get_view_projection_pixbuf (self, &_tmp6_, _tmp7_, _tmp8_);
			result = _tmp9_;
			return result;
		}
		default:
		{
			ZoomState _tmp10_;
			GdkPixbuf* _tmp11_;
			g_critical ("ZoomBuffer.vala:365: ZoomBuffer: get_zoomed_image( ): object is an inc" \
"onsistent state");
			_tmp10_ = *zoom_state;
			_tmp11_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp10_);
			result = _tmp11_;
			return result;
		}
	}
}

GdkPixbuf*
zoom_buffer_get_zoom_preview_image (ZoomBuffer* self,
                                    ZoomState* zoom_state)
{
	ZoomState _tmp0_;
	GdkPixbuf* _tmp1_;
	GdkPixbuf* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (zoom_state != NULL, NULL);
	self->priv->is_interactive_redraw_in_progress = TRUE;
	_tmp0_ = *zoom_state;
	_tmp1_ = zoom_buffer_get_zoom_preview_image_internal (self, &_tmp0_);
	result = _tmp1_;
	return result;
}

static inline gpointer
zoom_buffer_iso_source_fetch_job_get_instance_private (ZoomBufferIsoSourceFetchJob* self)
{
	return G_STRUCT_MEMBER_P (self, ZoomBufferIsoSourceFetchJob_private_offset);
}

static ZoomBufferIsoSourceFetchJob*
zoom_buffer_iso_source_fetch_job_construct (GType object_type,
                                            ZoomBuffer* owner,
                                            Photo* to_fetch,
                                            CompletionCallback completion_callback,
                                            gpointer completion_callback_target)
{
	ZoomBufferIsoSourceFetchJob* self = NULL;
	Photo* _tmp0_;
	g_return_val_if_fail (owner != NULL, NULL);
	g_return_val_if_fail (to_fetch != NULL, NULL);
	self = (ZoomBufferIsoSourceFetchJob*) background_job_construct (object_type, (GObject*) owner, completion_callback, completion_callback_target, NULL, NULL, NULL, NULL);
	_tmp0_ = _g_object_ref0 (to_fetch);
	_g_object_unref0 (self->priv->to_fetch);
	self->priv->to_fetch = _tmp0_;
	return self;
}

static ZoomBufferIsoSourceFetchJob*
zoom_buffer_iso_source_fetch_job_new (ZoomBuffer* owner,
                                      Photo* to_fetch,
                                      CompletionCallback completion_callback,
                                      gpointer completion_callback_target)
{
	return zoom_buffer_iso_source_fetch_job_construct (ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB, owner, to_fetch, completion_callback, completion_callback_target);
}

static void
zoom_buffer_iso_source_fetch_job_real_execute (BackgroundJob* base)
{
	ZoomBufferIsoSourceFetchJob * self;
	GError* _inner_error0_ = NULL;
	self = (ZoomBufferIsoSourceFetchJob*) base;
	{
		GdkPixbuf* _tmp0_ = NULL;
		Photo* _tmp1_;
		Scaling _tmp2_ = {0};
		GdkPixbuf* _tmp3_;
		GdkPixbuf* _tmp4_;
		_tmp1_ = self->priv->to_fetch;
		scaling_for_original (&_tmp2_);
		_tmp3_ = photo_get_pixbuf_with_options (_tmp1_, &_tmp2_, PHOTO_EXCEPTION_ADJUST, BACKING_FETCH_MODE_BASELINE, &_inner_error0_);
		_tmp0_ = _tmp3_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp4_ = _tmp0_;
		_tmp0_ = NULL;
		_g_object_unref0 (self->fetched);
		self->fetched = _tmp4_;
		_g_object_unref0 (_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
		g_critical ("ZoomBuffer.vala:45: IsoSourceFetchJob: execute( ): can't get pixbuf fr" \
"om backing photo");
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		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;
	}
}

static void
zoom_buffer_iso_source_fetch_job_class_init (ZoomBufferIsoSourceFetchJobClass * klass,
                                             gpointer klass_data)
{
	zoom_buffer_iso_source_fetch_job_parent_class = g_type_class_peek_parent (klass);
	((BackgroundJobClass *) klass)->finalize = zoom_buffer_iso_source_fetch_job_finalize;
	g_type_class_adjust_private_offset (klass, &ZoomBufferIsoSourceFetchJob_private_offset);
	((BackgroundJobClass *) klass)->execute = (void (*) (BackgroundJob*)) zoom_buffer_iso_source_fetch_job_real_execute;
}

static void
zoom_buffer_iso_source_fetch_job_instance_init (ZoomBufferIsoSourceFetchJob * self,
                                                gpointer klass)
{
	self->priv = zoom_buffer_iso_source_fetch_job_get_instance_private (self);
	self->fetched = NULL;
}

static void
zoom_buffer_iso_source_fetch_job_finalize (BackgroundJob * obj)
{
	ZoomBufferIsoSourceFetchJob * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, ZOOM_BUFFER_TYPE_ISO_SOURCE_FETCH_JOB, ZoomBufferIsoSourceFetchJob);
	_g_object_unref0 (self->priv->to_fetch);
	_g_object_unref0 (self->fetched);
	BACKGROUND_JOB_CLASS (zoom_buffer_iso_source_fetch_job_parent_class)->finalize (obj);
}

static GType
zoom_buffer_iso_source_fetch_job_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ZoomBufferIsoSourceFetchJobClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) zoom_buffer_iso_source_fetch_job_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ZoomBufferIsoSourceFetchJob), 0, (GInstanceInitFunc) zoom_buffer_iso_source_fetch_job_instance_init, NULL };
	GType zoom_buffer_iso_source_fetch_job_type_id;
	zoom_buffer_iso_source_fetch_job_type_id = g_type_register_static (TYPE_BACKGROUND_JOB, "ZoomBufferIsoSourceFetchJob", &g_define_type_info, 0);
	ZoomBufferIsoSourceFetchJob_private_offset = g_type_add_instance_private (zoom_buffer_iso_source_fetch_job_type_id, sizeof (ZoomBufferIsoSourceFetchJobPrivate));
	return zoom_buffer_iso_source_fetch_job_type_id;
}

static GType
zoom_buffer_iso_source_fetch_job_get_type (void)
{
	static volatile gsize zoom_buffer_iso_source_fetch_job_type_id__once = 0;
	if (g_once_init_enter (&zoom_buffer_iso_source_fetch_job_type_id__once)) {
		GType zoom_buffer_iso_source_fetch_job_type_id;
		zoom_buffer_iso_source_fetch_job_type_id = zoom_buffer_iso_source_fetch_job_get_type_once ();
		g_once_init_leave (&zoom_buffer_iso_source_fetch_job_type_id__once, zoom_buffer_iso_source_fetch_job_type_id);
	}
	return zoom_buffer_iso_source_fetch_job_type_id__once;
}

static inline gpointer
zoom_buffer_transformation_job_get_instance_private (ZoomBufferTransformationJob* self)
{
	return G_STRUCT_MEMBER_P (self, ZoomBufferTransformationJob_private_offset);
}

static gpointer
_pixel_transformer_ref0 (gpointer self)
{
	return self ? pixel_transformer_ref (self) : NULL;
}

static ZoomBufferTransformationJob*
zoom_buffer_transformation_job_construct (GType object_type,
                                          ZoomBuffer* owner,
                                          GdkPixbuf* to_transform,
                                          PixelTransformer* transformer,
                                          CompletionCallback completion_callback,
                                          gpointer completion_callback_target,
                                          GCancellable* cancellable)
{
	ZoomBufferTransformationJob* self = NULL;
	GCancellable* _tmp0_;
	GdkPixbuf* _tmp1_;
	PixelTransformer* _tmp2_;
	GdkPixbuf* _tmp3_;
	g_return_val_if_fail (owner != NULL, NULL);
	g_return_val_if_fail (to_transform != NULL, NULL);
	g_return_val_if_fail (cancellable != NULL, NULL);
	self = (ZoomBufferTransformationJob*) background_job_construct (object_type, (GObject*) owner, completion_callback, completion_callback_target, cancellable, NULL, NULL, NULL);
	_tmp0_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (self->priv->cancellable);
	self->priv->cancellable = _tmp0_;
	_tmp1_ = _g_object_ref0 (to_transform);
	_g_object_unref0 (self->priv->to_transform);
	self->priv->to_transform = _tmp1_;
	_tmp2_ = _pixel_transformer_ref0 (transformer);
	_pixel_transformer_unref0 (self->priv->transformer);
	self->priv->transformer = _tmp2_;
	_tmp3_ = gdk_pixbuf_copy (to_transform);
	_g_object_unref0 (self->transformed);
	self->transformed = _tmp3_;
	return self;
}

static ZoomBufferTransformationJob*
zoom_buffer_transformation_job_new (ZoomBuffer* owner,
                                    GdkPixbuf* to_transform,
                                    PixelTransformer* transformer,
                                    CompletionCallback completion_callback,
                                    gpointer completion_callback_target,
                                    GCancellable* cancellable)
{
	return zoom_buffer_transformation_job_construct (ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, owner, to_transform, transformer, completion_callback, completion_callback_target, cancellable);
}

static void
zoom_buffer_transformation_job_real_execute (BackgroundJob* base)
{
	ZoomBufferTransformationJob * self;
	PixelTransformer* _tmp0_;
	self = (ZoomBufferTransformationJob*) base;
	_tmp0_ = self->priv->transformer;
	if (_tmp0_ != NULL) {
		PixelTransformer* _tmp1_;
		GdkPixbuf* _tmp2_;
		GdkPixbuf* _tmp3_;
		GCancellable* _tmp4_;
		_tmp1_ = self->priv->transformer;
		_tmp2_ = self->priv->to_transform;
		_tmp3_ = self->transformed;
		_tmp4_ = self->priv->cancellable;
		pixel_transformer_transform_to_other_pixbuf (_tmp1_, _tmp2_, _tmp3_, _tmp4_);
	}
}

static void
zoom_buffer_transformation_job_class_init (ZoomBufferTransformationJobClass * klass,
                                           gpointer klass_data)
{
	zoom_buffer_transformation_job_parent_class = g_type_class_peek_parent (klass);
	((BackgroundJobClass *) klass)->finalize = zoom_buffer_transformation_job_finalize;
	g_type_class_adjust_private_offset (klass, &ZoomBufferTransformationJob_private_offset);
	((BackgroundJobClass *) klass)->execute = (void (*) (BackgroundJob*)) zoom_buffer_transformation_job_real_execute;
}

static void
zoom_buffer_transformation_job_instance_init (ZoomBufferTransformationJob * self,
                                              gpointer klass)
{
	self->priv = zoom_buffer_transformation_job_get_instance_private (self);
	self->transformed = NULL;
}

static void
zoom_buffer_transformation_job_finalize (BackgroundJob * obj)
{
	ZoomBufferTransformationJob * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, ZOOM_BUFFER_TYPE_TRANSFORMATION_JOB, ZoomBufferTransformationJob);
	_g_object_unref0 (self->priv->to_transform);
	_pixel_transformer_unref0 (self->priv->transformer);
	_g_object_unref0 (self->priv->cancellable);
	_g_object_unref0 (self->transformed);
	BACKGROUND_JOB_CLASS (zoom_buffer_transformation_job_parent_class)->finalize (obj);
}

static GType
zoom_buffer_transformation_job_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ZoomBufferTransformationJobClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) zoom_buffer_transformation_job_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ZoomBufferTransformationJob), 0, (GInstanceInitFunc) zoom_buffer_transformation_job_instance_init, NULL };
	GType zoom_buffer_transformation_job_type_id;
	zoom_buffer_transformation_job_type_id = g_type_register_static (TYPE_BACKGROUND_JOB, "ZoomBufferTransformationJob", &g_define_type_info, 0);
	ZoomBufferTransformationJob_private_offset = g_type_add_instance_private (zoom_buffer_transformation_job_type_id, sizeof (ZoomBufferTransformationJobPrivate));
	return zoom_buffer_transformation_job_type_id;
}

static GType
zoom_buffer_transformation_job_get_type (void)
{
	static volatile gsize zoom_buffer_transformation_job_type_id__once = 0;
	if (g_once_init_enter (&zoom_buffer_transformation_job_type_id__once)) {
		GType zoom_buffer_transformation_job_type_id;
		zoom_buffer_transformation_job_type_id = zoom_buffer_transformation_job_get_type_once ();
		g_once_init_leave (&zoom_buffer_transformation_job_type_id__once, zoom_buffer_transformation_job_type_id);
	}
	return zoom_buffer_transformation_job_type_id__once;
}

static void
zoom_buffer_class_init (ZoomBufferClass * klass,
                        gpointer klass_data)
{
	zoom_buffer_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ZoomBuffer_private_offset);
	G_OBJECT_CLASS (klass)->finalize = zoom_buffer_finalize;
}

static void
zoom_buffer_instance_init (ZoomBuffer * self,
                           gpointer klass)
{
	self->priv = zoom_buffer_get_instance_private (self);
	self->priv->iso_source_image = NULL;
	self->priv->reduced_source_image = NULL;
	self->priv->iso_transformed_image = NULL;
	self->priv->reduced_transformed_image = NULL;
	self->priv->preview_image = NULL;
	self->priv->backing_photo = NULL;
	self->priv->object_state = ZOOM_BUFFER_OBJECT_STATE_SOURCE_NOT_LOADED;
	self->priv->demand_transform_cached_pixbuf = NULL;
	self->priv->demand_transform_job = NULL;
	self->priv->workers = NULL;
	self->priv->is_interactive_redraw_in_progress = FALSE;
}

static void
zoom_buffer_finalize (GObject * obj)
{
	ZoomBuffer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_ZOOM_BUFFER, ZoomBuffer);
	_g_object_unref0 (self->priv->iso_source_image);
	_g_object_unref0 (self->priv->reduced_source_image);
	_g_object_unref0 (self->priv->iso_transformed_image);
	_g_object_unref0 (self->priv->reduced_transformed_image);
	_g_object_unref0 (self->priv->preview_image);
	_g_object_unref0 (self->priv->backing_photo);
	_g_object_unref0 (self->priv->demand_transform_cached_pixbuf);
	_background_job_unref0 (self->priv->demand_transform_job);
	_workers_unref0 (self->priv->workers);
	_g_object_unref0 (self->priv->parent_page);
	G_OBJECT_CLASS (zoom_buffer_parent_class)->finalize (obj);
}

static GType
zoom_buffer_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (ZoomBufferClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) zoom_buffer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ZoomBuffer), 0, (GInstanceInitFunc) zoom_buffer_instance_init, NULL };
	GType zoom_buffer_type_id;
	zoom_buffer_type_id = g_type_register_static (G_TYPE_OBJECT, "ZoomBuffer", &g_define_type_info, 0);
	ZoomBuffer_private_offset = g_type_add_instance_private (zoom_buffer_type_id, sizeof (ZoomBufferPrivate));
	return zoom_buffer_type_id;
}

GType
zoom_buffer_get_type (void)
{
	static volatile gsize zoom_buffer_type_id__once = 0;
	if (g_once_init_enter (&zoom_buffer_type_id__once)) {
		GType zoom_buffer_type_id;
		zoom_buffer_type_id = zoom_buffer_get_type_once ();
		g_once_init_leave (&zoom_buffer_type_id__once, zoom_buffer_type_id);
	}
	return zoom_buffer_type_id__once;
}

