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

/*
 * Copyright (C) 2009-2011 Canonical Ltd.
 * Author: Robert Ancell <robert.ancell@canonical.com>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
 * license.
 */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixdata.h>
#include <float.h>
#include <math.h>
#include <gdk/gdk.h>
#include <cairo-ps.h>
#include <zlib.h>
#include <jpeglib.h>
#include <config.h>
#include <gobject/gvaluecollector.h>


#define TYPE_BOOK (book_get_type ())
#define BOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BOOK, Book))
#define BOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BOOK, BookClass))
#define IS_BOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BOOK))
#define IS_BOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BOOK))
#define BOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_BOOK, BookClass))

typedef struct _Book Book;
typedef struct _BookClass BookClass;
typedef struct _BookPrivate BookPrivate;

#define TYPE_PAGE (page_get_type ())
#define PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PAGE, Page))
#define PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PAGE, PageClass))
#define IS_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PAGE))
#define IS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PAGE))
#define PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PAGE, PageClass))

typedef struct _Page Page;
typedef struct _PageClass PageClass;
#define __g_list_free__page_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__page_unref0_ (var), NULL)))

#define TYPE_SCAN_DIRECTION (scan_direction_get_type ())
#define _page_unref0(var) ((var == NULL) ? NULL : (var = (page_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))

#define TYPE_PS_WRITER (ps_writer_get_type ())
#define PS_WRITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PS_WRITER, PsWriter))
#define PS_WRITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PS_WRITER, PsWriterClass))
#define IS_PS_WRITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PS_WRITER))
#define IS_PS_WRITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PS_WRITER))
#define PS_WRITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PS_WRITER, PsWriterClass))

typedef struct _PsWriter PsWriter;
typedef struct _PsWriterClass PsWriterClass;
typedef struct _PsWriterPrivate PsWriterPrivate;
#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))
#define _ps_writer_unref0(var) ((var == NULL) ? NULL : (var = (ps_writer_unref (var), NULL)))

#define TYPE_PDF_WRITER (pdf_writer_get_type ())
#define PDF_WRITER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PDF_WRITER, PDFWriter))
#define PDF_WRITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PDF_WRITER, PDFWriterClass))
#define IS_PDF_WRITER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PDF_WRITER))
#define IS_PDF_WRITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PDF_WRITER))
#define PDF_WRITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PDF_WRITER, PDFWriterClass))

typedef struct _PDFWriter PDFWriter;
typedef struct _PDFWriterClass PDFWriterClass;
typedef struct _PDFWriterPrivate PDFWriterPrivate;
#define _pdf_writer_unref0(var) ((var == NULL) ? NULL : (var = (pdf_writer_unref (var), NULL)))
typedef struct _ParamSpecBook ParamSpecBook;
#define _g_list_free0(var) ((var == NULL) ? NULL : (var = (g_list_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _ParamSpecPDFWriter ParamSpecPDFWriter;
typedef struct _ParamSpecPsWriter ParamSpecPsWriter;

struct _Book {
	GTypeInstance parent_instance;
	volatile int ref_count;
	BookPrivate * priv;
};

struct _BookClass {
	GTypeClass parent_class;
	void (*finalize) (Book *self);
};

struct _BookPrivate {
	GList* pages;
	gboolean needs_saving;
};

typedef enum  {
	SCAN_DIRECTION_TOP_TO_BOTTOM,
	SCAN_DIRECTION_LEFT_TO_RIGHT,
	SCAN_DIRECTION_BOTTOM_TO_TOP,
	SCAN_DIRECTION_RIGHT_TO_LEFT
} ScanDirection;

struct _PsWriter {
	GTypeInstance parent_instance;
	volatile int ref_count;
	PsWriterPrivate * priv;
	cairo_surface_t* surface;
	GFileOutputStream* stream;
};

struct _PsWriterClass {
	GTypeClass parent_class;
	void (*finalize) (PsWriter *self);
};

struct _PDFWriter {
	GTypeInstance parent_instance;
	volatile int ref_count;
	PDFWriterPrivate * priv;
	gsize offset;
	GList* object_offsets;
};

struct _PDFWriterClass {
	GTypeClass parent_class;
	void (*finalize) (PDFWriter *self);
};

struct _ParamSpecBook {
	GParamSpec parent_instance;
};

struct _PDFWriterPrivate {
	GFileOutputStream* stream;
};

struct _ParamSpecPDFWriter {
	GParamSpec parent_instance;
};

struct _ParamSpecPsWriter {
	GParamSpec parent_instance;
};


static gpointer book_parent_class = NULL;
static gpointer pdf_writer_parent_class = NULL;
static gpointer ps_writer_parent_class = NULL;

