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 | |
33 | typedef struct { |
34 | void *buf; |
35 | gsize len; |
36 | } MappedBuf; |
37 | |
38 | static void |
39 | destroy_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 | |
50 | static GdkPixbuf * |
51 | get_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 | |
112 | static void |
113 | test_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 | |
162 | static void |
163 | test_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 | |
187 | int |
188 | main (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 | |