1/* -*- Mode: C; c-basic-offset: 2; -*- */
2/* GdkPixbuf library - test loaders
3 *
4 * Copyright (C) 2015 Red Hat, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Benjamin Otte
20 */
21
22#include "config.h"
23
24#include <gdk-pixbuf/gdk-pixbuf.h>
25
26#include "test-common.h"
27
28/* As defined in gdk-pixbuf-private.h */
29#define DEFAULT_FILL_COLOR 0x979899ff
30
31static void
32loader_size_prepared (GdkPixbufLoader *loader,
33 int w,
34 int h,
35 GdkPixbuf **pixbuf)
36{
37 g_assert (*pixbuf == NULL);
38
39 *pixbuf = gdk_pixbuf_new (colorspace: GDK_COLORSPACE_RGB, FALSE, bits_per_sample: 8, width: w, height: h);
40 g_assert (*pixbuf != NULL);
41 /* likely!! */
42 gdk_pixbuf_fill (pixbuf: *pixbuf, DEFAULT_FILL_COLOR);
43}
44
45static void
46loader_area_prepared (GdkPixbufLoader *loader,
47 GdkPixbuf **pixbuf)
48{
49 g_assert (*pixbuf != NULL);
50
51 if (gdk_pixbuf_get_has_alpha (pixbuf: gdk_pixbuf_loader_get_pixbuf (loader)))
52 {
53 GdkPixbuf *alpha = gdk_pixbuf_add_alpha (pixbuf: *pixbuf, FALSE, r: 0, g: 0, b: 0);
54
55 g_object_unref (object: *pixbuf);
56 *pixbuf = alpha;
57 }
58
59 g_assert (*pixbuf != NULL);
60}
61
62static void
63loader_area_updated (GdkPixbufLoader *loader,
64 int x,
65 int y,
66 int w,
67 int h,
68 GdkPixbuf **pixbuf)
69{
70 gdk_pixbuf_copy_area (src_pixbuf: gdk_pixbuf_loader_get_pixbuf (loader),
71 src_x: x, src_y: y,
72 width: w, height: h,
73 dest_pixbuf: *pixbuf,
74 dest_x: x, dest_y: y);
75}
76
77static GFile *
78make_ref_file (GFile *file)
79{
80 char *uri, *ref_uri;
81 GFile *result;
82
83 uri = g_file_get_uri (file);
84 ref_uri = g_strconcat (string1: uri, ".ref.png", NULL);
85
86 result = g_file_new_for_uri (uri: ref_uri);
87
88#ifdef G_OS_WIN32
89 /* XXX: The .ref.png files are symlinks and on Windows git will create
90 * files containing the symlink target instead of symlinks. */
91 {
92 char *contents;
93 gboolean success;
94
95 success = g_file_load_contents (result, NULL, &contents, NULL, NULL, NULL);
96 if (success)
97 {
98 if (g_str_is_ascii (contents))
99 {
100 GFile *parent = g_file_get_parent (result);
101 g_object_unref (result);
102 result = g_file_get_child (parent, contents);
103 g_object_unref (parent);
104 }
105 g_free (contents);
106 }
107 }
108#endif
109
110 g_free (mem: ref_uri);
111 g_free (mem: uri);
112
113 return result;
114}
115
116static gboolean
117is_not_ref_image (GFile *file)
118{
119 char *uri;
120 gboolean result;
121
122 uri = g_file_get_uri (file);
123
124 result = !g_str_has_suffix (str: uri, suffix: ".ref.png");
125
126 g_free (mem: uri);
127
128 return result;
129}
130
131static void
132test_reftest (gconstpointer data)
133{
134 GdkPixbufLoader *loader;
135 GdkPixbuf *reference, *loaded = NULL;
136 GError *error = NULL;
137 GFile *file, *ref_file;
138 GInputStream *stream;
139 guchar *contents;
140 gsize i, contents_length;
141 char *filename;
142 gboolean success;
143
144 file = G_FILE (data);
145 if (!file_supported (file))
146 {
147 g_test_skip (msg: "format not supported");
148 return;
149 }
150
151 ref_file = make_ref_file (file);
152 if (!file_supported (file: ref_file))
153 {
154 g_test_skip (msg: "format not supported for reference file");
155 return;
156 }
157
158 filename = g_file_get_path (file);
159
160 g_test_message (format: "Loading ref file '%s' for test file '%s'", g_file_peek_path (file: ref_file), filename);
161
162 stream = G_INPUT_STREAM (g_file_read (ref_file, NULL, &error));
163 g_assert_no_error (error);
164 g_assert (stream != NULL);
165 reference = gdk_pixbuf_new_from_stream (stream, NULL, error: &error);
166 g_assert_no_error (error);
167 g_assert (reference != NULL);
168 g_object_unref (object: stream);
169
170 success = g_file_load_contents (file, NULL, contents: (gchar **) &contents, length: &contents_length, NULL, error: &error);
171 g_assert_no_error (error);
172 g_assert (success);
173
174#ifdef GDK_PIXBUF_USE_GIO_MIME
175 {
176 char *mime_type, *content_type;
177
178 content_type = g_content_type_guess (filename, data: contents, data_size: contents_length, NULL);
179 mime_type = g_content_type_get_mime_type (type: content_type);
180 g_assert (mime_type);
181 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error: &error);
182 g_free (mem: mime_type);
183 g_free (mem: content_type);
184 }
185#else
186 {
187 char *format;
188
189 success = find_format (filename, &format);
190 g_assert_true (success);
191 loader = gdk_pixbuf_loader_new_with_type (format, &error);
192 g_free (format);
193 }
194#endif
195
196 g_assert_no_error (error);
197 g_assert (loader != NULL);
198 g_signal_connect (loader, "size-prepared", G_CALLBACK (loader_size_prepared), &loaded);
199 g_signal_connect (loader, "area-prepared", G_CALLBACK (loader_area_prepared), &loaded);
200 g_signal_connect (loader, "area-updated", G_CALLBACK (loader_area_updated), &loaded);
201
202 for (i = 0; i < contents_length; i++)
203 {
204 success = gdk_pixbuf_loader_write (loader, buf: &contents[i], count: 1, error: &error);
205 g_assert_no_error (error);
206 g_assert (success);
207 }
208
209 success = gdk_pixbuf_loader_close (loader, error: &error);
210 g_assert_no_error (error);
211 g_assert (success);
212
213 g_assert (loaded != NULL);
214
215 success = pixdata_equal (test: loaded, ref: reference, error: &error);
216 g_assert_no_error (error);
217 g_assert (success);
218
219 g_free (mem: contents);
220 g_object_unref (object: loaded);
221 g_object_unref (object: loader);
222 g_object_unref (object: reference);
223 g_object_unref (object: ref_file);
224 g_free (mem: filename);
225}
226
227int
228main (int argc, char **argv)
229{
230
231 g_test_init (argc: &argc, argv: &argv, NULL);
232
233 if (argc < 2)
234 {
235 GFile *dir;
236 gchar *test_images;
237
238 test_images = g_build_filename (first_element: g_test_get_dir (file_type: G_TEST_DIST), "test-images/reftests", NULL);
239 dir = g_file_new_for_path (path: test_images);
240
241 add_test_for_all_images (prefix: "/pixbuf/reftest", base: dir, file: dir, test_func: test_reftest, add_test_func: is_not_ref_image);
242
243 g_object_unref (object: dir);
244 g_free (mem: test_images);
245 }
246 else
247 {
248 guint i;
249
250 for (i = 1; i < argc; i++)
251 {
252 GFile *file = g_file_new_for_commandline_arg (arg: argv[i]);
253
254 add_test_for_all_images (prefix: "/pixbuf/reftest", NULL, file, test_func: test_reftest, add_test_func: is_not_ref_image);
255
256 g_object_unref (object: file);
257 }
258 }
259
260 return g_test_run ();
261}
262

source code of gtk/subprojects/gdk-pixbuf/tests/pixbuf-reftest.c