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

source code of gtk/subprojects/gdk-pixbuf/tests/pixbuf-readonly-to-mutable.c