gpointer book_ref (gpointer instance);
void book_unref (gpointer instance);
GParamSpec* param_spec_book (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_book (GValue* value, gpointer v_object);
void value_take_book (GValue* value, gpointer v_object);
gpointer value_get_book (const GValue* value);
GType book_get_type (void) G_GNUC_CONST;
gpointer page_ref (gpointer instance);
void page_unref (gpointer instance);
GParamSpec* param_spec_page (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_page (GValue* value, gpointer v_object);
void value_take_page (GValue* value, gpointer v_object);
gpointer value_get_page (const GValue* value);
GType page_get_type (void) G_GNUC_CONST;
#define BOOK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_BOOK, BookPrivate))
enum  {
	BOOK_DUMMY_PROPERTY
};
static void _page_unref0_ (gpointer var);
static void _g_list_free__page_unref0_ (GList* self);
Book* book_new (void);
Book* book_construct (GType object_type);
void book_clear (Book* self);
static void book_page_changed_cb (Book* self, Page* page);
void book_set_needs_saving (Book* self, gboolean needs_saving);
GType scan_direction_get_type (void) G_GNUC_CONST;
Page* book_append_page (Book* self, gint width, gint height, gint dpi, ScanDirection scan_direction);
Page* page_new (gint width, gint height, gint dpi, ScanDirection scan_direction);
Page* page_construct (GType object_type, gint width, gint height, gint dpi, ScanDirection scan_direction);
static void _book_page_changed_cb_page_pixels_changed (Page* _sender, gpointer self);
static void _book_page_changed_cb_page_crop_changed (Page* _sender, gpointer self);
void book_move_page (Book* self, Page* page, guint location);
void book_delete_page (Book* self, Page* page);
guint book_get_n_pages (Book* self);
Page* book_get_page (Book* self, gint page_number);
guint book_get_page_index (Book* self, Page* page);
static GFile* book_make_indexed_file (Book* self, const gchar* uri, gint i);
static void book_save_multi_file (Book* self, const gchar* type, GFile* file, GError** error);
void page_save (Page* self, const gchar* type, GFile* file, GError** error);
static void book_save_ps_pdf_surface (Book* self, cairo_surface_t* surface, GdkPixbuf* image, gdouble dpi);
static void book_save_ps (Book* self, GFile* file, GError** error);
PsWriter* ps_writer_new (GFileOutputStream* stream);
PsWriter* ps_writer_construct (GType object_type, GFileOutputStream* stream);
gpointer ps_writer_ref (gpointer instance);
void ps_writer_unref (gpointer instance);
GParamSpec* param_spec_ps_writer (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_ps_writer (GValue* value, gpointer v_object);
void value_take_ps_writer (GValue* value, gpointer v_object);
gpointer value_get_ps_writer (const GValue* value);
GType ps_writer_get_type (void) G_GNUC_CONST;
GdkPixbuf* page_get_image (Page* self, gboolean apply_crop);
gint page_get_dpi (Page* self);
static guint8* book_compress_zlib (Book* self, guint8* data, int data_length1, int* result_length1);
static void book_jpeg_init_cb (struct jpeg_compress_struct* info);
static gboolean book_jpeg_empty_cb (struct jpeg_compress_struct* info);
static void book_jpeg_term_cb (struct jpeg_compress_struct* info);
static guint8* book_compress_jpeg (Book* self, GdkPixbuf* image, gsize* n_written, int* result_length1);
static void _book_jpeg_init_cb_jpeg_initdestinationfunc (struct jpeg_compress_struct* cinfo);
static gboolean _book_jpeg_empty_cb_jpeg_emptyoutputbufferfunc (struct jpeg_compress_struct* cinfo);
static void _book_jpeg_term_cb_jpeg_termdestinationfunc (struct jpeg_compress_struct* cinfo);
static void book_save_pdf (Book* self, GFile* file, GError** error);
PDFWriter* pdf_writer_new (GFileOutputStream* stream);
PDFWriter* pdf_writer_construct (GType object_type, GFileOutputStream* stream);
gpointer pdf_writer_ref (gpointer instance);
void pdf_writer_unref (gpointer instance);
GParamSpec* param_spec_pdf_writer (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_pdf_writer (GValue* value, gpointer v_object);
void value_take_pdf_writer (GValue* value, gpointer v_object);
gpointer value_get_pdf_writer (const GValue* value);
GType pdf_writer_get_type (void) G_GNUC_CONST;
void pdf_writer_write_string (PDFWriter* self, const gchar* text);
guint pdf_writer_start_object (PDFWriter* self);
gboolean page_is_color (Page* self);
gint page_get_depth (Page* self);
static guint8* _vala_array_dup1 (guint8* self, int length);
static guint8* _vala_array_dup2 (guint8* self, int length);
void pdf_writer_write (PDFWriter* self, guint8* data, int data_length1);
void book_save (Book* self, const gchar* type, GFile* file, GError** error);
gboolean book_get_needs_saving (Book* self);
static void g_cclosure_user_marshal_VOID__PAGE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void book_finalize (Book* obj);
#define PDF_WRITER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_PDF_WRITER, PDFWriterPrivate))
enum  {
	PDF_WRITER_DUMMY_PROPERTY
};
static void pdf_writer_finalize (PDFWriter* obj);
enum  {
	PS_WRITER_DUMMY_PROPERTY
};
static cairo_status_t ps_writer_write_cairo_data (PsWriter* self, guint8* data, int data_length1);
static cairo_status_t _ps_writer_write_cairo_data_cairo_write_func_t (gpointer self, guchar* data, int data_length1);
static void ps_writer_finalize (PsWriter* obj);


static void _page_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (page_unref (var), NULL));
}


static void _g_list_free__page_unref0_ (GList* self) {
	g_list_foreach (self, (GFunc) _page_unref0_, NULL);
	g_list_free (self);
}


Book* book_construct (GType object_type) {
	Book* self = NULL;
	self = (Book*) g_type_create_instance (object_type);
	return self;
}


Book* book_new (void) {
	return book_construct (TYPE_BOOK);
}


void book_clear (Book* self) {
	g_return_if_fail (self != NULL);
	__g_list_free__page_unref0_0 (self->priv->pages);
	self->priv->pages = NULL;
	g_signal_emit_by_name (self, "cleared");
}


static void book_page_changed_cb (Book* self, Page* page) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	book_set_needs_saving (self, TRUE);
}


static void _book_page_changed_cb_page_pixels_changed (Page* _sender, gpointer self) {
	book_page_changed_cb (self, _sender);
}


static void _book_page_changed_cb_page_crop_changed (Page* _sender, gpointer self) {
	book_page_changed_cb (self, _sender);
}


static gpointer _page_ref0 (gpointer self) {
	return self ? page_ref (self) : NULL;
}


Page* book_append_page (Book* self, gint width, gint height, gint dpi, ScanDirection scan_direction) {
	Page* result = NULL;
	Page* _tmp0_ = NULL;
	Page* page;
	Page* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = page_new (width, height, dpi, scan_direction);
	page = _tmp0_;
	g_signal_connect (page, "pixels-changed", (GCallback) _book_page_changed_cb_page_pixels_changed, self);
	g_signal_connect (page, "crop-changed", (GCallback) _book_page_changed_cb_page_crop_changed, self);
	_tmp1_ = _page_ref0 (page);
	self->priv->pages = g_list_append (self->priv->pages, _tmp1_);
	g_signal_emit_by_name (self, "page-added", page);
	book_set_needs_saving (self, TRUE);
	result = page;
	return result;
}


void book_move_page (Book* self, Page* page, guint location) {
	Page* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	self->priv->pages = g_list_remove (self->priv->pages, page);
	_tmp0_ = _page_ref0 (page);
	self->priv->pages = g_list_insert (self->priv->pages, _tmp0_, (gint) location);
	g_signal_emit_by_name (self, "reordered");
	book_set_needs_saving (self, TRUE);
}


void book_delete_page (Book* self, Page* page) {
	guint _tmp0_;
	guint _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	g_signal_parse_name ("pixels-changed", TYPE_PAGE, &_tmp0_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (page, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp0_, 0, NULL, (GCallback) _book_page_changed_cb_page_pixels_changed, self);
	g_signal_parse_name ("crop-changed", TYPE_PAGE, &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (page, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _book_page_changed_cb_page_crop_changed, self);
	g_signal_emit_by_name (self, "page-removed", page);
	self->priv->pages = g_list_remove (self->priv->pages, page);
	book_set_needs_saving (self, TRUE);
}


guint book_get_n_pages (Book* self) {
	guint result = 0U;
	guint _tmp0_;
	g_return_val_if_fail (self != NULL, 0U);
	_tmp0_ = g_list_length (self->priv->pages);
	result = _tmp0_;
	return result;
}


Page* book_get_page (Book* self, gint page_number) {
	Page* result = NULL;
	gconstpointer _tmp1_ = NULL;
	Page* _tmp2_;
	g_return_val_if_fail (self != NULL, NULL);
	if (page_number < 0) {
		guint _tmp0_;
		_tmp0_ = g_list_length (self->priv->pages);
		page_number = ((gint) _tmp0_) + page_number;
	}
	_tmp1_ = g_list_nth_data (self->priv->pages, (guint) page_number);
	_tmp2_ = _page_ref0 ((Page*) _tmp1_);
	result = _tmp2_;
	return result;
}


guint book_get_page_index (Book* self, Page* page) {
	guint result = 0U;
	gint _tmp0_;
	g_return_val_if_fail (self != NULL, 0U);
	g_return_val_if_fail (page != NULL, 0U);
	_tmp0_ = g_list_index (self->priv->pages, page);
	result = (guint) _tmp0_;
	return result;
}


static gint string_last_index_of_char (const gchar* self, gunichar c, gint start_index) {
	gint result = 0;
	gchar* _tmp0_ = NULL;
	gchar* _result_;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = g_utf8_strrchr (((gchar*) self) + start_index, (gssize) (-1), c);
	_result_ = _tmp0_;
	if (_result_ != NULL) {
		result = (gint) (_result_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}


static gchar* string_slice (const gchar* self, glong start, glong end) {
	gchar* result = NULL;
	gint _tmp0_;
	glong string_length;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gchar* _tmp3_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = strlen (self);
	string_length = (glong) _tmp0_;
	if (start < ((glong) 0)) {
		start = string_length + start;
	}
	if (end < ((glong) 0)) {
		end = string_length + end;
	}
	if (start >= ((glong) 0)) {
		_tmp1_ = start <= string_length;
	} else {
		_tmp1_ = FALSE;
	}
	g_return_val_if_fail (_tmp1_, NULL);
	if (end >= ((glong) 0)) {
		_tmp2_ = end <= string_length;
	} else {
		_tmp2_ = FALSE;
	}
	g_return_val_if_fail (_tmp2_, NULL);
	g_return_val_if_fail (start <= end, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + start, (gsize) (end - start));
	result = _tmp3_;
	return result;
}


static GFile* book_make_indexed_file (Book* self, const gchar* uri, gint i) {
	GFile* result = NULL;
	gchar* _tmp1_ = NULL;
	gchar* basename;
	gchar* _tmp2_;
	gchar* prefix;
	gchar* _tmp3_;
	gchar* suffix;
	gint _tmp4_;
	gint extension_index;
	gchar* _tmp10_ = NULL;
	gchar* _tmp11_;
	GFile* _tmp12_ = NULL;
	GFile* _tmp13_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (uri != NULL, NULL);
	if (i == 0) {
		GFile* _tmp0_ = NULL;
		_tmp0_ = g_file_new_for_uri (uri);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = g_path_get_basename (uri);
	basename = _tmp1_;
	_tmp2_ = g_strdup (uri);
	prefix = _tmp2_;
	_tmp3_ = g_strdup ("");
	suffix = _tmp3_;
	_tmp4_ = string_last_index_of_char (basename, (gunichar) '.', 0);
	extension_index = _tmp4_;
	if (extension_index >= 0) {
		gint _tmp5_;
		gchar* _tmp6_ = NULL;
		gint _tmp7_;
		gint _tmp8_;
		gchar* _tmp9_ = NULL;
		_tmp5_ = strlen (basename);
		_tmp6_ = string_slice (basename, (glong) extension_index, (glong) _tmp5_);
		_g_free0 (suffix);
		suffix = _tmp6_;
		_tmp7_ = strlen (uri);
		_tmp8_ = strlen (suffix);
		_tmp9_ = string_slice (uri, (glong) 0, (glong) (_tmp7_ - _tmp8_));
		_g_free0 (prefix);
		prefix = _tmp9_;
	}
	_tmp10_ = g_strdup_printf ("%s-%d%s", prefix, i, suffix);
	_tmp11_ = _tmp10_;
	_tmp12_ = g_file_new_for_uri (_tmp11_);
	_tmp13_ = _tmp12_;
	_g_free0 (_tmp11_);
	result = _tmp13_;
	_g_free0 (suffix);
	_g_free0 (prefix);
	_g_free0 (basename);
	return result;
}


static void book_save_multi_file (Book* self, const gchar* type, GFile* file, GError** error) {
	gint i;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (type != NULL);
	g_return_if_fail (file != NULL);
	i = 0;
	{
		GList* page_collection = NULL;
		GList* page_it = NULL;
		page_collection = self->priv->pages;
		for (page_it = page_collection; page_it != NULL; page_it = page_it->next) {
			Page* _tmp0_;
			Page* page = NULL;
			_tmp0_ = _page_ref0 ((Page*) page_it->data);
			page = _tmp0_;
			{
				gchar* _tmp1_ = NULL;
				gchar* _tmp2_;
				GFile* _tmp3_ = NULL;
				GFile* _tmp4_;
				_tmp1_ = g_file_get_uri (file);
				_tmp2_ = _tmp1_;
				_tmp3_ = book_make_indexed_file (self, _tmp2_, i);
				_tmp4_ = _tmp3_;
				page_save (page, type, _tmp4_, &_inner_error_);
				_g_object_unref0 (_tmp4_);
				_g_free0 (_tmp2_);
				if (_inner_error_ != NULL) {
					g_propagate_error (error, _inner_error_);
					_page_unref0 (page);
					return;
				}
				i++;
				_page_unref0 (page);
			}
		}
	}
}


static void book_save_ps_pdf_surface (Book* self, cairo_surface_t* surface, GdkPixbuf* image, gdouble dpi) {
	cairo_t* _tmp0_ = NULL;
	cairo_t* context;
	cairo_pattern_t* _tmp1_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (surface != NULL);
	g_return_if_fail (image != NULL);
	_tmp0_ = cairo_create (surface);
	context = _tmp0_;
	cairo_scale (context, 72.0 / dpi, 72.0 / dpi);
	gdk_cairo_set_source_pixbuf (context, image, (gdouble) 0, (gdouble) 0);
	_tmp1_ = cairo_get_source (context);
	cairo_pattern_set_filter (_tmp1_, CAIRO_FILTER_BEST);
	cairo_paint (context);
	_cairo_destroy0 (context);
}


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


static void book_save_ps (Book* self, GFile* file, GError** error) {
	GFileOutputStream* _tmp0_ = NULL;
	GFileOutputStream* stream;
	PsWriter* _tmp1_ = NULL;
	PsWriter* writer;
	cairo_surface_t* _tmp2_;
	cairo_surface_t* surface;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file != NULL);
	_tmp0_ = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &_inner_error_);
	stream = _tmp0_;
	if (_inner_error_ != NULL) {
		g_propagate_error (error, _inner_error_);
		return;
	}
	_tmp1_ = ps_writer_new (stream);
	writer = _tmp1_;
	_tmp2_ = _cairo_surface_reference0 (writer->surface);
	surface = _tmp2_;
	{
		GList* page_collection = NULL;
		GList* page_it = NULL;
		page_collection = self->priv->pages;
		for (page_it = page_collection; page_it != NULL; page_it = page_it->next) {
			Page* _tmp3_;
			Page* page = NULL;
			_tmp3_ = _page_ref0 ((Page*) page_it->data);
			page = _tmp3_;
			{
				GdkPixbuf* _tmp4_ = NULL;
				GdkPixbuf* image;
				gint _tmp5_;
				gint _tmp6_;
				gdouble width;
				gint _tmp7_;
				gint _tmp8_;
				gdouble height;
				gint _tmp9_;
				_tmp4_ = page_get_image (page, TRUE);
				image = _tmp4_;
				_tmp5_ = gdk_pixbuf_get_width (image);
				_tmp6_ = page_get_dpi (page);
				width = (_tmp5_ * 72.0) / _tmp6_;
				_tmp7_ = gdk_pixbuf_get_height (image);
				_tmp8_ = page_get_dpi (page);
				height = (_tmp7_ * 72.0) / _tmp8_;
				cairo_ps_surface_set_size (surface, width, height);
				_tmp9_ = page_get_dpi (page);
				book_save_ps_pdf_surface (self, surface, image, (gdouble) _tmp9_);
				cairo_surface_show_page (surface);
				_g_object_unref0 (image);
				_page_unref0 (page);
			}
		}
	}
	_cairo_surface_destroy0 (surface);
	_ps_writer_unref0 (writer);
	_g_object_unref0 (stream);
}


static guint8* book_compress_zlib (Book* self, guint8* data, int data_length1, int* result_length1) {
	guint8* result = NULL;
	z_stream stream = {0};
	guint8* _tmp0_ = NULL;
	guint8* out_data;
	gint out_data_length1;
	gint _out_data_size_;
	guint n_written;
	gint _tmp3_;
	guint8* _tmp4_;
	g_return_val_if_fail (self != NULL, NULL);
	deflateInit (&stream, (gint) Z_BEST_COMPRESSION);
	_tmp0_ = g_new0 (guint8, data_length1);
	out_data = _tmp0_;
	out_data_length1 = data_length1;
	_out_data_size_ = out_data_length1;
	stream.next_in = data;
	stream.avail_in = data_length1;
	stream.next_out = out_data;
	stream.avail_out = out_data_length1;
	while (TRUE) {
		gint _tmp1_;
		if (!(stream.avail_in > ((guint) 0))) {
			break;
		}
		_tmp1_ = deflate (&stream, (gint) Z_FINISH);
		if (_tmp1_ == ((gint) Z_STREAM_ERROR)) {
			break;
		}
	}
	if (stream.avail_in > ((guint) 0)) {
		guint8* _tmp2_;
		_tmp2_ = NULL;
		if (result_length1) {
			*result_length1 = 0;
		}
		result = _tmp2_;
		out_data = (g_free (out_data), NULL);
		deflateEnd (&stream);
		return result;
	}
	n_written = data_length1 - stream.avail_out;
	_tmp3_ = (gint) n_written;
	out_data = g_renew (guint8, out_data, (gint) n_written);
	(_tmp3_ > out_data_length1) ? memset (out_data + out_data_length1, 0, sizeof (guint8) * (_tmp3_ - out_data_length1)) : NULL;
	out_data_length1 = _tmp3_;
	_out_data_size_ = _tmp3_;
	_tmp4_ = out_data;
	if (result_length1) {
		*result_length1 = out_data_length1;
	}
	result = _tmp4_;
	deflateEnd (&stream);
	return result;
}


static void book_jpeg_init_cb (struct jpeg_compress_struct* info) {
}


static gboolean book_jpeg_empty_cb (struct jpeg_compress_struct* info) {
	gboolean result = FALSE;
	result = TRUE;
	return result;
}


static void book_jpeg_term_cb (struct jpeg_compress_struct* info) {
}


static void _book_jpeg_init_cb_jpeg_initdestinationfunc (struct jpeg_compress_struct* cinfo) {
	book_jpeg_init_cb (cinfo);
}


static gboolean _book_jpeg_empty_cb_jpeg_emptyoutputbufferfunc (struct jpeg_compress_struct* cinfo) {
	gboolean result;
	result = book_jpeg_empty_cb (cinfo);
	return result;
}


static void _book_jpeg_term_cb_jpeg_termdestinationfunc (struct jpeg_compress_struct* cinfo) {
	book_jpeg_term_cb (cinfo);
}


static guint8* book_compress_jpeg (Book* self, GdkPixbuf* image, gsize* n_written, int* result_length1) {
	gsize _n_written = 0UL;
	guint8* result = NULL;
	struct jpeg_compress_struct info = {0};
	struct jpeg_error_mgr jerr = {0};
	struct jpeg_destination_mgr dest_mgr = {0};
	struct jpeg_error_mgr* _tmp0_ = NULL;
	gint _tmp1_;
	gint _tmp2_;
	gint max_length;
	guint8* _tmp3_ = NULL;
	guint8* data;
	gint data_length1;
	gint _data_size_;
	guint8* _tmp4_ = NULL;
	guint8* pixels;
	gint pixels_length1;
	gint _pixels_size_;
	guint8* _tmp7_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (image != NULL, NULL);
	memset (&info, 0, sizeof (struct jpeg_compress_struct));
	memset (&jerr, 0, sizeof (struct jpeg_error_mgr));
	memset (&dest_mgr, 0, sizeof (struct jpeg_destination_mgr));
	_tmp0_ = jpeg_std_error (&jerr);
	info.err = _tmp0_;
	jpeg_create_compress (&info);
	_tmp1_ = gdk_pixbuf_get_width (image);
	info.image_width = _tmp1_;
	_tmp2_ = gdk_pixbuf_get_height (image);
	info.image_height = _tmp2_;
	info.input_components = 3;
	info.in_color_space = JCS_RGB;
	jpeg_set_defaults (&info);
	max_length = (info.image_width * info.image_height) * info.input_components;
	_tmp3_ = g_new0 (guint8, max_length);
	data = _tmp3_;
	data_length1 = max_length;
	_data_size_ = data_length1;
	dest_mgr.next_output_byte = data;
	dest_mgr.free_in_buffer = max_length;
	dest_mgr.init_destination = _book_jpeg_init_cb_jpeg_initdestinationfunc;
	dest_mgr.empty_output_buffer = _book_jpeg_empty_cb_jpeg_emptyoutputbufferfunc;
	dest_mgr.term_destination = _book_jpeg_term_cb_jpeg_termdestinationfunc;
	info.dest = &dest_mgr;
	jpeg_start_compress (&info, TRUE);
	_tmp4_ = gdk_pixbuf_get_pixels (image);
	pixels = _tmp4_;
	pixels_length1 = -1;
	_pixels_size_ = pixels_length1;
	{
		gint r;
		r = 0;
		{
			gboolean _tmp5_;
			_tmp5_ = TRUE;
			while (TRUE) {
				guint8* row[1] = {0};
				gint _tmp6_;
				if (!_tmp5_) {
					r++;
				}
				_tmp5_ = FALSE;
				if (!(r < info.image_height)) {
					break;
				}
				_tmp6_ = gdk_pixbuf_get_rowstride (image);
				row[0] = ((guint8*) pixels) + (r * _tmp6_);
				jpeg_write_scanlines (&info, row, 1);
			}
		}
	}
	jpeg_finish_compress (&info);
	_n_written = (gsize) (max_length - dest_mgr.free_in_buffer);
	_tmp7_ = data;
	if (result_length1) {
		*result_length1 = data_length1;
	}
	result = _tmp7_;
	jpeg_destroy_compress (&info);
	if (n_written) {
		*n_written = _n_written;
	}
	return result;
}


static guint8* _vala_array_dup1 (guint8* self, int length) {
	return g_memdup (self, length * sizeof (guint8));
}


static guint8* _vala_array_dup2 (guint8* self, int length) {
	return g_memdup (self, length * sizeof (guint8));
}


static void book_save_pdf (Book* self, GFile* file, GError** error) {
	GFileOutputStream* _tmp0_ = NULL;
	GFileOutputStream* stream;
	PDFWriter* _tmp1_ = NULL;
	PDFWriter* writer;
	guint _tmp2_;
	guint catalog_number;
	gchar* _tmp3_ = NULL;
	gchar* _tmp4_;
	gchar* _tmp5_ = NULL;
	gchar* _tmp6_;
	guint _tmp7_;
	guint pages_number;
	gchar* _tmp8_ = NULL;
	gchar* _tmp9_;
	guint _tmp14_;
	gchar* _tmp15_ = NULL;
	gchar* _tmp16_;
	guint _tmp100_;
	guint info_number;
	gchar* _tmp101_ = NULL;
	gchar* _tmp102_;
	gchar* _tmp103_ = NULL;
	gchar* _tmp104_;
	gsize xref_offset;
	guint _tmp105_;
	gchar* _tmp106_ = NULL;
	gchar* _tmp107_;
	guint _tmp110_;
	gchar* _tmp111_ = NULL;
	gchar* _tmp112_;
	gchar* _tmp113_ = NULL;
	gchar* _tmp114_;
	gchar* _tmp115_ = NULL;
	gchar* _tmp116_;
	gchar* _tmp117_ = NULL;
	gchar* _tmp118_;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file != NULL);
	_tmp0_ = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &_inner_error_);
	stream = _tmp0_;
	if (_inner_error_ != NULL) {
		g_propagate_error (error, _inner_error_);
		return;
	}
	_tmp1_ = pdf_writer_new (stream);
	writer = _tmp1_;
	pdf_writer_write_string (writer, "%%PDF-1.3\n");
	pdf_writer_write_string (writer, "%%\xe2\xe3\xcf\xd3\n");
	_tmp2_ = pdf_writer_start_object (writer);
	catalog_number = _tmp2_;
	_tmp3_ = g_strdup_printf ("%u 0 obj\n", catalog_number);
	_tmp4_ = _tmp3_;
	pdf_writer_write_string (writer, _tmp4_);
	_g_free0 (_tmp4_);
	pdf_writer_write_string (writer, "<<\n");
	pdf_writer_write_string (writer, "/Type /Catalog\n");
	_tmp5_ = g_strdup_printf ("/Pages %u 0 R\n", catalog_number + 1);
	_tmp6_ = _tmp5_;
	pdf_writer_write_string (writer, _tmp6_);
	_g_free0 (_tmp6_);
	pdf_writer_write_string (writer, ">>\n");
	pdf_writer_write_string (writer, "endobj\n");
	pdf_writer_write_string (writer, "\n");
	_tmp7_ = pdf_writer_start_object (writer);
	pages_number = _tmp7_;
	_tmp8_ = g_strdup_printf ("%u 0 obj\n", pages_number);
	_tmp9_ = _tmp8_;
	pdf_writer_write_string (writer, _tmp9_);
	_g_free0 (_tmp9_);
	pdf_writer_write_string (writer, "<<\n");
	pdf_writer_write_string (writer, "/Type /Pages\n");
	pdf_writer_write_string (writer, "/Kids [");
	{
		gint i;
		i = 0;
		{
			gboolean _tmp10_;
			_tmp10_ = TRUE;
			while (TRUE) {
				guint _tmp11_;
				gchar* _tmp12_ = NULL;
				gchar* _tmp13_;
				if (!_tmp10_) {
					i++;
				}
				_tmp10_ = FALSE;
				_tmp11_ = book_get_n_pages (self);
				if (!(((guint) i) < _tmp11_)) {
					break;
				}
				_tmp12_ = g_strdup_printf (" %u 0 R", (pages_number + 1) + (i * 3));
				_tmp13_ = _tmp12_;
				pdf_writer_write_string (writer, _tmp13_);
				_g_free0 (_tmp13_);
			}
		}
	}
	pdf_writer_write_string (writer, " ]\n");
	_tmp14_ = book_get_n_pages (self);
	_tmp15_ = g_strdup_printf ("/Count %u\n", _tmp14_);
	_tmp16_ = _tmp15_;
	pdf_writer_write_string (writer, _tmp16_);
	_g_free0 (_tmp16_);
	pdf_writer_write_string (writer, ">>\n");
	pdf_writer_write_string (writer, "endobj\n");
	{
		gint i;
		i = 0;
		{
			gboolean _tmp17_;
			_tmp17_ = TRUE;
			while (TRUE) {
				guint _tmp18_;
				Page* _tmp19_ = NULL;
				Page* page;
				GdkPixbuf* _tmp20_ = NULL;
				GdkPixbuf* image;
				gint _tmp21_;
				gint width;
				gint _tmp22_;
				gint height;
				guint8* _tmp23_ = NULL;
				guint8* pixels;
				gint pixels_length1;
				gint _pixels_size_;
				gint _tmp24_;
				gdouble page_width;
				gint _tmp25_;
				gdouble page_height;
				gint depth;
				gchar* _tmp26_;
				gchar* color_space;
				gchar* filter;
				gchar* _tmp27_ = NULL;
				gchar* width_buffer;
				gint width_buffer_length1;
				gint _width_buffer_size_;
				gchar* _tmp28_ = NULL;
				gchar* height_buffer;
				gint height_buffer_length1;
				gint _height_buffer_size_;
				guint8* data = NULL;
				gint data_length1 = 0;
				gint _data_size_ = 0;
				gboolean _tmp29_;
				gint _tmp52_;
				guint8* _tmp53_ = NULL;
				guint8* compressed_data;
				gint compressed_data_length1;
				gint _compressed_data_size_;
				guint _tmp63_;
				guint number;
				gchar* _tmp64_ = NULL;
				gchar* _tmp65_;
				gchar* _tmp66_ = NULL;
				gchar* _tmp67_;
				gchar* _tmp68_ = NULL;
				gchar* _tmp69_;
				const gchar* _tmp70_ = NULL;
				const gchar* _tmp71_ = NULL;
				gchar* _tmp72_ = NULL;
				gchar* _tmp73_;
				gchar* _tmp74_ = NULL;
				gchar* _tmp75_;
				guint _tmp76_;
				gchar* _tmp77_ = NULL;
				gchar* _tmp78_;
				gchar* _tmp79_ = NULL;
				gchar* _tmp80_;
				gchar* _tmp81_ = NULL;
				gchar* _tmp82_;
				gchar* _tmp83_ = NULL;
				gchar* _tmp84_;
				gchar* _tmp85_ = NULL;
				gchar* _tmp86_;
				gchar* _tmp87_ = NULL;
				gchar* _tmp88_;
				const gchar* _tmp91_ = NULL;
				const gchar* _tmp92_ = NULL;
				gchar* _tmp93_ = NULL;
				gchar* command;
				guint _tmp94_;
				gchar* _tmp95_ = NULL;
				gchar* _tmp96_;
				gint _tmp97_;
				gchar* _tmp98_ = NULL;
				gchar* _tmp99_;
				if (!_tmp17_) {
					i++;
				}
				_tmp17_ = FALSE;
				_tmp18_ = book_get_n_pages (self);
				if (!(((guint) i) < _tmp18_)) {
					break;
				}
				_tmp19_ = book_get_page (self, i);
				page = _tmp19_;
				_tmp20_ = page_get_image (page, TRUE);
				image = _tmp20_;
				_tmp21_ = gdk_pixbuf_get_width (image);
				width = _tmp21_;
				_tmp22_ = gdk_pixbuf_get_height (image);
				height = _tmp22_;
				_tmp23_ = gdk_pixbuf_get_pixels (image);
				pixels = _tmp23_;
				pixels_length1 = -1;
				_pixels_size_ = pixels_length1;
				_tmp24_ = page_get_dpi (page);
				page_width = (width * 72.0) / _tmp24_;
				_tmp25_ = page_get_dpi (page);
				page_height = (height * 72.0) / _tmp25_;
				depth = 8;
				_tmp26_ = g_strdup ("DeviceRGB");
				color_space = _tmp26_;
				filter = NULL;
				_tmp27_ = g_new0 (gchar, G_ASCII_DTOSTR_BUF_SIZE);
				width_buffer = _tmp27_;
				width_buffer_length1 = G_ASCII_DTOSTR_BUF_SIZE;
				_width_buffer_size_ = width_buffer_length1;
				_tmp28_ = g_new0 (gchar, G_ASCII_DTOSTR_BUF_SIZE);
				height_buffer = _tmp28_;
				height_buffer_length1 = G_ASCII_DTOSTR_BUF_SIZE;
				_height_buffer_size_ = height_buffer_length1;
				_tmp29_ = page_is_color (page);
				if (_tmp29_) {
					gchar* _tmp30_;
					gint data_length;
					guint8* _tmp31_ = NULL;
					depth = 8;
					_tmp30_ = g_strdup ("DeviceRGB");
					_g_free0 (color_space);
					color_space = _tmp30_;
					data_length = ((height * width) * 3) + 1;
					_tmp31_ = g_new0 (guint8, data_length);
					data = (g_free (data), NULL);
					data = _tmp31_;
					data_length1 = data_length;
					_data_size_ = data_length1;
					{
						gint row;
						row = 0;
						{
							gboolean _tmp32_;
							_tmp32_ = TRUE;
							while (TRUE) {
								gint _tmp33_;
								gint in_offset;
								gint out_offset;
								if (!_tmp32_) {
									row++;
								}
								_tmp32_ = FALSE;
								if (!(row < height)) {
									break;
								}
								_tmp33_ = gdk_pixbuf_get_rowstride (image);
								in_offset = row * _tmp33_;
								out_offset = (row * width) * 3;
								{
									gint x;
									x = 0;
									{
										gboolean _tmp34_;
										_tmp34_ = TRUE;
										while (TRUE) {
											gint in_o;
											gint out_o;
											if (!_tmp34_) {
												x++;
											}
											_tmp34_ = FALSE;
											if (!(x < width)) {
												break;
											}
											in_o = in_offset + (x * 3);
											out_o = out_offset + (x * 3);
											data[out_o] = pixels[in_o];
											data[out_o + 1] = pixels[in_o + 1];
											data[out_o + 2] = pixels[in_o + 2];
										}
									}
								}
							}
						}
					}
				} else {
					gint _tmp35_;
					_tmp35_ = page_get_depth (page);
					if (_tmp35_ == 2) {
						gint shift_count;
						gchar* _tmp36_;
						gint data_length;
						guint8* _tmp37_ = NULL;
						gint offset;
						shift_count = 6;
						depth = 2;
						_tmp36_ = g_strdup ("DeviceGray");
						_g_free0 (color_space);
						color_space = _tmp36_;
						data_length = height * (((width * 2) + 7) / 8);
						_tmp37_ = g_new0 (guint8, data_length);
						data = (g_free (data), NULL);
						data = _tmp37_;
						data_length1 = data_length;
						_data_size_ = data_length1;
						offset = 0;
						data[offset] = (guint8) 0;
						{
							gint row;
							row = 0;
							{
								gboolean _tmp38_;
								_tmp38_ = TRUE;
								while (TRUE) {
									gint _tmp39_;
									gint in_offset;
									if (!_tmp38_) {
										row++;
									}
									_tmp38_ = FALSE;
									if (!(row < height)) {
										break;
									}
									if (shift_count != 6) {
										offset++;
										data[offset] = (guint8) 0;
										shift_count = 6;
									}
									_tmp39_ = gdk_pixbuf_get_rowstride (image);
									in_offset = row * _tmp39_;
									{
										gint x;
										x = 0;
										{
											gboolean _tmp40_;
											_tmp40_ = TRUE;
											while (TRUE) {
												guint8 p;
												if (!_tmp40_) {
													x++;
												}
												_tmp40_ = FALSE;
												if (!(x < width)) {
													break;
												}
												p = pixels[in_offset + (x * 3)];
												if (((gint) p) >= 192) {
													data[offset] |= (guint8) (3 << shift_count);
												} else {
													if (((gint) p) >= 128) {
														data[offset] |= (guint8) (2 << shift_count);
													} else {
														if (((gint) p) >= 64) {
															data[offset] |= (guint8) (1 << shift_count);
														}
													}
												}
												if (shift_count == 0) {
													offset++;
													data[offset] = (guint8) 0;
													shift_count = 6;
												} else {
													shift_count = shift_count - 2;
												}
											}
										}
									}
								}
							}
						}
					} else {
						gint _tmp41_;
						_tmp41_ = page_get_depth (page);
						if (_tmp41_ == 1) {
							gint mask;
							gchar* _tmp42_;
							gint data_length;
							guint8* _tmp43_ = NULL;
							gint offset;
							mask = 0x80;
							depth = 1;
							_tmp42_ = g_strdup ("DeviceGray");
							_g_free0 (color_space);
							color_space = _tmp42_;
							data_length = height * ((width + 7) / 8);
							_tmp43_ = g_new0 (guint8, data_length);
							data = (g_free (data), NULL);
							data = _tmp43_;
							data_length1 = data_length;
							_data_size_ = data_length1;
							offset = 0;
							data[offset] = (guint8) 0;
							{
								gint row;
								row = 0;
								{
									gboolean _tmp44_;
									_tmp44_ = TRUE;
									while (TRUE) {
										gint _tmp45_;
										gint in_offset;
										if (!_tmp44_) {
											row++;
										}
										_tmp44_ = FALSE;
										if (!(row < height)) {
											break;
										}
										if (mask != 0x80) {
											offset++;
											data[offset] = (guint8) 0;
											mask = 0x80;
										}
										_tmp45_ = gdk_pixbuf_get_rowstride (image);
										in_offset = row * _tmp45_;
										{
											gint x;
											x = 0;
											{
												gboolean _tmp46_;
												_tmp46_ = TRUE;
												while (TRUE) {
													if (!_tmp46_) {
														x++;
													}
													_tmp46_ = FALSE;
													if (!(x < width)) {
														break;
													}
													if (((gint) pixels[in_offset + (x * 3)]) != 0) {
														data[offset] |= (guint8) mask;
													}
													mask = mask >> 1;
													if (mask == 0) {
														offset++;
														data[offset] = (guint8) 0;
														mask = 0x80;
													}
												}
											}
										}
									}
								}
							}
						} else {
							gchar* _tmp47_;
							gint data_length;
							guint8* _tmp48_ = NULL;
							depth = 8;
							_tmp47_ = g_strdup ("DeviceGray");
							_g_free0 (color_space);
							color_space = _tmp47_;
							data_length = (height * width) + 1;
							_tmp48_ = g_new0 (guint8, data_length);
							data = (g_free (data), NULL);
							data = _tmp48_;
							data_length1 = data_length;
							_data_size_ = data_length1;
							{
								gint row;
								row = 0;
								{
									gboolean _tmp49_;
									_tmp49_ = TRUE;
									while (TRUE) {
										gint _tmp50_;
										gint in_offset;
										gint out_offset;
										if (!_tmp49_) {
											row++;
										}
										_tmp49_ = FALSE;
										if (!(row < height)) {
											break;
										}
										_tmp50_ = gdk_pixbuf_get_rowstride (image);
										in_offset = row * _tmp50_;
										out_offset = row * width;
										{
											gint x;
											x = 0;
											{
												gboolean _tmp51_;
												_tmp51_ = TRUE;
												while (TRUE) {
													if (!_tmp51_) {
														x++;
													}
													_tmp51_ = FALSE;
													if (!(x < width)) {
														break;
													}
													data[out_offset + x] = pixels[in_offset + (x * 3)];
												}
											}
										}
									}
								}
							}
						}
					}
				}
				_tmp53_ = book_compress_zlib (self, data, data_length1, &_tmp52_);
				compressed_data = _tmp53_;
				compressed_data_length1 = _tmp52_;
				_compressed_data_size_ = compressed_data_length1;
				if (compressed_data != NULL) {
					if (depth > 1) {
						gsize jpeg_length = 0UL;
						gsize _tmp54_;
						gint _tmp55_;
						guint8* _tmp56_ = NULL;
						guint8* jpeg_data;
						gint jpeg_data_length1;
						gint _jpeg_data_size_;
						_tmp56_ = book_compress_jpeg (self, image, &_tmp54_, &_tmp55_);
						jpeg_length = _tmp54_;
						jpeg_data = _tmp56_;
						jpeg_data_length1 = _tmp55_;
						_jpeg_data_size_ = jpeg_data_length1;
						if (jpeg_length < ((gsize) compressed_data_length1)) {
							gchar* _tmp57_;
							guint8* _tmp58_;
							guint8* _tmp59_;
							_tmp57_ = g_strdup ("DCTDecode");
							_g_free0 (filter);
							filter = _tmp57_;
							_tmp59_ = (_tmp58_ = jpeg_data, (_tmp58_ == NULL) ? ((gpointer) _tmp58_) : _vala_array_dup1 (_tmp58_, jpeg_data_length1));
							data = (g_free (data), NULL);
							data = _tmp59_;
							data_length1 = jpeg_data_length1;
							_data_size_ = data_length1;
						}
						jpeg_data = (g_free (jpeg_data), NULL);
					}
					if (filter == NULL) {
						gchar* _tmp60_;
						guint8* _tmp61_;
						guint8* _tmp62_;
						_tmp60_ = g_strdup ("FlateDecode");
						_g_free0 (filter);
						filter = _tmp60_;
						_tmp62_ = (_tmp61_ = compressed_data, (_tmp61_ == NULL) ? ((gpointer) _tmp61_) : _vala_array_dup2 (_tmp61_, compressed_data_length1));
						data = (g_free (data), NULL);
						data = _tmp62_;
						data_length1 = compressed_data_length1;
						_data_size_ = data_length1;
					}
				}
				pdf_writer_write_string (writer, "\n");
				_tmp63_ = pdf_writer_start_object (writer);
				number = _tmp63_;
				_tmp64_ = g_strdup_printf ("%u 0 obj\n", number);
				_tmp65_ = _tmp64_;
				pdf_writer_write_string (writer, _tmp65_);
				_g_free0 (_tmp65_);
				pdf_writer_write_string (writer, "<<\n");
				pdf_writer_write_string (writer, "/Type /Page\n");
				_tmp66_ = g_strdup_printf ("/Parent %u 0 R\n", pages_number);
				_tmp67_ = _tmp66_;
				pdf_writer_write_string (writer, _tmp67_);
				_g_free0 (_tmp67_);
				_tmp68_ = g_strdup_printf ("/Resources << /XObject << /Im%d %u 0 R >> >>\n", i, number + 1);
				_tmp69_ = _tmp68_;
				pdf_writer_write_string (writer, _tmp69_);
				_g_free0 (_tmp69_);
				_tmp70_ = g_ascii_formatd (width_buffer, width_buffer_length1, "%.2f", page_width);
				_tmp71_ = g_ascii_formatd (height_buffer, height_buffer_length1, "%.2f", page_height);
				_tmp72_ = g_strdup_printf ("/MediaBox [ 0 0 %s %s ]\n", _tmp70_, _tmp71_);
				_tmp73_ = _tmp72_;
				pdf_writer_write_string (writer, _tmp73_);
				_g_free0 (_tmp73_);
				_tmp74_ = g_strdup_printf ("/Contents %u 0 R\n", number + 2);
				_tmp75_ = _tmp74_;
				pdf_writer_write_string (writer, _tmp75_);
				_g_free0 (_tmp75_);
				pdf_writer_write_string (writer, ">>\n");
				pdf_writer_write_string (writer, "endobj\n");
				pdf_writer_write_string (writer, "\n");
				_tmp76_ = pdf_writer_start_object (writer);
				number = _tmp76_;
				_tmp77_ = g_strdup_printf ("%u 0 obj\n", number);
				_tmp78_ = _tmp77_;
				pdf_writer_write_string (writer, _tmp78_);
				_g_free0 (_tmp78_);
				pdf_writer_write_string (writer, "<<\n");
				pdf_writer_write_string (writer, "/Type /XObject\n");
				pdf_writer_write_string (writer, "/Subtype /Image\n");
				_tmp79_ = g_strdup_printf ("/Width %d\n", width);
				_tmp80_ = _tmp79_;
				pdf_writer_write_string (writer, _tmp80_);
				_g_free0 (_tmp80_);
				_tmp81_ = g_strdup_printf ("/Height %d\n", height);
				_tmp82_ = _tmp81_;
				pdf_writer_write_string (writer, _tmp82_);
				_g_free0 (_tmp82_);
				_tmp83_ = g_strdup_printf ("/ColorSpace /%s\n", color_space);
				_tmp84_ = _tmp83_;
				pdf_writer_write_string (writer, _tmp84_);
				_g_free0 (_tmp84_);
				_tmp85_ = g_strdup_printf ("/BitsPerComponent %d\n", depth);
				_tmp86_ = _tmp85_;
				pdf_writer_write_string (writer, _tmp86_);
				_g_free0 (_tmp86_);
				_tmp87_ = g_strdup_printf ("/Length %d\n", data_length1);
				_tmp88_ = _tmp87_;
				pdf_writer_write_string (writer, _tmp88_);
				_g_free0 (_tmp88_);
				if (filter != NULL) {
					gchar* _tmp89_ = NULL;
					gchar* _tmp90_;
					_tmp89_ = g_strdup_printf ("/Filter /%s\n", filter);
					_tmp90_ = _tmp89_;
					pdf_writer_write_string (writer, _tmp90_);
					_g_free0 (_tmp90_);
				}
				pdf_writer_write_string (writer, ">>\n");
				pdf_writer_write_string (writer, "stream\n");
				pdf_writer_write (writer, data, data_length1);
				pdf_writer_write_string (writer, "\n");
				pdf_writer_write_string (writer, "endstream\n");
				pdf_writer_write_string (writer, "endobj\n");
				_tmp91_ = g_ascii_formatd (width_buffer, width_buffer_length1, "%f", page_width);
				_tmp92_ = g_ascii_formatd (height_buffer, height_buffer_length1, "%f", page_height);
				_tmp93_ = g_strdup_printf ("q\n%s 0 0 %s 0 0 cm\n/Im%d Do\nQ", _tmp91_, _tmp92_, i);
				command = _tmp93_;
				pdf_writer_write_string (writer, "\n");
				_tmp94_ = pdf_writer_start_object (writer);
				number = _tmp94_;
				_tmp95_ = g_strdup_printf ("%u 0 obj\n", number);
				_tmp96_ = _tmp95_;
				pdf_writer_write_string (writer, _tmp96_);
				_g_free0 (_tmp96_);
				pdf_writer_write_string (writer, "<<\n");
				_tmp97_ = strlen (command);
				_tmp98_ = g_strdup_printf ("/Length %d\n", _tmp97_ + 1);
				_tmp99_ = _tmp98_;
				pdf_writer_write_string (writer, _tmp99_);
				_g_free0 (_tmp99_);
				pdf_writer_write_string (writer, ">>\n");
				pdf_writer_write_string (writer, "stream\n");
				pdf_writer_write_string (writer, command);
				pdf_writer_write_string (writer, "\n");
				pdf_writer_write_string (writer, "endstream\n");
				pdf_writer_write_string (writer, "endobj\n");
				_g_free0 (command);
				compressed_data = (g_free (compressed_data), NULL);
				data = (g_free (data), NULL);
				height_buffer = (g_free (height_buffer), NULL);
				width_buffer = (g_free (width_buffer), NULL);
				_g_free0 (filter);
				_g_free0 (color_space);
				_g_object_unref0 (image);
				_page_unref0 (page);
			}
		}
	}
	pdf_writer_write_string (writer, "\n");
	_tmp100_ = pdf_writer_start_object (writer);
	info_number = _tmp100_;
	_tmp101_ = g_strdup_printf ("%u 0 obj\n", info_number);
	_tmp102_ = _tmp101_;
	pdf_writer_write_string (writer, _tmp102_);
	_g_free0 (_tmp102_);
	pdf_writer_write_string (writer, "<<\n");
	_tmp103_ = g_strdup_printf ("/Creator (Simple Scan %s)\n", VERSION);
	_tmp104_ = _tmp103_;
	pdf_writer_write_string (writer, _tmp104_);
	_g_free0 (_tmp104_);
	pdf_writer_write_string (writer, ">>\n");
	pdf_writer_write_string (writer, "endobj\n");
	xref_offset = writer->offset;
	pdf_writer_write_string (writer, "xref\n");
	_tmp105_ = g_list_length (writer->object_offsets);
	_tmp106_ = g_strdup_printf ("1 %zu\n", (gsize) _tmp105_);
	_tmp107_ = _tmp106_;
	pdf_writer_write_string (writer, _tmp107_);
	_g_free0 (_tmp107_);
	{
		GList* offset_collection = NULL;
		GList* offset_it = NULL;
		offset_collection = writer->object_offsets;
		for (offset_it = offset_collection; offset_it != NULL; offset_it = offset_it->next) {
			guint offset = 0U;
			offset = GPOINTER_TO_UINT (offset_it->data);
			{
				gchar* _tmp108_ = NULL;
				gchar* _tmp109_;
				_tmp108_ = g_strdup_printf ("%010zu 0000 n\n", (gsize) offset);
				_tmp109_ = _tmp108_;
				pdf_writer_write_string (writer, _tmp109_);
				_g_free0 (_tmp109_);
			}
		}
	}
	pdf_writer_write_string (writer, "trailer\n");
	pdf_writer_write_string (writer, "<<\n");
	_tmp110_ = g_list_length (writer->object_offsets);
	_tmp111_ = g_strdup_printf ("/Size %zu\n", (gsize) _tmp110_);
	_tmp112_ = _tmp111_;
	pdf_writer_write_string (writer, _tmp112_);
	_g_free0 (_tmp112_);
	_tmp113_ = g_strdup_printf ("/Info %u 0 R\n", info_number);
	_tmp114_ = _tmp113_;
	pdf_writer_write_string (writer, _tmp114_);
	_g_free0 (_tmp114_);
	_tmp115_ = g_strdup_printf ("/Root %u 0 R\n", catalog_number);
	_tmp116_ = _tmp115_;
	pdf_writer_write_string (writer, _tmp116_);
	_g_free0 (_tmp116_);
	pdf_writer_write_string (writer, ">>\n");
	pdf_writer_write_string (writer, "startxref\n");
	_tmp117_ = g_strdup_printf ("%zu\n", xref_offset);
	_tmp118_ = _tmp117_;
	pdf_writer_write_string (writer, _tmp118_);
	_g_free0 (_tmp118_);
	pdf_writer_write_string (writer, "%%%%EOF\n");
	_pdf_writer_unref0 (writer);
	_g_object_unref0 (stream);
}


void book_save (Book* self, const gchar* type, GFile* file, GError** error) {
	gint _tmp0_;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (type != NULL);
	g_return_if_fail (file != NULL);
	_tmp0_ = g_strcmp0 (type, "jpeg");
	if (_tmp0_ == 0) {
		book_save_multi_file (self, "jpeg", file, &_inner_error_);
		if (_inner_error_ != NULL) {
			g_propagate_error (error, _inner_error_);
			return;
		}
	} else {
		gint _tmp1_;
		_tmp1_ = g_strcmp0 (type, "png");
		if (_tmp1_ == 0) {
			book_save_multi_file (self, "png", file, &_inner_error_);
			if (_inner_error_ != NULL) {
				g_propagate_error (error, _inner_error_);
				return;
			}
		} else {
			gint _tmp2_;
			_tmp2_ = g_strcmp0 (type, "tiff");
			if (_tmp2_ == 0) {
				book_save_multi_file (self, "tiff", file, &_inner_error_);
				if (_inner_error_ != NULL) {
					g_propagate_error (error, _inner_error_);
					return;
				}
			} else {
				gint _tmp3_;
				_tmp3_ = g_strcmp0 (type, "ps");
				if (_tmp3_ == 0) {
					book_save_ps (self, file, &_inner_error_);
					if (_inner_error_ != NULL) {
						g_propagate_error (error, _inner_error_);
						return;
					}
				} else {
					gint _tmp4_;
					_tmp4_ = g_strcmp0 (type, "pdf");
					if (_tmp4_ == 0) {
						book_save_pdf (self, file, &_inner_error_);
						if (_inner_error_ != NULL) {
							g_propagate_error (error, _inner_error_);
							return;
						}
					}
				}
			}
		}
	}
}


void book_set_needs_saving (Book* self, gboolean needs_saving) {
	gboolean needed_saving;
	g_return_if_fail (self != NULL);
	needed_saving = self->priv->needs_saving;
	self->priv->needs_saving = needs_saving;
	if (needed_saving != needs_saving) {
		g_signal_emit_by_name (self, "needs-saving-changed");
	}
}


gboolean book_get_needs_saving (Book* self) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->needs_saving;
	return result;
}


static void g_cclosure_user_marshal_VOID__PAGE (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__PAGE) (gpointer data1, gpointer arg_1, gpointer data2);
	register GMarshalFunc_VOID__PAGE callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 2);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__PAGE) (marshal_data ? marshal_data : cc->callback);
	callback (data1, value_get_page (param_values + 1), data2);
}


