]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf-util.c
848aadd141d45304b86f007f1ec7a7c7513d61d1
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf-util.c
1 /* GdkPixbuf library - Utilities and miscellaneous convenience functions
2  *
3  * Copyright (C) 1999 The Free Software Foundation
4  *
5  * Authors: Federico Mena-Quintero <federico@gimp.org>
6  *          Cody Russell  <bratsche@dfw.net>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <config.h>
25 #include "gdk-pixbuf-private.h"
26
27 \f
28
29 /**
30  * gdk_pixbuf_add_alpha:
31  * @pixbuf: A pixbuf.
32  * @substitute_color: Whether to substitute a color for zero opacity.  If this
33  * is #FALSE, then the (@r, @g, @b) arguments will be ignored.
34  * @r: Red value to substitute.
35  * @g: Green value to substitute.
36  * @b: Blue value to substitute.
37  *
38  * Takes an existing pixbuf and adds an alpha channel to it.  If the original
39  * pixbuf already had alpha information, then the contents of the new pixbuf are
40  * exactly the same as the original's.  Otherwise, the new pixbuf will have all
41  * pixels with full opacity if @substitute_color is #FALSE.  If
42  * @substitute_color is #TRUE, then the color specified by (@r, @g, @b) will be
43  * substituted for zero opacity.
44  *
45  * Return value: A newly-created pixbuf with a reference count of 1.
46  **/
47 GdkPixbuf *
48 gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf,
49                       gboolean substitute_color, guchar r, guchar g, guchar b)
50 {
51         GdkPixbuf *new_pixbuf;
52         int x, y;
53
54         g_return_val_if_fail (pixbuf != NULL, NULL);
55         g_return_val_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB, NULL);
56         g_return_val_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4, NULL);
57         g_return_val_if_fail (pixbuf->bits_per_sample == 8, NULL);
58
59         if (pixbuf->has_alpha) {
60                 new_pixbuf = gdk_pixbuf_copy (pixbuf);
61                 if (!new_pixbuf)
62                         return NULL;
63
64                 return new_pixbuf;
65         }
66
67         new_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, pixbuf->width, pixbuf->height);
68         if (!new_pixbuf)
69                 return NULL;
70
71         for (y = 0; y < pixbuf->height; y++) {
72                 guchar *src, *dest;
73                 guchar tr, tg, tb;
74
75                 src = pixbuf->pixels + y * pixbuf->rowstride;
76                 dest = new_pixbuf->pixels + y * new_pixbuf->rowstride;
77
78                 for (x = 0; x < pixbuf->width; x++) {
79                         tr = *dest++ = *src++;
80                         tg = *dest++ = *src++;
81                         tb = *dest++ = *src++;
82
83                         if (substitute_color && tr == r && tg == g && tb == b)
84                                 *dest++ = 0;
85                         else
86                                 *dest++ = 255;
87                 }
88         }
89
90         return new_pixbuf;
91 }
92
93 /**
94  * gdk_pixbuf_copy_area:
95  * @src_pixbuf: Source pixbuf.
96  * @src_x: Source X coordinate within @src_pixbuf.
97  * @src_y: Source Y coordinate within @src_pixbuf.
98  * @width: Width of the area to copy.
99  * @height: Height of the area to copy.
100  * @dest_pixbuf: Destination pixbuf.
101  * @dest_x: X coordinate within @dest_pixbuf.
102  * @dest_y: Y coordinate within @dest_pixbuf.
103  *
104  * Copies a rectangular area from @src_pixbuf to @dest_pixbuf.  Conversion of
105  * pixbuf formats is done automatically.
106  **/
107 void
108 gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf,
109                       int src_x, int src_y,
110                       int width, int height,
111                       GdkPixbuf *dest_pixbuf,
112                       int dest_x, int dest_y)
113 {
114         g_return_if_fail (src_pixbuf != NULL);
115         g_return_if_fail (dest_pixbuf != NULL);
116
117         g_return_if_fail (src_x >= 0 && src_x + width <= src_pixbuf->width);
118         g_return_if_fail (src_y >= 0 && src_y + height <= src_pixbuf->height);
119
120         g_return_if_fail (dest_x >= 0 && dest_x + width <= dest_pixbuf->width);
121         g_return_if_fail (dest_y >= 0 && dest_y + height <= dest_pixbuf->height);
122
123         /* This will perform format conversions automatically */
124
125         gdk_pixbuf_scale (src_pixbuf,
126                           dest_pixbuf,
127                           dest_x, dest_y,
128                           width, height,
129                           (double) (dest_x - src_x),
130                           (double) (dest_y - src_y),
131                           1.0, 1.0,
132                           GDK_INTERP_NEAREST);
133 }