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 private import std.algorithm;
40 
41 
42 /**
43  * Incremental image loader.
44  * 
45  * `GdkPixbufLoader` provides a way for applications to drive the
46  * process of loading an image, by letting them send the image data
47  * directly to the loader instead of having the loader read the data
48  * from a file. Applications can use this functionality instead of
49  * `gdk_pixbuf_new_from_file()` or `gdk_pixbuf_animation_new_from_file()`
50  * when they need to parse image data in small chunks. For example,
51  * it should be used when reading an image from a (potentially) slow
52  * network connection, or when loading an extremely large file.
53  * 
54  * To use `GdkPixbufLoader` to load an image, create a new instance,
55  * and call [method@GdkPixbuf.PixbufLoader.write] to send the data
56  * to it. When done, [method@GdkPixbuf.PixbufLoader.close] should be
57  * called to end the stream and finalize everything.
58  * 
59  * The loader will emit three important signals throughout the process:
60  * 
61  * - [signal@GdkPixbuf.PixbufLoader::size-prepared] will be emitted as
62  * soon as the image has enough information to determine the size of
63  * the image to be used. If you want to scale the image while loading
64  * it, you can call [method@GdkPixbuf.PixbufLoader.set_size] in
65  * response to this signal.
66  * - [signal@GdkPixbuf.PixbufLoader::area-prepared] will be emitted as
67  * soon as the pixbuf of the desired has been allocated. You can obtain
68  * the `GdkPixbuf` instance by calling [method@GdkPixbuf.PixbufLoader.get_pixbuf].
69  * If you want to use it, simply acquire a reference to it. You can
70  * also call `gdk_pixbuf_loader_get_pixbuf()` later to get the same
71  * pixbuf.
72  * - [signal@GdkPixbuf.PixbufLoader::area-updated] will be emitted every
73  * time a region is updated. This way you can update a partially
74  * completed image. Note that you do not know anything about the
75  * completeness of an image from the updated area. For example, in an
76  * interlaced image you will need to make several passes before the
77  * image is done loading.
78  * 
79  * ## Loading an animation
80  * 
81  * Loading an animation is almost as easy as loading an image. Once the
82  * first [signal@GdkPixbuf.PixbufLoader::area-prepared] signal has been
83  * emitted, you can call [method@GdkPixbuf.PixbufLoader.get_animation] to
84  * get the [class@GdkPixbuf.PixbufAnimation] instance, and then call
85  * and [method@GdkPixbuf.PixbufAnimation.get_iter] to get a
86  * [class@GdkPixbuf.PixbufAnimationIter] to retrieve the pixbuf for the
87  * desired time stamp.
88  */
89 public class PixbufLoader : ObjectG
90 {
91 	/** the main Gtk struct */
92 	protected GdkPixbufLoader* gdkPixbufLoader;
93 
94 	/** Get the main Gtk struct */
95 	public GdkPixbufLoader* getPixbufLoaderStruct(bool transferOwnership = false)
96 	{
97 		if (transferOwnership)
98 			ownedRef = false;
99 		return gdkPixbufLoader;
100 	}
101 
102 	/** the main Gtk struct as a void* */
103 	protected override void* getStruct()
104 	{
105 		return cast(void*)gdkPixbufLoader;
106 	}
107 
108 	/**
109 	 * Sets our main struct and passes it to the parent class.
110 	 */
111 	public this (GdkPixbufLoader* gdkPixbufLoader, bool ownedRef = false)
112 	{
113 		this.gdkPixbufLoader = gdkPixbufLoader;
114 		super(cast(GObject*)gdkPixbufLoader, ownedRef);
115 	}
116 
117 	/**
118 	 * Creates a new pixbuf loader object that always attempts to parse
119 	 * image data as if it were an image of type @image_type, instead of
120 	 * identifying the type automatically. Useful if you want an error if
121 	 * the image isn't the expected type, for loading image formats
122 	 * that can't be reliably identified by looking at the data, or if
123 	 * the user manually forces a specific type.
124 	 *
125 	 * The list of supported image formats depends on what image loaders
126 	 * are installed, but typically "png", "jpeg", "gif", "tiff" and
127 	 * "xpm" are among the supported formats. To obtain the full list of
128 	 * supported image formats, call gdk_pixbuf_format_get_name() on each
129 	 * of the #GdkPixbufFormat structs returned by gdk_pixbuf_get_formats().
130 	 *
131 	 * Params:
132 	 *     imageType  = name of the image format to be loaded with the image
133 	 *     isMimeType = Set to true if type is a mime type
134 	 *
135 	 * Return: A newly-created pixbuf loader.
136 	 *
137 	 * Throws: GException on failure.
138 	 */
139 	public this(string type, bool isMimeType=false)
140 	{
141 		GError* err = null;
142 		GdkPixbufLoader* p;
143 
144 		if ( isMimeType )
145 		{
146 			p = cast(GdkPixbufLoader*)gdk_pixbuf_loader_new_with_mime_type(Str.toStringz(type), &err);
147 		}
148 		else
149 		{
150 			p = cast(GdkPixbufLoader*)gdk_pixbuf_loader_new_with_type(Str.toStringz(type), &err);
151 		}
152 
153 		if (err !is null)
154 		{
155 			throw new GException( new ErrorG(err) );
156 		}
157 
158 		this(cast(GdkPixbufLoader*) p, true);
159 	}
160 
161 	/**
162 	 */
163 
164 	/** */
165 	public static GType getType()
166 	{
167 		return gdk_pixbuf_loader_get_type();
168 	}
169 
170 	/**
171 	 * Creates a new pixbuf loader object.
172 	 *
173 	 * Returns: A newly-created pixbuf loader.
174 	 *
175 	 * Throws: ConstructionException GTK+ fails to create the object.
176 	 */
177 	public this()
178 	{
179 		auto __p = gdk_pixbuf_loader_new();
180 
181 		if(__p is null)
182 		{
183 			throw new ConstructionException("null returned by new");
184 		}
185 
186 		this(cast(GdkPixbufLoader*) __p, true);
187 	}
188 
189 	/**
190 	 * Informs a pixbuf loader that no further writes with
191 	 * gdk_pixbuf_loader_write() will occur, so that it can free its
192 	 * internal loading structures.
193 	 *
194 	 * This function also tries to parse any data that hasn't yet been parsed;
195 	 * if the remaining data is partial or corrupt, an error will be returned.
196 	 *
197 	 * If `FALSE` is returned, `error` will be set to an error from the
198 	 * `GDK_PIXBUF_ERROR` or `G_FILE_ERROR` domains.
199 	 *
200 	 * If you're just cancelling a load rather than expecting it to be finished,
201 	 * passing `NULL` for `error` to ignore it is reasonable.
202 	 *
203 	 * Remember that this function does not release a reference on the loader, so
204 	 * you will need to explicitly release any reference you hold.
205 	 *
206 	 * Returns: `TRUE` if all image data written so far was successfully
207 	 *     passed out via the update_area signal
208 	 *
209 	 * Throws: GException on failure.
210 	 */
211 	public bool close()
212 	{
213 		GError* err = null;
214 
215 		auto __p = gdk_pixbuf_loader_close(gdkPixbufLoader, &err) != 0;
216 
217 		if (err !is null)
218 		{
219 			throw new GException( new ErrorG(err) );
220 		}
221 
222 		return __p;
223 	}
224 
225 	/**
226 	 * Queries the #GdkPixbufAnimation that a pixbuf loader is currently creating.
227 	 *
228 	 * In general it only makes sense to call this function after the
229 	 * [signal@GdkPixbuf.PixbufLoader::area-prepared] signal has been emitted by
230 	 * the loader.
231 	 *
232 	 * If the loader doesn't have enough bytes yet, and hasn't emitted the `area-prepared`
233 	 * signal, this function will return `NULL`.
234 	 *
235 	 * Returns: The animation that the loader is
236 	 *     currently loading
237 	 */
238 	public PixbufAnimation getAnimation()
239 	{
240 		auto __p = gdk_pixbuf_loader_get_animation(gdkPixbufLoader);
241 
242 		if(__p is null)
243 		{
244 			return null;
245 		}
246 
247 		return ObjectG.getDObject!(PixbufAnimation)(cast(GdkPixbufAnimation*) __p);
248 	}
249 
250 	/**
251 	 * Obtains the available information about the format of the
252 	 * currently loading image file.
253 	 *
254 	 * Returns: A #GdkPixbufFormat
255 	 *
256 	 * Since: 2.2
257 	 */
258 	public PixbufFormat getFormat()
259 	{
260 		auto __p = gdk_pixbuf_loader_get_format(gdkPixbufLoader);
261 
262 		if(__p is null)
263 		{
264 			return null;
265 		}
266 
267 		return ObjectG.getDObject!(PixbufFormat)(cast(GdkPixbufFormat*) __p);
268 	}
269 
270 	/**
271 	 * Queries the #GdkPixbuf that a pixbuf loader is currently creating.
272 	 *
273 	 * In general it only makes sense to call this function after the
274 	 * [signal@GdkPixbuf.PixbufLoader::area-prepared] signal has been
275 	 * emitted by the loader; this means that enough data has been read
276 	 * to know the size of the image that will be allocated.
277 	 *
278 	 * If the loader has not received enough data via gdk_pixbuf_loader_write(),
279 	 * then this function returns `NULL`.
280 	 *
281 	 * The returned pixbuf will be the same in all future calls to the loader,
282 	 * so if you want to keep using it, you should acquire a reference to it.
283 	 *
284 	 * Additionally, if the loader is an animation, it will return the "static
285 	 * image" of the animation (see gdk_pixbuf_animation_get_static_image()).
286 	 *
287 	 * Returns: The pixbuf that the loader is
288 	 *     creating
289 	 */
290 	public Pixbuf getPixbuf()
291 	{
292 		auto __p = gdk_pixbuf_loader_get_pixbuf(gdkPixbufLoader);
293 
294 		if(__p is null)
295 		{
296 			return null;
297 		}
298 
299 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) __p);
300 	}
301 
302 	/**
303 	 * Causes the image to be scaled while it is loaded.
304 	 *
305 	 * The desired image size can be determined relative to the original
306 	 * size of the image by calling gdk_pixbuf_loader_set_size() from a
307 	 * signal handler for the ::size-prepared signal.
308 	 *
309 	 * Attempts to set the desired image size  are ignored after the
310 	 * emission of the ::size-prepared signal.
311 	 *
312 	 * Params:
313 	 *     width = The desired width of the image being loaded.
314 	 *     height = The desired height of the image being loaded.
315 	 *
316 	 * Since: 2.2
317 	 */
318 	public void setSize(int width, int height)
319 	{
320 		gdk_pixbuf_loader_set_size(gdkPixbufLoader, width, height);
321 	}
322 
323 	/**
324 	 * Parses the next `count` bytes in the given image buffer.
325 	 *
326 	 * Params:
327 	 *     buf = Pointer to image data.
328 	 *
329 	 * Returns: `TRUE` if the write was successful, or
330 	 *     `FALSE` if the loader cannot parse the buffer
331 	 *
332 	 * Throws: GException on failure.
333 	 */
334 	public bool write(char[] buf)
335 	{
336 		GError* err = null;
337 
338 		auto __p = gdk_pixbuf_loader_write(gdkPixbufLoader, buf.ptr, cast(size_t)buf.length, &err) != 0;
339 
340 		if (err !is null)
341 		{
342 			throw new GException( new ErrorG(err) );
343 		}
344 
345 		return __p;
346 	}
347 
348 	/**
349 	 * Parses the next contents of the given image buffer.
350 	 *
351 	 * Params:
352 	 *     buffer = The image data as a `GBytes` buffer.
353 	 *
354 	 * Returns: `TRUE` if the write was successful, or `FALSE` if
355 	 *     the loader cannot parse the buffer
356 	 *
357 	 * Since: 2.30
358 	 *
359 	 * Throws: GException on failure.
360 	 */
361 	public bool writeBytes(Bytes buffer)
362 	{
363 		GError* err = null;
364 
365 		auto __p = gdk_pixbuf_loader_write_bytes(gdkPixbufLoader, (buffer is null) ? null : buffer.getBytesStruct(), &err) != 0;
366 
367 		if (err !is null)
368 		{
369 			throw new GException( new ErrorG(err) );
370 		}
371 
372 		return __p;
373 	}
374 
375 	/**
376 	 * This signal is emitted when the pixbuf loader has allocated the
377 	 * pixbuf in the desired size.
378 	 *
379 	 * After this signal is emitted, applications can call
380 	 * gdk_pixbuf_loader_get_pixbuf() to fetch the partially-loaded
381 	 * pixbuf.
382 	 */
383 	gulong addOnAreaPrepared(void delegate(PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
384 	{
385 		return Signals.connect(this, "area-prepared", dlg, connectFlags ^ ConnectFlags.SWAPPED);
386 	}
387 
388 	/**
389 	 * This signal is emitted when a significant area of the image being
390 	 * loaded has been updated.
391 	 *
392 	 * Normally it means that a complete scanline has been read in, but
393 	 * it could be a different area as well.
394 	 *
395 	 * Applications can use this signal to know when to repaint
396 	 * areas of an image that is being loaded.
397 	 *
398 	 * Params:
399 	 *     x = X offset of upper-left corner of the updated area.
400 	 *     y = Y offset of upper-left corner of the updated area.
401 	 *     width = Width of updated area.
402 	 *     height = Height of updated area.
403 	 */
404 	gulong addOnAreaUpdated(void delegate(int, int, int, int, PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
405 	{
406 		return Signals.connect(this, "area-updated", dlg, connectFlags ^ ConnectFlags.SWAPPED);
407 	}
408 
409 	/**
410 	 * This signal is emitted when gdk_pixbuf_loader_close() is called.
411 	 *
412 	 * It can be used by different parts of an application to receive
413 	 * notification when an image loader is closed by the code that
414 	 * drives it.
415 	 */
416 	gulong addOnClosed(void delegate(PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
417 	{
418 		return Signals.connect(this, "closed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
419 	}
420 
421 	/**
422 	 * This signal is emitted when the pixbuf loader has been fed the
423 	 * initial amount of data that is required to figure out the size
424 	 * of the image that it will create.
425 	 *
426 	 * Applications can call gdk_pixbuf_loader_set_size() in response
427 	 * to this signal to set the desired size to which the image
428 	 * should be scaled.
429 	 *
430 	 * Params:
431 	 *     width = the original width of the image
432 	 *     height = the original height of the image
433 	 */
434 	gulong addOnSizePrepared(void delegate(int, int, PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
435 	{
436 		return Signals.connect(this, "size-prepared", dlg, connectFlags ^ ConnectFlags.SWAPPED);
437 	}
438 }