static void value_book_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_book_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		book_unref (value->data[0].v_pointer);
	}
}


static void value_book_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = book_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_book_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_book_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		Book* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = book_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_book_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	Book** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = book_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_book (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecBook* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_BOOK), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_book (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_BOOK), NULL);
	return value->data[0].v_pointer;
}


void value_set_book (GValue* value, gpointer v_object) {
	Book* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_BOOK));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_BOOK));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		book_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		book_unref (old);
	}
}


void value_take_book (GValue* value, gpointer v_object) {
	Book* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_BOOK));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_BOOK));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		book_unref (old);
	}
}


static void book_class_init (BookClass * klass) {
	book_parent_class = g_type_class_peek_parent (klass);
	BOOK_CLASS (klass)->finalize = book_finalize;
	g_type_class_add_private (klass, sizeof (BookPrivate));
	g_signal_new ("page_added", TYPE_BOOK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__PAGE, G_TYPE_NONE, 1, TYPE_PAGE);
	g_signal_new ("page_removed", TYPE_BOOK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__PAGE, G_TYPE_NONE, 1, TYPE_PAGE);
	g_signal_new ("reordered", TYPE_BOOK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("cleared", TYPE_BOOK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("needs_saving_changed", TYPE_BOOK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}


static void book_instance_init (Book * self) {
	self->priv = BOOK_GET_PRIVATE (self);
	self->ref_count = 1;
}


static void book_finalize (Book* obj) {
	Book * self;
	self = BOOK (obj);
	__g_list_free__page_unref0_0 (self->priv->pages);
}


GType book_get_type (void) {
	static volatile gsize book_type_id__volatile = 0;
	if (g_once_init_enter (&book_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_book_init, value_book_free_value, value_book_copy_value, value_book_peek_pointer, "p", value_book_collect_value, "p", value_book_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (BookClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) book_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Book), 0, (GInstanceInitFunc) book_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType book_type_id;
		book_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Book", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&book_type_id__volatile, book_type_id);
	}
	return book_type_id__volatile;
}


gpointer book_ref (gpointer instance) {
	Book* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void book_unref (gpointer instance) {
	Book* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		BOOK_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


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


PDFWriter* pdf_writer_construct (GType object_type, GFileOutputStream* stream) {
	PDFWriter* self = NULL;
	GFileOutputStream* _tmp0_;
	g_return_val_if_fail (stream != NULL, NULL);
	self = (PDFWriter*) g_type_create_instance (object_type);
	_tmp0_ = _g_object_ref0 (stream);
	_g_object_unref0 (self->priv->stream);
	self->priv->stream = _tmp0_;
	return self;
}


PDFWriter* pdf_writer_new (GFileOutputStream* stream) {
	return pdf_writer_construct (TYPE_PDF_WRITER, stream);
}


void pdf_writer_write (PDFWriter* self, guint8* data, int data_length1) {
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	{
		g_output_stream_write_all ((GOutputStream*) self->priv->stream, data, (gsize) data_length1, NULL, NULL, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		e = _inner_error_;
		_inner_error_ = NULL;
		g_warning ("book.vala:529: Error writing PDF: %s", e->message);
		_g_error_free0 (e);
	}
	__finally0:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return;
	}
	self->offset = self->offset + data_length1;
}


static gchar* string_to_utf8 (const gchar* self, int* result_length1) {
	gchar* result = NULL;
	gint _tmp0_;
	gchar* _tmp1_ = NULL;
	gchar* _result_;
	gint _result__length1;
	gint __result__size_;
	gint _tmp2_;
	gchar* _tmp3_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = strlen (self);
	_tmp1_ = g_new0 (gchar, _tmp0_ + 1);
	_result_ = _tmp1_;
	_result__length1 = _tmp0_ + 1;
	__result__size_ = _result__length1;
	_result__length1--;
	_tmp2_ = strlen (self);
	memcpy (_result_, self, (gsize) _tmp2_);
	_tmp3_ = _result_;
	if (result_length1) {
		*result_length1 = _result__length1;
	}
	result = _tmp3_;
	return result;
}


void pdf_writer_write_string (PDFWriter* self, const gchar* text) {
	gint _tmp0_;
	gchar* _tmp1_ = NULL;
	guint8* _tmp2_;
	gint _tmp2__length1;
	g_return_if_fail (self != NULL);
	g_return_if_fail (text != NULL);
	_tmp1_ = string_to_utf8 (text, &_tmp0_);
	_tmp2_ = (guint8*) _tmp1_;
	_tmp2__length1 = _tmp0_;
	pdf_writer_write (self, _tmp2_, _tmp0_);
	_tmp2_ = (g_free (_tmp2_), NULL);
}


guint pdf_writer_start_object (PDFWriter* self) {
	guint result = 0U;
	guint _tmp0_;
	g_return_val_if_fail (self != NULL, 0U);
	self->object_offsets = g_list_append (self->object_offsets, GUINT_TO_POINTER ((guint) self->offset));
	_tmp0_ = g_list_length (self->object_offsets);
	result = _tmp0_;
	return result;
}


static void value_pdf_writer_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_pdf_writer_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		pdf_writer_unref (value->data[0].v_pointer);
	}
}


static void value_pdf_writer_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = pdf_writer_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_pdf_writer_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_pdf_writer_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		PDFWriter* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = pdf_writer_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_pdf_writer_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	PDFWriter** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = pdf_writer_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_pdf_writer (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecPDFWriter* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_PDF_WRITER), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_pdf_writer (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PDF_WRITER), NULL);
	return value->data[0].v_pointer;
}


void value_set_pdf_writer (GValue* value, gpointer v_object) {
	PDFWriter* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PDF_WRITER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PDF_WRITER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		pdf_writer_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		pdf_writer_unref (old);
	}
}


