1 /* -*- Mode: C; c-basic-offset: 2; -*- */
2 /* GdkPixbuf library - test loaders
3 *
4 * Copyright (C) 2014 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
20 #include "gdk-pixbuf/gdk-pixbuf.h"
21 #include "test-common.h"
22 #include <string.h>
23
24 #ifdef G_OS_UNIX
25 #include <fcntl.h>
26 #include <sys/mman.h>
27 #include <unistd.h>
28 #endif
29
30 #ifdef G_OS_UNIX
31
32 typedef struct {
33 void *buf;
34 gsize len;
35 } MappedBuf;
36
37 static void
destroy_buf_unmap(gpointer data)38 destroy_buf_unmap (gpointer data)
39 {
40 MappedBuf *buf = data;
41 int r;
42
43 r = munmap (buf->buf, buf->len);
44 g_assert_cmpint (r, ==, 0);
45 g_free (buf);
46 }
47 #endif
48
49 static GdkPixbuf *
get_readonly_pixbuf(void)50 get_readonly_pixbuf (void)
51 {
52 GdkPixbuf *reference;
53 GdkPixbuf *result;
54 GBytes *bytes;
55 GError *error = NULL;
56
57 reference = gdk_pixbuf_new_from_file (g_test_get_filename (G_TEST_DIST, "test-image.png", NULL), &error);
58 g_assert_no_error (error);
59
60 #ifdef G_OS_UNIX
61 {
62 MappedBuf *buf;
63 int pagesize;
64 int pages;
65 int r;
66 int zero_fd;
67 gsize pixlen;
68
69 pagesize = sysconf (_SC_PAGESIZE);
70 g_assert_cmpint (pagesize, >, 0);
71
72 pixlen = gdk_pixbuf_get_byte_length (reference);
73 pages = pixlen / pagesize + 1;
74
75 buf = g_new0 (MappedBuf, 1);
76 buf->len = pages * pagesize;
77 zero_fd = open("/dev/zero", O_RDWR);
78 g_assert(zero_fd != -1);
79 buf->buf = mmap (NULL, buf->len, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
80 g_assert (buf->buf != NULL);
81 close(zero_fd);
82
83 memcpy (buf->buf, gdk_pixbuf_get_pixels (reference), pixlen);
84
85 r = mprotect (buf->buf, buf->len, PROT_READ);
86 g_assert_cmpint (r, ==, 0);
87
88 bytes = g_bytes_new_with_free_func (buf->buf, buf->len, destroy_buf_unmap, buf);
89 }
90 #else
91 bytes = g_bytes_new (gdk_pixbuf_get_pixels (reference), gdk_pixbuf_get_byte_length (reference));
92 #endif
93
94 result = gdk_pixbuf_new_from_bytes (bytes,
95 gdk_pixbuf_get_colorspace (reference),
96 gdk_pixbuf_get_has_alpha (reference),
97 gdk_pixbuf_get_bits_per_sample (reference),
98 gdk_pixbuf_get_width (reference),
99 gdk_pixbuf_get_height (reference),
100 gdk_pixbuf_get_rowstride (reference));
101 g_object_unref (reference);
102 g_bytes_unref (bytes);
103
104 return result;
105 }
106
107 static void
test_mutate_readonly(void)108 test_mutate_readonly (void)
109 {
110 GdkPixbuf *src;
111 GdkPixbuf *dest;
112
113 if (!format_supported ("png"))
114 {
115 g_test_skip ("format not supported");
116 return;
117 }
118
119 src = get_readonly_pixbuf ();
120 gdk_pixbuf_scale (src, src,
121 0, 0,
122 gdk_pixbuf_get_width (src) / 4,
123 gdk_pixbuf_get_height (src) / 4,
124 0, 0, 0.5, 0.5,
125 GDK_INTERP_NEAREST);
126 g_object_unref (src);
127
128 src = get_readonly_pixbuf ();
129
130 dest = gdk_pixbuf_scale_simple (src,
131 gdk_pixbuf_get_width (src) / 4,
132 gdk_pixbuf_get_height (src) / 4,
133 GDK_INTERP_NEAREST);
134 g_object_unref (dest);
135
136 dest = gdk_pixbuf_composite_color_simple (src,
137 gdk_pixbuf_get_width (src) / 4,
138 gdk_pixbuf_get_height (src) / 4,
139 GDK_INTERP_NEAREST,
140 128,
141 8,
142 G_MAXUINT32,
143 G_MAXUINT32/2);
144 g_object_unref (dest);
145
146 dest = gdk_pixbuf_rotate_simple (src, 180);
147 g_object_unref (dest);
148
149 dest = gdk_pixbuf_flip (src, TRUE);
150 g_object_unref (dest);
151 dest = gdk_pixbuf_flip (src, FALSE);
152 g_object_unref (dest);
153
154 g_object_unref (src);
155 }
156
157 static void
test_read_pixel_bytes(void)158 test_read_pixel_bytes (void)
159 {
160 GdkPixbuf *src;
161 GBytes *bytes;
162
163 if (!format_supported ("png"))
164 {
165 g_test_skip ("format not supported");
166 return;
167 }
168
169 src = get_readonly_pixbuf ();
170 bytes = gdk_pixbuf_read_pixel_bytes (src);
171 g_object_unref (src);
172 g_bytes_unref (bytes);
173
174 src = get_readonly_pixbuf ();
175 /* Force a mutable conversion */
176 (void) gdk_pixbuf_get_pixels (src);
177 bytes = gdk_pixbuf_read_pixel_bytes (src);
178 g_object_unref (src);
179 g_bytes_unref (bytes);
180 }
181
182 int
main(int argc,char ** argv)183 main (int argc, char **argv)
184 {
185 g_test_init (&argc, &argv, NULL);
186
187 g_test_add_func ("/pixbuf/readonly/mutate", test_mutate_readonly);
188 g_test_add_func ("/pixbuf/readonly/readpixelbytes", test_read_pixel_bytes);
189
190 return g_test_run ();
191 }
192