]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/test-gdk-pixbuf.c
marshaller fixes.
[~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 #include <glib-object.h>
29
30 \f
31
32 static void
33 store_pixel (guchar *pixels,
34              int pixel,
35              gboolean alpha)
36 {
37         if (alpha) {
38                 pixels[0] = pixel >> 24;
39                 pixels[1] = pixel >> 16;
40                 pixels[2] = pixel >> 8;
41                 pixels[3] = pixel;
42         } else {
43                 pixels[0] = pixel >> 16;
44                 pixels[1] = pixel >> 8;
45                 pixels[2] = pixel;
46         }
47 }
48
49 static void
50 fill_with_pixel (GdkPixbuf *pixbuf,
51                  int pixel)
52 {
53         int x, y;
54         
55         for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++) {
56                 for (y = 0; y < gdk_pixbuf_get_height (pixbuf); y++) {
57                         store_pixel (gdk_pixbuf_get_pixels (pixbuf)
58                                      + y * gdk_pixbuf_get_rowstride (pixbuf)
59                                      + x * gdk_pixbuf_get_n_channels (pixbuf),
60                                      pixel,
61                                      gdk_pixbuf_get_has_alpha (pixbuf));
62                 }
63         }
64 }
65
66 static int
67 load_pixel (const guchar *pixels,
68             gboolean alpha)
69 {
70         if (alpha)
71                 return (((((pixels[0] << 8) | pixels[1]) << 8) | pixels[2]) << 8) | pixels[3];
72         else
73                 return (((pixels[0] << 8) | pixels[1]) << 8) | pixels[2];
74 }
75
76 static gboolean
77 simple_composite_test_one (GdkInterpType type,
78                            int source_pixel,
79                            gboolean source_alpha,
80                            int destination_pixel,
81                            gboolean destination_alpha,
82                            int expected_result)
83 {
84         GdkPixbuf *source_pixbuf;
85         GdkPixbuf *destination_pixbuf;
86         int result_pixel;
87
88         source_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, source_alpha, 8, 32, 32);
89         destination_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, destination_alpha, 8, 32, 32);
90         
91         fill_with_pixel (source_pixbuf, source_pixel);
92         fill_with_pixel (destination_pixbuf, destination_pixel);
93
94         gdk_pixbuf_composite (source_pixbuf, destination_pixbuf,
95                               0, 0, 32, 32, 0, 0, 1, 1, type, 0xFF);
96
97         result_pixel = load_pixel (gdk_pixbuf_get_pixels (destination_pixbuf)
98                                    + 16 * gdk_pixbuf_get_rowstride (destination_pixbuf)
99                                    + 16 * gdk_pixbuf_get_n_channels (destination_pixbuf),
100                                    destination_alpha);
101           
102         gdk_pixbuf_unref (source_pixbuf);
103         gdk_pixbuf_unref (destination_pixbuf);
104
105         if (result_pixel != expected_result) {
106                 char *interpolation_type, *source_string, *destination_string, *result_string, *expected_string;
107
108                 switch (type) {
109                 case GDK_INTERP_NEAREST:  interpolation_type = "GDK_INTERP_NEAREST"; break;
110                 case GDK_INTERP_TILES:    interpolation_type = "GDK_INTERP_TILES"; break;
111                 case GDK_INTERP_BILINEAR: interpolation_type = "GDK_INTERP_BILINEAR"; break;
112                 case GDK_INTERP_HYPER:    interpolation_type = "GDK_INTERP_HYPER"; break;
113                 default:                  interpolation_type = "???";
114                 }
115
116                 if (source_alpha) {
117                         source_string = g_strdup_printf ("0x%08X", source_pixel);
118                 } else {
119                         source_string = g_strdup_printf ("0x%06X", source_pixel);
120                 }
121
122                 if (destination_alpha) {
123                         destination_string = g_strdup_printf ("0x%08X", destination_pixel);
124                         result_string = g_strdup_printf ("0x%08X", result_pixel);
125                         expected_string = g_strdup_printf ("0x%08X", expected_result);
126                 } else {
127                         destination_string = g_strdup_printf ("0x%06X", destination_pixel);
128                         result_string = g_strdup_printf ("0x%06X", result_pixel);
129                         expected_string = g_strdup_printf ("0x%06X", expected_result);
130                 }
131
132                 g_message ("simple_composite_test (%s): composite %s on top of %s, expected %s, got %s",
133                            interpolation_type,
134                            source_string, destination_string, expected_string, result_string);
135                 return FALSE;
136         }
137
138         return TRUE;
139 }
140
141 static gboolean
142 simple_composite_test_one_type (GdkInterpType type)
143 {
144         gboolean success;
145
146         success = TRUE;
147
148         /* There are only a few trivial cases in here.
149          * But these were enough to expose the problems in the old composite code.
150          */
151
152         /* Non-alpha into non-alpha. */
153         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x000000, FALSE, 0x000000);
154         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFFFFFF, FALSE, 0x000000);
155         success &= simple_composite_test_one (type, 0xFF0000, FALSE, 0x000000, FALSE, 0xFF0000);
156         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0x000000, FALSE, 0x00FF00);
157         success &= simple_composite_test_one (type, 0x0000FF, FALSE, 0x000000, FALSE, 0x0000FF);
158         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFF0000, FALSE, 0x000000);
159         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x00FF00, FALSE, 0x000000);
160         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x0000FF, FALSE, 0x000000);
161         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0xFFFFFF, FALSE, 0x00FF00);
162         success &= simple_composite_test_one (type, 0xFFFFFF, FALSE, 0xFFFFFF, FALSE, 0xFFFFFF);
163
164         /* Alpha into non-alpha. */
165         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x000000, FALSE, 0x000000);
166         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFFFFFF, FALSE, 0xFFFFFF);
167         success &= simple_composite_test_one (type, 0x0000007F, TRUE, 0xFFFFFF, FALSE, 0x808080);
168         success &= simple_composite_test_one (type, 0x00000080, TRUE, 0xFFFFFF, FALSE, 0x7F7F7F);
169         success &= simple_composite_test_one (type, 0x000000FF, TRUE, 0xFFFFFF, FALSE, 0x000000);
170         success &= simple_composite_test_one (type, 0x000000FF, TRUE, 0xFFFFFF, FALSE, 0x000000);
171         success &= simple_composite_test_one (type, 0xFF0000FF, TRUE, 0x000000, FALSE, 0xFF0000);
172         success &= simple_composite_test_one (type, 0x00FF00FF, TRUE, 0x000000, FALSE, 0x00FF00);
173         success &= simple_composite_test_one (type, 0x0000FFFF, TRUE, 0x000000, FALSE, 0x0000FF);
174         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFF0000, FALSE, 0xFF0000);
175         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00FF00, FALSE, 0x00FF00);
176         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x0000FF, FALSE, 0x0000FF);
177         success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF, FALSE, 0x7FFF7F);
178         success &= simple_composite_test_one (type, 0xFFFFFFFF, TRUE, 0xFFFFFF, FALSE, 0xFFFFFF);
179
180         /* Non-alpha into alpha. */
181         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x00000000, TRUE, 0x000000FF);
182         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFFFFFFFF, TRUE, 0x000000FF);
183         success &= simple_composite_test_one (type, 0xFF0000, FALSE, 0x00000000, TRUE, 0xFF0000FF);
184         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0x00000000, TRUE, 0x00FF00FF);
185         success &= simple_composite_test_one (type, 0x0000FF, FALSE, 0x00000000, TRUE, 0x0000FFFF);
186         success &= simple_composite_test_one (type, 0x000000, FALSE, 0xFF0000FF, TRUE, 0x000000FF);
187         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x00FF00FF, TRUE, 0x000000FF);
188         success &= simple_composite_test_one (type, 0x000000, FALSE, 0x0000FFFF, TRUE, 0x000000FF);
189         success &= simple_composite_test_one (type, 0x00FF00, FALSE, 0xFFFFFF00, TRUE, 0x00FF00FF);
190         success &= simple_composite_test_one (type, 0xFFFFFF, FALSE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
191
192         /* Alpha into alpha. */
193         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00000000, TRUE, 0x00000000);
194         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
195         success &= simple_composite_test_one (type, 0x0000007F, TRUE, 0xFFFFFFFF, TRUE, 0x808080FF);
196         success &= simple_composite_test_one (type, 0x00000080, TRUE, 0xFFFFFFFF, TRUE, 0x7F7F7FFF);
197         success &= simple_composite_test_one (type, 0x000000FF, TRUE, 0xFFFFFFFF, TRUE, 0x000000FF);
198         success &= simple_composite_test_one (type, 0xFF0000FF, TRUE, 0x00000000, TRUE, 0xFF0000FF);
199         success &= simple_composite_test_one (type, 0x00FF00FF, TRUE, 0x00000000, TRUE, 0x00FF00FF);
200         success &= simple_composite_test_one (type, 0x0000FFFF, TRUE, 0x00000000, TRUE, 0x0000FFFF);
201         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0xFF0000FF, TRUE, 0xFF0000FF);
202         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x00FF00FF, TRUE, 0x00FF00FF);
203         success &= simple_composite_test_one (type, 0x00000000, TRUE, 0x0000FFFF, TRUE, 0x0000FFFF);
204         success &= simple_composite_test_one (type, 0x00FF0080, TRUE, 0xFFFFFF00, TRUE, 0x00FF0080);
205         success &= simple_composite_test_one (type, 0xFF000080, TRUE, 0x00FF0040, TRUE, 0xCC32009F);
206         success &= simple_composite_test_one (type, 0xFFFFFFFF, TRUE, 0xFFFFFFFF, TRUE, 0xFFFFFFFF);
207
208         return success;
209 }
210
211 static gboolean
212 simple_composite_test (void)
213 {
214         gboolean success;
215
216         success = TRUE;
217
218         success &= simple_composite_test_one_type (GDK_INTERP_NEAREST);
219         success &= simple_composite_test_one_type (GDK_INTERP_TILES);
220         success &= simple_composite_test_one_type (GDK_INTERP_BILINEAR);
221         success &= simple_composite_test_one_type (GDK_INTERP_HYPER);
222
223         return success;
224 }
225
226 int
227 main (int argc, char **argv)
228 {
229         int result;
230
231         result = EXIT_SUCCESS;
232
233         g_type_init (G_TYPE_DEBUG_NONE);
234         
235         /* Run some tests. */
236         if (!simple_composite_test ()) {
237                 result = EXIT_FAILURE;
238         }
239
240         return result;
241 }