pidgin/pidgingdkpixbuf.c

changeset 39568
f4714f1de6d0
child 39571
b88f466a4a4d
equal deleted inserted replaced
39567:34043d9fcdf9 39568:f4714f1de6d0
1 /* pidgin
2 *
3 * Pidgin is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
20 */
21
22 #include "pidgin/pidgingdkpixbuf.h"
23
24 GdkPixbuf *
25 pidgin_gdk_pixbuf_new_from_image(PurpleImage *image, GError **error) {
26 GdkPixbufLoader *loader = NULL;
27 GdkPixbuf *pixbuf = NULL;
28 GBytes *data = NULL;
29 gboolean success = FALSE;
30
31 g_return_val_if_fail(PURPLE_IS_IMAGE(image), NULL);
32
33 data = purple_image_get_contents(image);
34 success = gdk_pixbuf_loader_write_bytes(loader, data, error);
35 g_bytes_unref(data);
36
37 if(success) {
38 if(error != NULL && *error != NULL) {
39 g_object_unref(G_OBJECT(loader));
40
41 return NULL;
42 }
43
44 if(gdk_pixbuf_loader_close(loader, error)) {
45 pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
46 if(pixbuf != NULL) {
47 pixbuf = g_object_ref(pixbuf);
48 }
49 }
50
51 g_object_unref(G_OBJECT(loader));
52 }
53
54 return pixbuf;
55 }
56
57 void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf) {
58 gint width, height, rowstride;
59 guchar *pixels;
60
61 if (!gdk_pixbuf_get_has_alpha(pixbuf)) {
62 return;
63 }
64
65 width = gdk_pixbuf_get_width(pixbuf);
66 height = gdk_pixbuf_get_height(pixbuf);
67 rowstride = gdk_pixbuf_get_rowstride(pixbuf);
68 pixels = gdk_pixbuf_get_pixels(pixbuf);
69
70 if (width < 6 || height < 6)
71 return;
72
73 /* The following code will conver the alpha of the pixel data in all
74 * corners to look something like the following diagram.
75 *
76 * 00 80 c0 FF FF c0 80 00
77 * 80 FF FF FF FF FF FF 80
78 * c0 FF FF FF FF FF FF c0
79 * FF FF FF FF FF FF FF FF
80 * FF FF FF FF FF FF FF FF
81 * c0 FF FF FF FF FF FF c0
82 * 80 FF FF FF FF FF FF 80
83 * 00 80 c0 FF FF c0 80 00
84 */
85
86 /* Top left */
87 pixels[3] = 0;
88 pixels[7] = 0x80;
89 pixels[11] = 0xC0;
90 pixels[rowstride + 3] = 0x80;
91 pixels[rowstride * 2 + 3] = 0xC0;
92
93 /* Top right */
94 pixels[width * 4 - 1] = 0;
95 pixels[width * 4 - 5] = 0x80;
96 pixels[width * 4 - 9] = 0xC0;
97 pixels[rowstride + (width * 4) - 1] = 0x80;
98 pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0;
99
100 /* Bottom left */
101 pixels[(height - 1) * rowstride + 3] = 0;
102 pixels[(height - 1) * rowstride + 7] = 0x80;
103 pixels[(height - 1) * rowstride + 11] = 0xC0;
104 pixels[(height - 2) * rowstride + 3] = 0x80;
105 pixels[(height - 3) * rowstride + 3] = 0xC0;
106
107 /* Bottom right */
108 pixels[height * rowstride - 1] = 0;
109 pixels[(height - 1) * rowstride - 1] = 0x80;
110 pixels[(height - 2) * rowstride - 1] = 0xC0;
111 pixels[height * rowstride - 5] = 0x80;
112 pixels[height * rowstride - 9] = 0xC0;
113 }
114
115 gboolean
116 pidgin_gdk_pixbuf_is_opaque(GdkPixbuf *pixbuf) {
117 gint height, rowstride, i;
118 guchar *pixels;
119 guchar *row;
120
121 if (!gdk_pixbuf_get_has_alpha(pixbuf))
122 return TRUE;
123
124 height = gdk_pixbuf_get_height (pixbuf);
125 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
126 pixels = gdk_pixbuf_get_pixels (pixbuf);
127
128 /* check the top row */
129 row = pixels;
130 for (i = 3; i < rowstride; i+=4) {
131 if (row[i] < 0xfe)
132 return FALSE;
133 }
134
135 /* check the left and right sides */
136 for (i = 1; i < height - 1; i++) {
137 row = pixels + (i * rowstride);
138 if (row[3] < 0xfe || row[rowstride - 1] < 0xfe) {
139 return FALSE;
140 }
141 }
142
143 /* check the bottom */
144 row = pixels + ((height - 1) * rowstride);
145 for (i = 3; i < rowstride; i += 4) {
146 if (row[i] < 0xfe)
147 return FALSE;
148 }
149
150 return TRUE;
151 }
152

mercurial