context: // Pixbuf.cs - Gdk Pixbuf class customizations
  //
  // Authors: 
  // 	Vladimir Vukicevic <vladimir@pobox.com>
  // 	Miguel de Icaza <miguel@ximian.com>
  // 	Mike Kestner <mkestner@ximian.com>
  // 	Duncan Mak <duncan@ximian.com>
  //	Gonzalo Paniagua Javier <gonzalo@ximian.com>
  //	Martin Willemoes Hansen <mwh@sysrq.dk>
  //	Jose Faria   <spigaz@gmail.com> 
  //
  // Copyright (c) 2002 Vladimir Vukicevic
  // Copyright (c) 2003 Ximian, Inc. (Miguel de Icaza)
  // Copyright (c) 2003 Ximian, Inc. (Duncan Mak)
  // Copyright (c) 2003 Ximian, Inc. (Gonzalo Paniagua Javier)
  // Copyright (c) 2003 Martin Willemoes Hansen
  // Copyright (c) 2004-2005 Novell, Inc.
  //
  // This code is inserted after the automatically generated code.
  //
  // This program is free software; you can redistribute it and/or
  // modify it under the terms of version 2 of the Lesser GNU General 
  // Public License as published by the Free Software Foundation.
  //
  // 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
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this program; if not, write to the
  // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  // Boston, MA 02111-1307, USA.
  
  namespace Gdk {
  
  	using System;
  	using System.Runtime.InteropServices;
  
  	public partial class Pixbuf {
  
  		public Pixbuf (System.IO.Stream stream) : base (IntPtr.Zero)
  		{
  			using (PixbufLoader pl = new PixbufLoader (stream)) {
  				Raw = pl.PixbufHandle;
  			}
  		}
  		
  		public Pixbuf (System.IO.Stream stream, int width, int height) : base (IntPtr.Zero)
  		{
  			using (PixbufLoader pl = new PixbufLoader (stream, width, height)) {
  				Raw = pl.PixbufHandle;
  			}
  		}
  		
  		public Pixbuf (System.Reflection.Assembly assembly, string resource) : base (IntPtr.Zero)
  		{
  			using (PixbufLoader pl = new PixbufLoader (assembly == null ? System.Reflection.Assembly.GetCallingAssembly () : assembly, resource)) {
  				Raw = pl.PixbufHandle;
  			}
  		}
  				
  		public Pixbuf (System.Reflection.Assembly assembly, string resource, int width, int height) : base (IntPtr.Zero)
  		{
  			using (PixbufLoader pl = new PixbufLoader (assembly == null ? System.Reflection.Assembly.GetCallingAssembly () : assembly, resource, width, height)) {
  				Raw = pl.PixbufHandle;
  			}
  		}
  		
  		public Pixbuf (byte[] buffer) : base (IntPtr.Zero)
  		{
  			using (PixbufLoader pl = new PixbufLoader (buffer)) {
  				Raw = pl.PixbufHandle;
  			}
  		}
  
  		public Pixbuf (byte[] buffer, int width, int height) : base (IntPtr.Zero)
  		{
  			using (PixbufLoader pl = new PixbufLoader (buffer, width, height)) {
  				Raw = pl.PixbufHandle;
  			}
  		}
  
  		static public Pixbuf LoadFromResource (string resource)
  		{
  			return new Pixbuf (System.Reflection.Assembly.GetCallingAssembly (), resource);
  		}
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr gdk_pixbuf_scale_simple(IntPtr raw, int dest_width, int dest_height, int interp_type);
  
  		public Gdk.Pixbuf ScaleSimple(int dest_width, int dest_height, Gdk.InterpType interp_type) {
  			IntPtr raw_ret = gdk_pixbuf_scale_simple(Handle, dest_width, dest_height, (int) interp_type);
  			Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
  			return ret;
  		}
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr gdk_pixbuf_composite_color_simple(IntPtr raw, int dest_width, int dest_height, int interp_type, int overall_alpha, int check_size, uint color1, uint color2);
  
  		public Gdk.Pixbuf CompositeColorSimple(int dest_width, int dest_height, Gdk.InterpType interp_type, int overall_alpha, int check_size, uint color1, uint color2) {
  			IntPtr raw_ret = gdk_pixbuf_composite_color_simple(Handle, dest_width, dest_height, (int) interp_type, overall_alpha, check_size, color1, color2);
  			Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
  			return ret;
  		}
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr gdk_pixbuf_add_alpha(IntPtr raw, bool substitute_color, byte r, byte g, byte b);
  
  		public Gdk.Pixbuf AddAlpha(bool substitute_color, byte r, byte g, byte b) {
  			IntPtr raw_ret = gdk_pixbuf_add_alpha(Handle, substitute_color, r, g, b);
  			Gdk.Pixbuf ret = (Gdk.Pixbuf) GLib.Object.GetObject(raw_ret, true);
  			return ret;
  		}
  
  		class DestroyHelper {
  
  			GCHandle gch;
  			GCHandle data_handle;
  			PixbufDestroyNotify notify;
  
  			public DestroyHelper (byte[] data, PixbufDestroyNotify notify)
  			{
  				gch = GCHandle.Alloc (this);
  				data_handle = GCHandle.Alloc (data, GCHandleType.Pinned);
  				this.notify = notify;
  			}
  
  			[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
  			public delegate void NativeDelegate (IntPtr buf, IntPtr data);
  
  			void ReleaseHandles (IntPtr buf, IntPtr data)
  			{
  				if (notify != null)
  					notify ((byte[])data_handle.Target);
  				data_handle.Free ();
  				gch.Free ();
  			}
  
  			NativeDelegate handler;
  			public NativeDelegate Handler {
  				get {
  					handler = new NativeDelegate (ReleaseHandles);
  					return handler;
  				}
  			}
  		}
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr gdk_pixbuf_new_from_data(byte[] data, int colorspace, bool has_alpha, int bits_per_sample, int width, int height, int rowstride, DestroyHelper.NativeDelegate destroy_fn, IntPtr destroy_fn_data);
  
  		public Pixbuf (byte[] data, Gdk.Colorspace colorspace, bool has_alpha, int bits_per_sample, int width, int height, int rowstride, Gdk.PixbufDestroyNotify destroy_fn) : base (IntPtr.Zero)
  		{
  			if (GetType () != typeof (Pixbuf)) {
  				throw new InvalidOperationException ("Can't override this constructor.");
  			}
  			DestroyHelper helper = new DestroyHelper (data, destroy_fn);
  			Raw = gdk_pixbuf_new_from_data(data, (int) colorspace, has_alpha, bits_per_sample, width, height, rowstride, helper.Handler, IntPtr.Zero);
  		}
  
  		// overload to default the colorspace
  		public Pixbuf(byte [] data, bool has_alpha, int bits_per_sample, int width, int height, int rowstride, Gdk.PixbufDestroyNotify destroy_fn) : this (data, Gdk.Colorspace.Rgb, has_alpha, bits_per_sample, width, height, rowstride, destroy_fn) {}
  
  		public Pixbuf(byte [] data, bool has_alpha, int bits_per_sample, int width, int height, int rowstride) : this (data, Gdk.Colorspace.Rgb, has_alpha, bits_per_sample, width, height, rowstride, null) {}
  
  		public Pixbuf(byte [] data, Gdk.Colorspace colorspace, bool has_alpha, int bits_per_sample, int width, int height, int rowstride) : this (data, colorspace, has_alpha, bits_per_sample, width, height, rowstride, null) {}
  
  		/* gdk_pixbuf_new_from_inline has been deprecated since version 2.32 and should not be used in newly-written code. Use GResource instead */
  		/*
  		public unsafe Pixbuf(byte[] data, bool copy_pixels) : base (IntPtr.Zero)
  		{
  			IntPtr error = IntPtr.Zero;
  			Raw = gdk_pixbuf_new_from_inline(data.Length, (IntPtr) data, copy_pixels, out error);
  			if (error != IntPtr.Zero) throw new GLib.GException (error);
  		}
  		*/
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern unsafe IntPtr gdk_pixbuf_new_from_inline(int len, IntPtr data, bool copy_pixels, out IntPtr error);
  
  		public unsafe Pixbuf(int data_length, void *data, bool copy_pixels) : base (IntPtr.Zero)
  		{
  			IntPtr error = IntPtr.Zero;
  			Raw = gdk_pixbuf_new_from_inline(data_length, (IntPtr) data, copy_pixels, out error);
  			if (error != IntPtr.Zero) throw new GLib.GException (error);
  		}
  	
  //
  // ICloneable interface
  //
  
  		public object Clone ()
  		{
  			return Copy ();
  		}
  
  
  //
  // the 'Pixels' property
  //
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr gdk_pixbuf_get_pixels(IntPtr raw);
  
                  public IntPtr Pixels {
                  	get {
                  		IntPtr ret = gdk_pixbuf_get_pixels (Handle);
                  		return ret;
                  	}
                  }
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern IntPtr gdk_pixbuf_get_formats();
  
  		public static PixbufFormat[] Formats {
  			get {
  				IntPtr list_ptr = gdk_pixbuf_get_formats ();
  				if (list_ptr == IntPtr.Zero)
  					return new PixbufFormat [0];
  				GLib.SList list = new GLib.SList (list_ptr, typeof (PixbufFormat));
  				PixbufFormat[] result = new PixbufFormat [list.Count];
  				for (int i = 0; i < list.Count; i++)
  					result [i] = (PixbufFormat) list [i];
  				return result;
  			}
  		}
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern unsafe bool gdk_pixbuf_save(IntPtr raw, IntPtr filename, IntPtr type, out IntPtr error, IntPtr dummy);
  
  		public unsafe bool Save(string filename, string type) {
  			IntPtr error = IntPtr.Zero;
  			IntPtr nfilename = GLib.Marshaller.StringToPtrGStrdup (filename);
  			IntPtr ntype = GLib.Marshaller.StringToPtrGStrdup (type);
  			bool ret = gdk_pixbuf_save(Handle, nfilename, ntype, out error, IntPtr.Zero);
  			GLib.Marshaller.Free (nfilename);
  			GLib.Marshaller.Free (ntype);
  			if (error != IntPtr.Zero) throw new GLib.GException (error);
  			return ret;
  		}
  
  		[DllImport ("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
  		static extern unsafe bool gdk_pixbuf_save_to_bufferv (IntPtr raw, out IntPtr buffer, out IntPtr buffer_size, IntPtr type, IntPtr[] option_keys, IntPtr[] option_values, out IntPtr error);
  
  		IntPtr[] NullTerm (string[] src)
  		{
  			if (src.Length == 0)
  				return null;
  			IntPtr[] result = new IntPtr [src.Length + 1];
  			for (int i = 0; i < src.Length; i++)
  				result [i] = GLib.Marshaller.StringToPtrGStrdup (src [i]);
  			result [src.Length] = IntPtr.Zero;
  			return result;
  		}
  
  		void ReleaseArray (IntPtr[] ptrs)
  		{
  			if (ptrs == null)
  				return;
  			foreach (IntPtr p in ptrs)
  				GLib.Marshaller.Free (p);
  		}
  
  		public unsafe byte[] SaveToBuffer (string type)
  		{
  			return SaveToBuffer (type, new string [0], new string [0]);
  		}
  
  		public unsafe byte[] SaveToBuffer (string type, string[] option_keys, string[] option_values) 
  		{
  			IntPtr error = IntPtr.Zero;
  			IntPtr buffer;
  			IntPtr buffer_size;
  			IntPtr ntype = GLib.Marshaller.StringToPtrGStrdup (type);
  
gt: 			IntPtr[] nkeys = NullTerm (option_keys);