]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/test-gdk-pixbuf.c
Convert GdkPixbuf to GObject, leaving it opaque (i.e. derivation is not
[~andy/gtk] / gdk-pixbuf / test-gdk-pixbuf.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /* GdkPixbuf library - test program
4  *
5  * Copyright (C) 1999 The Free Software Foundation
6  *
7  * Author: Federico Mena-Quintero <federico@gimp.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program 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
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  */
23
24 #include <config.h>
25
26 #include <stdlib.h>
27 #include "gdk-pixbuf.h"
28
29 \f
30
31 static void
32 store_pixel (guchar *pixels,
33              int pixel,
34              gboolean alpha)
35 {
36         if (alpha) {
37                 pixels[0] = pixel >> 24;
38                 pixels[1] = pixel >> 16;
39                 pixels[2] = pixel >> 8;
40                 pixels[3] = pixel;
41         } else {
42                 pixels[0] = pixel >> 16;
43                 pixels[1] = pixel >> 8;
44                 pixels[2] = pixel;
45         }
46 }
47
48 static void
49 fill_with_pixel (GdkPixbuf *pixbuf,
50                  int pixel)
51 {
52         int x, y;
53         
54         for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++) {
55                 for (y = 0; y < gdk_pixbuf_get_height (pixbuf); y++) {
56                         store_pixel (gdk_pixbuf_get_pixels (pixbuf)
57                                      + y * gdk_pixbuf_get_rowstride (pixbuf)
58                                      + x * gdk_pixbuf_get_n_channels (pixbuf),
59                                      pixel,
60                                      gdk_pixbuf_get_has_alpha (pixbuf));
61                 }
62         }
63 }
64
65 static int
66 load_pixel (const guchar *pixels,
67             gboolean alpha)
68 {
69         if (alpha)
70                 return (((((pixels[0] << 8) | pixels[1]) << 8) | pixels[2]) << 8) | pixels[3];
71         else
72                 return (((pixels[0] << 8) | pixels[1]) << 8) | pixels[2];
73 }
74
75 static gboolean
76 simple_composite_test_one (GdkInterpType type,
77                            int source_pixel,
78                            gboolean source_alpha,
79                            int destination_pixel,
80                            gboolean destination_alpha,
81                            int expected_result)
82 {
83         GdkPixbuf *source_pixbuf;
84         GdkPixbuf *destination_pixbuf;
85         int result_pixel;
86
87         source_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, source_alpha, 8, 32, 32);
88         destination_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, destination_alpha, 8, 32, 32);
89         
90         fill_with_pixel (source_pixbuf, source_pixel);
91         fill_with_pixel (destination_pixbuf, destination_pixel);
92
93         gdk_pixbuf_composite (source_pixbuf, destination_pixbuf,
94                               0, 0, 32, 32, 0, 0, 1, 1, type, 0xFF);
95
96         result_pixel = load_pixel (gdk_pixbuf_get_pixels (destination_pixbuf)
97                                    + 16 * gdk_pixbuf_get_rowstride (destination_pixbuf)
98                                    + 16 * gdk_pixbuf_get_n_channels (destination_pixbuf),
99                                    destination_alpha);
100           
101         gdk_pixbuf_unref (source_pixbuf);
102         gdk_pixbuf_unref (destination_pixbuf);
103
104         if (result_pixel != expected_result) {
105                 char *interpolation_type, *source_string, *destination_string, *result_string, *expected_string;
106
107                 switch (type) {
108                 case GDK_INTERP_NEAREST:  interpolation_type = "GDK_INTERP_NEAREST"; break;
109                 case GDK_INTERP_TILES:    interpolation_type = "GDK_INTERP_TILES"; break;
110                 case GDK_INTERP_BILINEAR: interpolation_type = "GDK_INTERP_BILINEAR"; break;
111                 case GDK_INTERP_HYPER:    interpolation_type = "GDK_INTERP_HYPER"; break;
112                 default:                  interpolation_type = "???";
113                 }
114
115                 if (source_alpha) {
116                         source_string = g_strdup_printf ("0x%08X", source_pixel);
117                 } else {
118                         source_string = g_strdup_printf ("0x%06X", source_pixel);
119                 }
120
121                 if (destination_alpha) {
122                         destination_string = g_strdup_printf ("0x%08X", destination_pixel);
123                         result_string = g_strdup_printf ("0x%08X", result_pixel);
124                         expected_string = g_strdup_printf ("0x%08X", expected_result);
125                 } else {
126                         destination_string = g_strdup_printf ("0x%06X", destination_pixel);
127                         result_string = g_strdup_printf ("0x%06X", result_pixel);
128                         expected_string = g_strdup_printf ("0x%06X", expected_result);
129                 }
130
131                 g_message ("simple_composite_test (%s): composite %s on top of %s, expected %s, got %s",
132                            interpolation_type,
133                            source_string, destination_string, expected_string, result_string);
134                 return FALSE;
135         }
136
137         return TRUE;
138 }
139
140 static gboolean
141 simple_composite_test_one_type (GdkInterpType type)
142 {
143         gboolean success;
144
145         success = TRUE;
146
147         /* There are only a few trivial cases in here.
148          * But these were enough to expose the problems in the old composite code.
149          */
150
151         /* Non-alpha into non-alpha. */
152         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x000000, FALSE, 0x000000);
153         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFFFFFF, FALSE, 0x000000);
154         success &= simple_composite_test_one (type, 0xFF0000, FALSE, 0x000000, FALSE, 0xFF0000);
155         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0x000000, FALSE, 0x00FF00);
156         success &= simple_composite_test_one (type, 0x0000FF, FALSE, 0x000000, FALSE, 0x0000FF);
157         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFF0000, FALSE, 0x000000);
158         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x00FF00, FALSE, 0x000000);
159         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x0000FF, FALSE, 0x000000);
160         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0xFFFFFF, FALSE, 0x00FF00);
161         success &= simple_composite_test_one (type, 0xFFFFFF, FALSE, 0xFFFFFF, FALSE, 0xFFFFFF);
162
163         /* Alpha into non-alpha. */
164         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x000000, FALSE, 0x000000);
165         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFFFFFF, FALSE, 0xFFFFFF);
166         success &= simple_composite_test_one (type, 0x0000007F, TRUE, 0xFFFFFF, FALSE, 0x808080);
167         success &= simple_composite_test_one (type, 0x00000080, TRUE, 0xFFFFFF, FALSE, 0x7F7F7F);
168         success &= simple_composite_test_one (type, 0x000000FF, TRUE, 0xFFFFFF, FALSE, 0x000000);
169         success &= simple_composite_test_one (type, 0x000000FF, TRUE, 0xFFFFFF, FALSE, 0x000000);
170         success &= simple_composite_test_one (type, 0xFF0000FF, TRUE, 0x000000, FALSE, 0xFF0000);
171         success &= simple_composite_test_one (type, 0x00FF00FF, TRUE, 0x000000, FALSE, 0x00FF00);
172         success &= simple_composite_test_one (type, 0x0000FFFF, TRUE, 0x000000, FALSE, 0x0000FF);
173         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFF0000, FALSE, 0xFF0000);
174         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00FF00, FALSE, 0x00FF00);
175         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x0000FF, FALSE, 0x0000FF);
176         success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF, FALSE, 0x7FFF7F);
177         success &= simple_composite_test_one (type, 0xFFFFFFFF, TRUE, 0xFFFFFF, FALSE, 0xFFFFFF);
178
179         /* Non-alpha into alpha. */
180         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x00000000, TRUE, 0x000000FF);
181         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFFFFFFFF, TRUE, 0x000000FF);
182         success &= simple_composite_test_one (type, 0xFF0000, FALSE, 0x00000000, TRUE, 0xFF0000FF);
183         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0x00000000, TRUE, 0x00FF00FF);
184         success &= simple_composite_test_one (type, 0x0000FF, FALSE, 0x00000000, TRUE, 0x0000FFFF);
185         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFF0000FF, TRUE, 0x000000FF);
186         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x00FF00FF, TRUE, 0x000000FF);
187         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x0000FFFF, TRUE, 0x000000FF);
188         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0xFFFFFF00, TRUE, 0x00FF00FF);
189         success &= simple_composite_test_one (type, 0xFFFFFF, FALSE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
190
191         /* Alpha into alpha. */
192         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00000000, TRUE, 0x00000000);
193         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
194         success &= simple_composite_test_one (type, 0x0000007F, TRUE, 0xFFFFFFFF, TRUE, 0x808080FF);
195         success &= simple_composite_test_one (type, 0x00000080, TRUE, 0xFFFFFFFF, TRUE, 0x7F7F7FFF);
196         success &= simple_composite_test_one (type, 0x000000FF, TRUE, 0xFFFFFFFF, TRUE, 0x000000FF);
197         success &= simple_composite_test_one (type, 0xFF0000FF, TRUE, 0x00000000, TRUE, 0xFF0000FF);
198         success &= simple_composite_test_one (type, 0x00FF00FF, TRUE, 0x00000000, TRUE, 0x00FF00FF);
199         success &= simple_composite_test_one (type, 0x0000FFFF, TRUE, 0x00000000, TRUE, 0x0000FFFF);
200         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFF0000FF, TRUE, 0xFF0000FF);
201         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00FF00FF, TRUE, 0x00FF00FF);
202         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x0000FFFF, TRUE, 0x0000FFFF);
203         success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF00, TRUE, 0x00FF0080);
204         success &= simple_composite_test_one (type, 0xFF000080, TRUE, 0x00FF0040, TRUE, 0xCC32009F);
205         success &= simple_composite_test_one (type, 0xFFFFFFFF, TRUE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
206
207         return success;
208 }
209
210 static gboolean
211 simple_composite_test (void)
212 {
213         gboolean success;
214
215         success = TRUE;
216
217         success &= simple_composite_test_one_type (GDK_INTERP_NEAREST);
218         success &= simple_composite_test_one_type (GDK_INTERP_TILES);
219         success &= simple_composite_test_one_type (GDK_INTERP_BILINEAR);
220         success &= simple_composite_test_one_type (GDK_INTERP_HYPER);
221
222         return success;
223 }
224
225 int
226 main (int argc, char **argv)
227 {
228         int result;
229
230         result = EXIT_SUCCESS;
231
232         gdk_pixbuf_init ();
233         
234         /* Run some tests. */
235         if (!simple_composite_test ()) {
236                 result = EXIT_FAILURE;
237         }
238
239         return result;
240 }