void value_take_pdf_writer (GValue* value, gpointer v_object) {
	PDFWriter* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PDF_WRITER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PDF_WRITER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		pdf_writer_unref (old);
	}
}


static void pdf_writer_class_init (PDFWriterClass * klass) {
	pdf_writer_parent_class = g_type_class_peek_parent (klass);
	PDF_WRITER_CLASS (klass)->finalize = pdf_writer_finalize;
	g_type_class_add_private (klass, sizeof (PDFWriterPrivate));
}


static void pdf_writer_instance_init (PDFWriter * self) {
	self->priv = PDF_WRITER_GET_PRIVATE (self);
	self->offset = (gsize) 0;
	self->ref_count = 1;
}


static void pdf_writer_finalize (PDFWriter* obj) {
	PDFWriter * self;
	self = PDF_WRITER (obj);
	_g_list_free0 (self->object_offsets);
	_g_object_unref0 (self->priv->stream);
}


GType pdf_writer_get_type (void) {
	static volatile gsize pdf_writer_type_id__volatile = 0;
	if (g_once_init_enter (&pdf_writer_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_pdf_writer_init, value_pdf_writer_free_value, value_pdf_writer_copy_value, value_pdf_writer_peek_pointer, "p", value_pdf_writer_collect_value, "p", value_pdf_writer_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (PDFWriterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pdf_writer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PDFWriter), 0, (GInstanceInitFunc) pdf_writer_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType pdf_writer_type_id;
		pdf_writer_type_id = g_type_register_fundamental (g_type_fundamental_next (), "PDFWriter", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&pdf_writer_type_id__volatile, pdf_writer_type_id);
	}
	return pdf_writer_type_id__volatile;
}


gpointer pdf_writer_ref (gpointer instance) {
	PDFWriter* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void pdf_writer_unref (gpointer instance) {
	PDFWriter* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		PDF_WRITER_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static cairo_status_t _ps_writer_write_cairo_data_cairo_write_func_t (gpointer self, guchar* data, int data_length1) {
	cairo_status_t result;
	result = ps_writer_write_cairo_data (self, data, data_length1);
	return result;
}


PsWriter* ps_writer_construct (GType object_type, GFileOutputStream* stream) {
	PsWriter* self = NULL;
	GFileOutputStream* _tmp0_;
	cairo_surface_t* _tmp1_ = NULL;
	g_return_val_if_fail (stream != NULL, NULL);
	self = (PsWriter*) g_type_create_instance (object_type);
	_tmp0_ = _g_object_ref0 (stream);
	_g_object_unref0 (self->stream);
	self->stream = _tmp0_;
	_tmp1_ = cairo_ps_surface_create_for_stream (_ps_writer_write_cairo_data_cairo_write_func_t, self, (gdouble) 0, (gdouble) 0);
	_cairo_surface_destroy0 (self->surface);
	self->surface = _tmp1_;
	return self;
}


PsWriter* ps_writer_new (GFileOutputStream* stream) {
	return ps_writer_construct (TYPE_PS_WRITER, stream);
}


static cairo_status_t ps_writer_write_cairo_data (PsWriter* self, guint8* data, int data_length1) {
	cairo_status_t result = 0;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, 0);
	{
		g_output_stream_write_all ((GOutputStream*) self->stream, data, (gsize) data_length1, NULL, NULL, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch1_g_error;
		}
	}
	goto __finally1;
	__catch1_g_error:
	{
		GError* e = NULL;
		e = _inner_error_;
		_inner_error_ = NULL;
		g_warning ("book.vala:565: Error writing data: %s", e->message);
		result = CAIRO_STATUS_WRITE_ERROR;
		_g_error_free0 (e);
		return result;
	}
	__finally1:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return 0;
	}
	result = CAIRO_STATUS_SUCCESS;
	return result;
}


static void value_ps_writer_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_ps_writer_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		ps_writer_unref (value->data[0].v_pointer);
	}
}


