]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf.c
be67197bcdf1100dc43d7df66dc9f87eeb436895
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf.c
1 /* GdkPixbuf library - Basic memory management
2  *
3  * Copyright (C) 1999 The Free Software Foundation
4  *
5  * Authors: Mark Crichton <crichton@gimp.org>
6  *          Miguel de Icaza <miguel@gnu.org>
7  *          Federico Mena-Quintero <federico@gimp.org>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include <config.h>
26 #include <math.h>
27 #include <stdlib.h>
28 #include "gdk-pixbuf.h"
29 #include "gdk-pixbuf-private.h"
30
31 \f
32
33 /* Reference counting */
34
35 /**
36  * gdk_pixbuf_ref:
37  * @pixbuf: A pixbuf.
38  *
39  * Adds a reference to a pixbuf.  It must be released afterwards using
40  * gdk_pixbuf_unref().
41  *
42  * Return value: The same as the @pixbuf argument.
43  **/
44 GdkPixbuf *
45 gdk_pixbuf_ref (GdkPixbuf *pixbuf)
46 {
47         g_return_val_if_fail (pixbuf != NULL, NULL);
48         g_return_val_if_fail (pixbuf->ref_count > 0, NULL);
49
50         pixbuf->ref_count++;
51         return pixbuf;
52 }
53
54 /**
55  * gdk_pixbuf_unref:
56  * @pixbuf: A pixbuf.
57  *
58  * Removes a reference from a pixbuf, which will be destroyed when the reference
59  * count drops to zero.
60  **/
61 void
62 gdk_pixbuf_unref (GdkPixbuf *pixbuf)
63 {
64         g_return_if_fail (pixbuf != NULL);
65         g_return_if_fail (pixbuf->ref_count > 0);
66
67         pixbuf->ref_count--;
68
69         if (pixbuf->ref_count == 0) {
70                 if (pixbuf->destroy_fn)
71                         (* pixbuf->destroy_fn) (pixbuf->pixels, pixbuf->destroy_fn_data);
72
73                 g_free (pixbuf);
74         }
75 }
76
77 \f
78
79 /* Used as the destroy notification function for gdk_pixbuf_new() */
80 static void
81 free_buffer (guchar *pixels, gpointer data)
82 {
83         free (pixels);
84 }
85
86 /**
87  * gdk_pixbuf_new:
88  * @colorspace: Color space for image.
89  * @has_alpha: Whether the image should have transparency information.
90  * @bits_per_sample: Number of bits per color sample.
91  * @width: Width of image in pixels.
92  * @height: Height of image in pixels.
93  *
94  * Creates a new #GdkPixbuf structure and allocates a buffer for it.  The buffer
95  * has an optimal rowstride.  Note that the buffer is not cleared; you will have
96  * to fill it completely yourself.
97  *
98  * Return value: A newly-created #GdkPixbuf with a reference count of 1, or NULL
99  * if not enough memory could be allocated for the image buffer.
100  **/
101 GdkPixbuf *
102 gdk_pixbuf_new (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample,
103                 int width, int height)
104 {
105         guchar *buf;
106         int channels;
107         int rowstride;
108
109         g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, NULL);
110         g_return_val_if_fail (bits_per_sample == 8, NULL);
111         g_return_val_if_fail (width > 0, NULL);
112         g_return_val_if_fail (height > 0, NULL);
113
114         /* Always align rows to 32-bit boundaries */
115
116         channels = has_alpha ? 4 : 3;
117         rowstride = 4 * ((channels * width + 3) / 4);
118
119         buf = malloc (height * rowstride);
120         if (!buf)
121                 return NULL;
122
123         return gdk_pixbuf_new_from_data (buf, colorspace, has_alpha, bits_per_sample,
124                                          width, height, rowstride,
125                                          free_buffer, NULL);
126 }
127
128 /**
129  * gdk_pixbuf_copy:
130  * @pixbuf: A pixbuf.
131  * 
132  * Creates a new #GdkPixbuf with a copy of the information in the specified
133  * @pixbuf.
134  * 
135  * Return value: A newly-created pixbuf with a reference count of 1, or NULL if
136  * not enough memory could be allocated.
137  **/
138 GdkPixbuf *
139 gdk_pixbuf_copy (const GdkPixbuf *pixbuf)
140 {
141         guchar *buf;
142         int size;
143
144         g_return_val_if_fail (pixbuf != NULL, NULL);
145
146         /* Calculate a semi-exact size.  Here we copy with full rowstrides;
147          * maybe we should copy each row individually with the minimum
148          * rowstride?
149          */
150
151         size = ((pixbuf->height - 1) * pixbuf->rowstride +
152                 pixbuf->width * ((pixbuf->n_channels * pixbuf->bits_per_sample + 7) / 8));
153
154         buf = malloc (size * sizeof (guchar));
155         if (!buf)
156                 return NULL;
157
158         memcpy (buf, pixbuf->pixels, size);
159
160         return gdk_pixbuf_new_from_data (buf,
161                                          pixbuf->colorspace, pixbuf->has_alpha,
162                                          pixbuf->bits_per_sample,
163                                          pixbuf->width, pixbuf->height,
164                                          pixbuf->rowstride,
165                                          free_buffer,
166                                          NULL);
167 }
168
169 \f
170
171 /* Accessors */
172
173 /**
174  * gdk_pixbuf_get_colorspace:
175  * @pixbuf: A pixbuf.
176  *
177  * Queries the color space of a pixbuf.
178  *
179  * Return value: Color space.
180  **/
181 GdkColorspace
182 gdk_pixbuf_get_colorspace (const GdkPixbuf *pixbuf)
183 {
184         g_return_val_if_fail (pixbuf != NULL, GDK_COLORSPACE_RGB);
185
186         return pixbuf->colorspace;
187 }
188
189 /**
190  * gdk_pixbuf_get_n_channels:
191  * @pixbuf: A pixbuf.
192  *
193  * Queries the number of channels of a pixbuf.
194  *
195  * Return value: Number of channels.
196  **/
197 int
198 gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf)
199 {
200         g_return_val_if_fail (pixbuf != NULL, -1);
201
202         return pixbuf->n_channels;
203 }
204
205 /**
206  * gdk_pixbuf_get_has_alpha:
207  * @pixbuf: A pixbuf.
208  *
209  * Queries whether a pixbuf has an alpha channel (opacity information).
210  *
211  * Return value: TRUE if it has an alpha channel, FALSE otherwise.
212  **/
213 gboolean
214 gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf)
215 {
216         g_return_val_if_fail (pixbuf != NULL, -1);
217
218         return pixbuf->has_alpha ? TRUE : FALSE;
219 }
220
221 /**
222  * gdk_pixbuf_get_bits_per_sample:
223  * @pixbuf: A pixbuf.
224  *
225  * Queries the number of bits per color sample in a pixbuf.
226  *
227  * Return value: Number of bits per color sample.
228  **/
229 int
230 gdk_pixbuf_get_bits_per_sample (const GdkPixbuf *pixbuf)
231 {
232         g_return_val_if_fail (pixbuf != NULL, -1);
233
234         return pixbuf->bits_per_sample;
235 }
236
237 /**
238  * gdk_pixbuf_get_pixels:
239  * @pixbuf: A pixbuf.
240  *
241  * Queries a pointer to the pixel data of a pixbuf.
242  *
243  * Return value: A pointer to the pixbuf's pixel data.
244  **/
245 guchar *
246 gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf)
247 {
248         g_return_val_if_fail (pixbuf != NULL, NULL);
249
250         return pixbuf->pixels;
251 }
252
253 /**
254  * gdk_pixbuf_get_width:
255  * @pixbuf: A pixbuf.
256  *
257  * Queries the width of a pixbuf.
258  *
259  * Return value: Width in pixels.
260  **/
261 int
262 gdk_pixbuf_get_width (const GdkPixbuf *pixbuf)
263 {
264         g_return_val_if_fail (pixbuf != NULL, -1);
265
266         return pixbuf->width;
267 }
268
269 /**
270  * gdk_pixbuf_get_height:
271  * @pixbuf: A pixbuf.
272  *
273  * Queries the height of a pixbuf.
274  *
275  * Return value: Height in pixels.
276  **/
277 int
278 gdk_pixbuf_get_height (const GdkPixbuf *pixbuf)
279 {
280         g_return_val_if_fail (pixbuf != NULL, -1);
281
282         return pixbuf->height;
283 }
284
285 /**
286  * gdk_pixbuf_get_rowstride:
287  * @pixbuf: A pixbuf.
288  *
289  * Queries the rowstride of a pixbuf, which is the number of bytes between rows.
290  *
291  * Return value: Number of bytes between rows.
292  **/
293 int
294 gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf)
295 {
296         g_return_val_if_fail (pixbuf != NULL, -1);
297
298         return pixbuf->rowstride;
299 }
300
301 \f
302
303 /* General initialization hooks */
304 const guint gdk_pixbuf_major_version = GDK_PIXBUF_MAJOR;
305 const guint gdk_pixbuf_minor_version = GDK_PIXBUF_MINOR;
306 const guint gdk_pixbuf_micro_version = GDK_PIXBUF_MICRO;
307
308 const char *gdk_pixbuf_version = GDK_PIXBUF_VERSION;
309
310 void
311 gdk_pixbuf_preinit (gpointer app, gpointer modinfo)
312 {
313 }
314
315 void
316 gdk_pixbuf_postinit (gpointer app, gpointer modinfo)
317 {
318 }