1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdkpixbuf.PixbufLoader;
26 
27 private import gdkpixbuf.Pixbuf;
28 private import gdkpixbuf.PixbufAnimation;
29 private import gdkpixbuf.PixbufFormat;
30 private import gdkpixbuf.c.functions;
31 public  import gdkpixbuf.c.types;
32 private import glib.Bytes;
33 private import glib.ConstructionException;
34 private import glib.ErrorG;
35 private import glib.GException;
36 private import glib.Str;
37 private import gobject.ObjectG;
38 private import gobject.Signals;
39 public  import gtkc.gdkpixbuftypes;
40 private import std.algorithm;
41 
42 
43 /**
44  * The GdkPixbufLoader struct contains only private
45  * fields.
46  */
47 public class PixbufLoader : ObjectG
48 {
49 	/** the main Gtk struct */
50 	protected GdkPixbufLoader* gdkPixbufLoader;
51 
52 	/** Get the main Gtk struct */
53 	public GdkPixbufLoader* getPixbufLoaderStruct(bool transferOwnership = false)
54 	{
55 		if (transferOwnership)
56 			ownedRef = false;
57 		return gdkPixbufLoader;
58 	}
59 
60 	/** the main Gtk struct as a void* */
61 	protected override void* getStruct()
62 	{
63 		return cast(void*)gdkPixbufLoader;
64 	}
65 
66 	/**
67 	 * Sets our main struct and passes it to the parent class.
68 	 */
69 	public this (GdkPixbufLoader* gdkPixbufLoader, bool ownedRef = false)
70 	{
71 		this.gdkPixbufLoader = gdkPixbufLoader;
72 		super(cast(GObject*)gdkPixbufLoader, ownedRef);
73 	}
74 
75 	/**
76 	 * Creates a new pixbuf loader object that always attempts to parse
77 	 * image data as if it were an image of type @image_type, instead of
78 	 * identifying the type automatically. Useful if you want an error if
79 	 * the image isn't the expected type, for loading image formats
80 	 * that can't be reliably identified by looking at the data, or if
81 	 * the user manually forces a specific type.
82 	 *
83 	 * The list of supported image formats depends on what image loaders
84 	 * are installed, but typically "png", "jpeg", "gif", "tiff" and
85 	 * "xpm" are among the supported formats. To obtain the full list of
86 	 * supported image formats, call gdk_pixbuf_format_get_name() on each
87 	 * of the #GdkPixbufFormat structs returned by gdk_pixbuf_get_formats().
88 	 *
89 	 * Params:
90 	 *     imageType  = name of the image format to be loaded with the image
91 	 *     isMimeType = Set to true if type is a mime type
92 	 *
93 	 * Return: A newly-created pixbuf loader.
94 	 *
95 	 * Throws: GException on failure.
96 	 */
97 	public this(string type, bool isMimeType=false)
98 	{
99 		GError* err = null;
100 		GdkPixbufLoader* p;
101 
102 		if ( isMimeType )
103 		{
104 			p = cast(GdkPixbufLoader*)gdk_pixbuf_loader_new_with_mime_type(Str.toStringz(type), &err);
105 		}
106 		else
107 		{
108 			p = cast(GdkPixbufLoader*)gdk_pixbuf_loader_new_with_type(Str.toStringz(type), &err);
109 		}
110 
111 		if (err !is null)
112 		{
113 			throw new GException( new ErrorG(err) );
114 		}
115 
116 		this(cast(GdkPixbufLoader*) p, true);
117 	}
118 
119 	/**
120 	 */
121 
122 	/** */
123 	public static GType getType()
124 	{
125 		return gdk_pixbuf_loader_get_type();
126 	}
127 
128 	/**
129 	 * Creates a new pixbuf loader object.
130 	 *
131 	 * Returns: A newly-created pixbuf loader.
132 	 *
133 	 * Throws: ConstructionException GTK+ fails to create the object.
134 	 */
135 	public this()
136 	{
137 		auto p = gdk_pixbuf_loader_new();
138 
139 		if(p is null)
140 		{
141 			throw new ConstructionException("null returned by new");
142 		}
143 
144 		this(cast(GdkPixbufLoader*) p, true);
145 	}
146 
147 	/**
148 	 * Informs a pixbuf loader that no further writes with
149 	 * gdk_pixbuf_loader_write() will occur, so that it can free its
150 	 * internal loading structures. Also, tries to parse any data that
151 	 * hasn't yet been parsed; if the remaining data is partial or
152 	 * corrupt, an error will be returned.  If %FALSE is returned, @error
153 	 * will be set to an error from the #GDK_PIXBUF_ERROR or #G_FILE_ERROR
154 	 * domains. If you're just cancelling a load rather than expecting it
155 	 * to be finished, passing %NULL for @error to ignore it is
156 	 * reasonable.
157 	 *
158 	 * Remember that this does not unref the loader, so if you plan not to
159 	 * use it anymore, please g_object_unref() it.
160 	 *
161 	 * Returns: %TRUE if all image data written so far was successfully
162 	 *     passed out via the update_area signal
163 	 *
164 	 * Throws: GException on failure.
165 	 */
166 	public bool close()
167 	{
168 		GError* err = null;
169 
170 		auto p = gdk_pixbuf_loader_close(gdkPixbufLoader, &err) != 0;
171 
172 		if (err !is null)
173 		{
174 			throw new GException( new ErrorG(err) );
175 		}
176 
177 		return p;
178 	}
179 
180 	/**
181 	 * Queries the #GdkPixbufAnimation that a pixbuf loader is currently creating.
182 	 * In general it only makes sense to call this function after the "area-prepared"
183 	 * signal has been emitted by the loader. If the loader doesn't have enough
184 	 * bytes yet (hasn't emitted the "area-prepared" signal) this function will
185 	 * return %NULL.
186 	 *
187 	 * Returns: The #GdkPixbufAnimation that the loader is loading, or %NULL if
188 	 *     not enough data has been read to determine the information.
189 	 */
190 	public PixbufAnimation getAnimation()
191 	{
192 		auto p = gdk_pixbuf_loader_get_animation(gdkPixbufLoader);
193 
194 		if(p is null)
195 		{
196 			return null;
197 		}
198 
199 		return ObjectG.getDObject!(PixbufAnimation)(cast(GdkPixbufAnimation*) p);
200 	}
201 
202 	/**
203 	 * Obtains the available information about the format of the
204 	 * currently loading image file.
205 	 *
206 	 * Returns: A #GdkPixbufFormat or
207 	 *     %NULL. The return value is owned by GdkPixbuf and should not be
208 	 *     freed.
209 	 *
210 	 * Since: 2.2
211 	 */
212 	public PixbufFormat getFormat()
213 	{
214 		auto p = gdk_pixbuf_loader_get_format(gdkPixbufLoader);
215 
216 		if(p is null)
217 		{
218 			return null;
219 		}
220 
221 		return ObjectG.getDObject!(PixbufFormat)(cast(GdkPixbufFormat*) p);
222 	}
223 
224 	/**
225 	 * Queries the #GdkPixbuf that a pixbuf loader is currently creating.
226 	 * In general it only makes sense to call this function after the
227 	 * "area-prepared" signal has been emitted by the loader; this means
228 	 * that enough data has been read to know the size of the image that
229 	 * will be allocated.  If the loader has not received enough data via
230 	 * gdk_pixbuf_loader_write(), then this function returns %NULL.  The
231 	 * returned pixbuf will be the same in all future calls to the loader,
232 	 * so simply calling g_object_ref() should be sufficient to continue
233 	 * using it.  Additionally, if the loader is an animation, it will
234 	 * return the "static image" of the animation
235 	 * (see gdk_pixbuf_animation_get_static_image()).
236 	 *
237 	 * Returns: The #GdkPixbuf that the loader is creating, or %NULL if not
238 	 *     enough data has been read to determine how to create the image buffer.
239 	 */
240 	public Pixbuf getPixbuf()
241 	{
242 		auto p = gdk_pixbuf_loader_get_pixbuf(gdkPixbufLoader);
243 
244 		if(p is null)
245 		{
246 			return null;
247 		}
248 
249 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) p);
250 	}
251 
252 	/**
253 	 * Causes the image to be scaled while it is loaded. The desired
254 	 * image size can be determined relative to the original size of
255 	 * the image by calling gdk_pixbuf_loader_set_size() from a
256 	 * signal handler for the ::size-prepared signal.
257 	 *
258 	 * Attempts to set the desired image size  are ignored after the
259 	 * emission of the ::size-prepared signal.
260 	 *
261 	 * Params:
262 	 *     width = The desired width of the image being loaded.
263 	 *     height = The desired height of the image being loaded.
264 	 *
265 	 * Since: 2.2
266 	 */
267 	public void setSize(int width, int height)
268 	{
269 		gdk_pixbuf_loader_set_size(gdkPixbufLoader, width, height);
270 	}
271 
272 	/**
273 	 * This will cause a pixbuf loader to parse the next @count bytes of
274 	 * an image.  It will return %TRUE if the data was loaded successfully,
275 	 * and %FALSE if an error occurred.  In the latter case, the loader
276 	 * will be closed, and will not accept further writes. If %FALSE is
277 	 * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR
278 	 * or #G_FILE_ERROR domains.
279 	 *
280 	 * Params:
281 	 *     buf = Pointer to image data.
282 	 *
283 	 * Returns: %TRUE if the write was successful, or %FALSE if the loader
284 	 *     cannot parse the buffer.
285 	 *
286 	 * Throws: GException on failure.
287 	 */
288 	public bool write(char[] buf)
289 	{
290 		GError* err = null;
291 
292 		auto p = gdk_pixbuf_loader_write(gdkPixbufLoader, buf.ptr, cast(size_t)buf.length, &err) != 0;
293 
294 		if (err !is null)
295 		{
296 			throw new GException( new ErrorG(err) );
297 		}
298 
299 		return p;
300 	}
301 
302 	/**
303 	 * This will cause a pixbuf loader to parse a buffer inside a #GBytes
304 	 * for an image.  It will return %TRUE if the data was loaded successfully,
305 	 * and %FALSE if an error occurred.  In the latter case, the loader
306 	 * will be closed, and will not accept further writes. If %FALSE is
307 	 * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR
308 	 * or #G_FILE_ERROR domains.
309 	 *
310 	 * See also: gdk_pixbuf_loader_write()
311 	 *
312 	 * Params:
313 	 *     buffer = The image data as a #GBytes
314 	 *
315 	 * Returns: %TRUE if the write was successful, or %FALSE if the loader
316 	 *     cannot parse the buffer.
317 	 *
318 	 * Since: 2.30
319 	 *
320 	 * Throws: GException on failure.
321 	 */
322 	public bool writeBytes(Bytes buffer)
323 	{
324 		GError* err = null;
325 
326 		auto p = gdk_pixbuf_loader_write_bytes(gdkPixbufLoader, (buffer is null) ? null : buffer.getBytesStruct(), &err) != 0;
327 
328 		if (err !is null)
329 		{
330 			throw new GException( new ErrorG(err) );
331 		}
332 
333 		return p;
334 	}
335 
336 	protected class OnAreaPreparedDelegateWrapper
337 	{
338 		void delegate(PixbufLoader) dlg;
339 		gulong handlerId;
340 
341 		this(void delegate(PixbufLoader) dlg)
342 		{
343 			this.dlg = dlg;
344 			onAreaPreparedListeners ~= this;
345 		}
346 
347 		void remove(OnAreaPreparedDelegateWrapper source)
348 		{
349 			foreach(index, wrapper; onAreaPreparedListeners)
350 			{
351 				if (wrapper.handlerId == source.handlerId)
352 				{
353 					onAreaPreparedListeners[index] = null;
354 					onAreaPreparedListeners = std.algorithm.remove(onAreaPreparedListeners, index);
355 					break;
356 				}
357 			}
358 		}
359 	}
360 	OnAreaPreparedDelegateWrapper[] onAreaPreparedListeners;
361 
362 	/**
363 	 * This signal is emitted when the pixbuf loader has allocated the
364 	 * pixbuf in the desired size.  After this signal is emitted,
365 	 * applications can call gdk_pixbuf_loader_get_pixbuf() to fetch
366 	 * the partially-loaded pixbuf.
367 	 */
368 	gulong addOnAreaPrepared(void delegate(PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
369 	{
370 		auto wrapper = new OnAreaPreparedDelegateWrapper(dlg);
371 		wrapper.handlerId = Signals.connectData(
372 			this,
373 			"area-prepared",
374 			cast(GCallback)&callBackAreaPrepared,
375 			cast(void*)wrapper,
376 			cast(GClosureNotify)&callBackAreaPreparedDestroy,
377 			connectFlags);
378 		return wrapper.handlerId;
379 	}
380 
381 	extern(C) static void callBackAreaPrepared(GdkPixbufLoader* pixbufloaderStruct, OnAreaPreparedDelegateWrapper wrapper)
382 	{
383 		wrapper.dlg(wrapper.outer);
384 	}
385 
386 	extern(C) static void callBackAreaPreparedDestroy(OnAreaPreparedDelegateWrapper wrapper, GClosure* closure)
387 	{
388 		wrapper.remove(wrapper);
389 	}
390 
391 	protected class OnAreaUpdatedDelegateWrapper
392 	{
393 		void delegate(int, int, int, int, PixbufLoader) dlg;
394 		gulong handlerId;
395 
396 		this(void delegate(int, int, int, int, PixbufLoader) dlg)
397 		{
398 			this.dlg = dlg;
399 			onAreaUpdatedListeners ~= this;
400 		}
401 
402 		void remove(OnAreaUpdatedDelegateWrapper source)
403 		{
404 			foreach(index, wrapper; onAreaUpdatedListeners)
405 			{
406 				if (wrapper.handlerId == source.handlerId)
407 				{
408 					onAreaUpdatedListeners[index] = null;
409 					onAreaUpdatedListeners = std.algorithm.remove(onAreaUpdatedListeners, index);
410 					break;
411 				}
412 			}
413 		}
414 	}
415 	OnAreaUpdatedDelegateWrapper[] onAreaUpdatedListeners;
416 
417 	/**
418 	 * This signal is emitted when a significant area of the image being
419 	 * loaded has been updated.  Normally it means that a complete
420 	 * scanline has been read in, but it could be a different area as
421 	 * well.  Applications can use this signal to know when to repaint
422 	 * areas of an image that is being loaded.
423 	 *
424 	 * Params:
425 	 *     x = X offset of upper-left corner of the updated area.
426 	 *     y = Y offset of upper-left corner of the updated area.
427 	 *     width = Width of updated area.
428 	 *     height = Height of updated area.
429 	 */
430 	gulong addOnAreaUpdated(void delegate(int, int, int, int, PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
431 	{
432 		auto wrapper = new OnAreaUpdatedDelegateWrapper(dlg);
433 		wrapper.handlerId = Signals.connectData(
434 			this,
435 			"area-updated",
436 			cast(GCallback)&callBackAreaUpdated,
437 			cast(void*)wrapper,
438 			cast(GClosureNotify)&callBackAreaUpdatedDestroy,
439 			connectFlags);
440 		return wrapper.handlerId;
441 	}
442 
443 	extern(C) static void callBackAreaUpdated(GdkPixbufLoader* pixbufloaderStruct, int x, int y, int width, int height, OnAreaUpdatedDelegateWrapper wrapper)
444 	{
445 		wrapper.dlg(x, y, width, height, wrapper.outer);
446 	}
447 
448 	extern(C) static void callBackAreaUpdatedDestroy(OnAreaUpdatedDelegateWrapper wrapper, GClosure* closure)
449 	{
450 		wrapper.remove(wrapper);
451 	}
452 
453 	protected class OnClosedDelegateWrapper
454 	{
455 		void delegate(PixbufLoader) dlg;
456 		gulong handlerId;
457 
458 		this(void delegate(PixbufLoader) dlg)
459 		{
460 			this.dlg = dlg;
461 			onClosedListeners ~= this;
462 		}
463 
464 		void remove(OnClosedDelegateWrapper source)
465 		{
466 			foreach(index, wrapper; onClosedListeners)
467 			{
468 				if (wrapper.handlerId == source.handlerId)
469 				{
470 					onClosedListeners[index] = null;
471 					onClosedListeners = std.algorithm.remove(onClosedListeners, index);
472 					break;
473 				}
474 			}
475 		}
476 	}
477 	OnClosedDelegateWrapper[] onClosedListeners;
478 
479 	/**
480 	 * This signal is emitted when gdk_pixbuf_loader_close() is called.
481 	 * It can be used by different parts of an application to receive
482 	 * notification when an image loader is closed by the code that
483 	 * drives it.
484 	 */
485 	gulong addOnClosed(void delegate(PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
486 	{
487 		auto wrapper = new OnClosedDelegateWrapper(dlg);
488 		wrapper.handlerId = Signals.connectData(
489 			this,
490 			"closed",
491 			cast(GCallback)&callBackClosed,
492 			cast(void*)wrapper,
493 			cast(GClosureNotify)&callBackClosedDestroy,
494 			connectFlags);
495 		return wrapper.handlerId;
496 	}
497 
498 	extern(C) static void callBackClosed(GdkPixbufLoader* pixbufloaderStruct, OnClosedDelegateWrapper wrapper)
499 	{
500 		wrapper.dlg(wrapper.outer);
501 	}
502 
503 	extern(C) static void callBackClosedDestroy(OnClosedDelegateWrapper wrapper, GClosure* closure)
504 	{
505 		wrapper.remove(wrapper);
506 	}
507 
508 	protected class OnSizePreparedDelegateWrapper
509 	{
510 		void delegate(int, int, PixbufLoader) dlg;
511 		gulong handlerId;
512 
513 		this(void delegate(int, int, PixbufLoader) dlg)
514 		{
515 			this.dlg = dlg;
516 			onSizePreparedListeners ~= this;
517 		}
518 
519 		void remove(OnSizePreparedDelegateWrapper source)
520 		{
521 			foreach(index, wrapper; onSizePreparedListeners)
522 			{
523 				if (wrapper.handlerId == source.handlerId)
524 				{
525 					onSizePreparedListeners[index] = null;
526 					onSizePreparedListeners = std.algorithm.remove(onSizePreparedListeners, index);
527 					break;
528 				}
529 			}
530 		}
531 	}
532 	OnSizePreparedDelegateWrapper[] onSizePreparedListeners;
533 
534 	/**
535 	 * This signal is emitted when the pixbuf loader has been fed the
536 	 * initial amount of data that is required to figure out the size
537 	 * of the image that it will create.  Applications can call
538 	 * gdk_pixbuf_loader_set_size() in response to this signal to set
539 	 * the desired size to which the image should be scaled.
540 	 *
541 	 * Params:
542 	 *     width = the original width of the image
543 	 *     height = the original height of the image
544 	 */
545 	gulong addOnSizePrepared(void delegate(int, int, PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
546 	{
547 		auto wrapper = new OnSizePreparedDelegateWrapper(dlg);
548 		wrapper.handlerId = Signals.connectData(
549 			this,
550 			"size-prepared",
551 			cast(GCallback)&callBackSizePrepared,
552 			cast(void*)wrapper,
553 			cast(GClosureNotify)&callBackSizePreparedDestroy,
554 			connectFlags);
555 		return wrapper.handlerId;
556 	}
557 
558 	extern(C) static void callBackSizePrepared(GdkPixbufLoader* pixbufloaderStruct, int width, int height, OnSizePreparedDelegateWrapper wrapper)
559 	{
560 		wrapper.dlg(width, height, wrapper.outer);
561 	}
562 
563 	extern(C) static void callBackSizePreparedDestroy(OnSizePreparedDelegateWrapper wrapper, GClosure* closure)
564 	{
565 		wrapper.remove(wrapper);
566 	}
567 }