static void value_ps_writer_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = ps_writer_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_ps_writer_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_ps_writer_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		PsWriter* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = ps_writer_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_ps_writer_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	PsWriter** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = ps_writer_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_ps_writer (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecPsWriter* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_PS_WRITER), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_ps_writer (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PS_WRITER), NULL);
	return value->data[0].v_pointer;
}


void value_set_ps_writer (GValue* value, gpointer v_object) {
	PsWriter* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PS_WRITER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PS_WRITER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		ps_writer_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		ps_writer_unref (old);
	}
}


void value_take_ps_writer (GValue* value, gpointer v_object) {
	PsWriter* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_PS_WRITER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_PS_WRITER));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		ps_writer_unref (old);
	}
}


static void ps_writer_class_init (PsWriterClass * klass) {
	ps_writer_parent_class = g_type_class_peek_parent (klass);
	PS_WRITER_CLASS (klass)->finalize = ps_writer_finalize;
}


static void ps_writer_instance_init (PsWriter * self) {
	self->ref_count = 1;
}


static void ps_writer_finalize (PsWriter* obj) {
	PsWriter * self;
	self = PS_WRITER (obj);
	_cairo_surface_destroy0 (self->surface);
	_g_object_unref0 (self->stream);
}


GType ps_writer_get_type (void) {
	static volatile gsize ps_writer_type_id__volatile = 0;
	if (g_once_init_enter (&ps_writer_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_ps_writer_init, value_ps_writer_free_value, value_ps_writer_copy_value, value_ps_writer_peek_pointer, "p", value_ps_writer_collect_value, "p", value_ps_writer_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (PsWriterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ps_writer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PsWriter), 0, (GInstanceInitFunc) ps_writer_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType ps_writer_type_id;
		ps_writer_type_id = g_type_register_fundamental (g_type_fundamental_next (), "PsWriter", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&ps_writer_type_id__volatile, ps_writer_type_id);
	}
	return ps_writer_type_id__volatile;
}


gpointer ps_writer_ref (gpointer instance) {
	PsWriter* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void ps_writer_unref (gpointer instance) {
	PsWriter* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		PS_WRITER_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}