]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf-util.c
By order of jrb: const patch for various bits, io-gif.c fixup for
[~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 Library 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  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library 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.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 (GdkPixbuf *pixbuf, gboolean substitute_color, guchar r, guchar g, guchar b)
49 {
50         ArtPixBuf *apb;
51         ArtPixBuf *new_apb;
52         GdkPixbuf *new_pixbuf;
53         int x, y;
54
55         g_return_val_if_fail (pixbuf != NULL, NULL);
56
57         apb = pixbuf->art_pixbuf;
58         g_return_val_if_fail (apb->format == ART_PIX_RGB, NULL);
59         g_return_val_if_fail (apb->n_channels == 3 || apb->n_channels == 4, NULL);
60         g_return_val_if_fail (apb->bits_per_sample == 8, NULL);
61
62         if (apb->has_alpha) {
63                 new_apb = art_pixbuf_duplicate (apb);
64                 if (!new_apb)
65                         return NULL;
66
67                 return gdk_pixbuf_new_from_art_pixbuf (new_apb);
68         }
69
70         new_pixbuf = gdk_pixbuf_new (ART_PIX_RGB, TRUE, 8, apb->width, apb->height);
71         if (!new_pixbuf)
72                 return NULL;
73
74         new_apb = new_pixbuf->art_pixbuf;
75
76         for (y = 0; y < apb->height; y++) {
77                 guchar *src, *dest;
78                 guchar tr, tg, tb;
79
80                 src = apb->pixels + y * apb->rowstride;
81                 dest = new_apb->pixels + y * new_apb->rowstride;
82
83                 for (x = 0; x < apb->width; x++) {
84                         tr = *dest++ = *src++;
85                         tg = *dest++ = *src++;
86                         tb = *dest++ = *src++;
87
88                         if (substitute_color && tr == r && tg == g && tb == b)
89                                 *dest++ = 0;
90                         else
91                                 *dest++ = 255;
92                 }
93         }
94
95         return new_pixbuf;
96 }
97
98 /**
99  * gdk_pixbuf_copy_area:
100  * @src_pixbuf: Source pixbuf.
101  * @src_x: Source X coordinate within @src_pixbuf.
102  * @src_y: Source Y coordinate within @src_pixbuf.
103  * @width: Width of the area to copy.
104  * @height: Height of the area to copy.
105  * @dest_pixbuf: Destination pixbuf.
106  * @dest_x: X coordinate within @dest_pixbuf.
107  * @dest_y: Y coordinate within @dest_pixbuf.
108  *
109  * Copies a rectangular area from @src_pixbuf to @dest_pixbuf.  Conversion of
110  * pixbuf formats is done automatically.
111  **/
112 void
113 gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf,
114                       int src_x, int src_y,
115                       int width, int height,
116                       GdkPixbuf *dest_pixbuf,
117                       int dest_x, int dest_y)
118 {
119         const ArtPixBuf *src_apb;
120         ArtPixBuf       *dest_apb;
121
122         g_return_if_fail (src_pixbuf != NULL);
123         g_return_if_fail (dest_pixbuf != NULL);
124
125         src_apb = src_pixbuf->art_pixbuf;
126         dest_apb = dest_pixbuf->art_pixbuf;
127
128         g_return_if_fail (src_x >= 0 && src_x + width <= src_apb->width);
129         g_return_if_fail (src_y >= 0 && src_y + height <= src_apb->height);
130
131         g_return_if_fail (dest_x >= 0 && dest_x + width <= dest_apb->width);
132         g_return_if_fail (dest_y >= 0 && dest_y + height <= dest_apb->height);
133
134         /* This will perform format conversions automatically */
135
136         gdk_pixbuf_scale (src_pixbuf,
137                           dest_pixbuf,
138                           dest_x, dest_y,
139                           width, height,
140                           (double) (dest_x - src_x),
141                           (double) (dest_y - src_y),
142                           1.0, 1.0,
143                           ART_FILTER_NEAREST);
144 }