]> Pileus Git - ~andy/gtk/blob - tests/testpixbuf-save.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / tests / testpixbuf-save.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 #include "config.h"
4 #include <stdio.h>
5
6 #include <gtk/gtk.h>
7
8 static void
9 compare_pixbufs (GdkPixbuf *pixbuf, GdkPixbuf *compare, const gchar *file_type)
10 {
11         if ((gdk_pixbuf_get_width (pixbuf) !=
12              gdk_pixbuf_get_width (compare)) ||
13             (gdk_pixbuf_get_height (pixbuf) !=
14              gdk_pixbuf_get_height (compare)) ||
15             (gdk_pixbuf_get_n_channels (pixbuf) !=
16              gdk_pixbuf_get_n_channels (compare)) ||
17             (gdk_pixbuf_get_has_alpha (pixbuf) !=
18              gdk_pixbuf_get_has_alpha (compare)) ||
19             (gdk_pixbuf_get_bits_per_sample (pixbuf) !=
20              gdk_pixbuf_get_bits_per_sample (compare))) {
21                 fprintf (stderr,
22                          "saved %s file differs from copy in memory\n",
23                          file_type);
24         } else {
25                 guchar *orig_pixels;
26                 guchar *compare_pixels;
27                 gint    orig_rowstride;
28                 gint    compare_rowstride;
29                 gint    width;
30                 gint    height;
31                 gint    bytes_per_pixel;
32                 gint    x, y;
33                 guchar *p1, *p2;
34                 gint    count = 0;
35
36                 orig_pixels = gdk_pixbuf_get_pixels (pixbuf);
37                 compare_pixels = gdk_pixbuf_get_pixels (compare);
38
39                 orig_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
40                 compare_rowstride = gdk_pixbuf_get_rowstride (compare);
41
42                 width = gdk_pixbuf_get_width (pixbuf);
43                 height = gdk_pixbuf_get_height (pixbuf);
44
45                 /*  well...  */
46                 bytes_per_pixel = gdk_pixbuf_get_n_channels (pixbuf);
47
48                 p1 = orig_pixels;
49                 p2 = compare_pixels;
50
51                 for (y = 0; y < height; y++) {
52                         for (x = 0; x < width * bytes_per_pixel; x++)
53                                 count += (*p1++ != *p2++);
54
55                         orig_pixels += orig_rowstride;
56                         compare_pixels += compare_rowstride;
57
58                         p1 = orig_pixels;
59                         p2 = compare_pixels;
60                 }
61
62                 if (count > 0) {
63                         fprintf (stderr,
64                                  "saved %s file differs from copy in memory\n",
65                                  file_type);
66                 }
67         }
68 }
69
70 static gboolean
71 save_to_loader (const gchar *buf, gsize count, GError **err, gpointer data)
72 {
73         GdkPixbufLoader *loader = data;
74
75         return gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err);
76 }
77
78 static GdkPixbuf *
79 buffer_to_pixbuf (const gchar *buf, gsize count, GError **err)
80 {
81         GdkPixbufLoader *loader;
82         GdkPixbuf *pixbuf;
83
84         loader = gdk_pixbuf_loader_new ();
85         if (gdk_pixbuf_loader_write (loader, (const guchar *)buf, count, err) &&
86             gdk_pixbuf_loader_close (loader, err)) {
87                 pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
88                 g_object_unref (loader);
89                 return pixbuf;
90         } else {
91                 return NULL;
92         }
93 }
94
95 static void
96 do_compare (GdkPixbuf *pixbuf, GdkPixbuf *compare, GError *err)
97 {
98         if (compare == NULL) {
99                 fprintf (stderr, "%s", err->message);
100                 g_error_free (err);
101         } else {
102                 compare_pixbufs (pixbuf, compare, "jpeg");
103                 g_object_unref (compare);
104         }
105 }
106
107 static void
108 keypress_check (GtkWidget *widget, GdkEventKey *evt, gpointer data)
109 {
110         GdkPixbuf *pixbuf;
111         GtkDrawingArea *da = (GtkDrawingArea*)data;
112         GError *err = NULL;
113         gchar *buffer;
114         gsize count;
115         GdkPixbufLoader *loader;
116
117         pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (da), "pixbuf");
118
119         if (evt->keyval == 'q')
120                 gtk_main_quit ();
121
122         if (evt->keyval == 's' && (evt->state & GDK_CONTROL_MASK)) {
123                 /* save to callback */
124                 if (pixbuf == NULL) {
125                         fprintf (stderr, "PIXBUF NULL\n");
126                         return;
127                 }       
128
129                 loader = gdk_pixbuf_loader_new ();
130                 if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "jpeg",
131                                                   &err,
132                                                   "quality", "100",
133                                                   NULL) ||
134                     !gdk_pixbuf_loader_close (loader, &err)) {
135                         fprintf (stderr, "%s", err->message);
136                         g_error_free (err);
137                 } else {
138                         do_compare (pixbuf,
139                                     g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
140                                     err);
141                         g_object_unref (loader);
142                 }
143         }
144         else if (evt->keyval == 'S') {
145                 /* save to buffer */
146                 if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "jpeg",
147                                                 &err,
148                                                 "quality", "100",
149                                                 NULL)) {
150                         fprintf (stderr, "%s", err->message);
151                         g_error_free (err);
152                 } else {
153                         do_compare (pixbuf,
154                                     buffer_to_pixbuf (buffer, count, &err),
155                                     err);
156                 }
157         }
158         else if (evt->keyval == 's') {
159                 /* save normally */
160                 if (pixbuf == NULL) {
161                         fprintf (stderr, "PIXBUF NULL\n");
162                         return;
163                 }       
164
165                 if (!gdk_pixbuf_save (pixbuf, "foo.jpg", "jpeg",
166                                       &err,
167                                       "quality", "100",
168                                       NULL)) {
169                         fprintf (stderr, "%s", err->message);
170                         g_error_free (err);
171                 } else {
172                         do_compare (pixbuf,
173                                     gdk_pixbuf_new_from_file ("foo.jpg", &err),
174                                     err);
175                 }
176         }
177
178         if (evt->keyval == 'p' && (evt->state & GDK_CONTROL_MASK)) {
179                 /* save to callback */
180                 if (pixbuf == NULL) {
181                         fprintf (stderr, "PIXBUF NULL\n");
182                         return;
183                 }
184
185                 loader = gdk_pixbuf_loader_new ();
186                 if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "png",
187                                                   &err,
188                                                   "tEXt::Software", "testpixbuf-save",
189                                                   NULL)
190                     || !gdk_pixbuf_loader_close (loader, &err)) {
191                         fprintf (stderr, "%s", err->message);
192                         g_error_free (err);
193                 } else {
194                         do_compare (pixbuf,
195                                     g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
196                                     err);
197                         g_object_unref (loader);
198                 }
199         }
200         else if (evt->keyval == 'P') {
201                 /* save to buffer */
202                 if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "png",
203                                                 &err,
204                                                 "tEXt::Software", "testpixbuf-save",
205                                                 NULL)) {
206                         fprintf (stderr, "%s", err->message);
207                         g_error_free (err);
208                 } else {
209                         do_compare (pixbuf,
210                                     buffer_to_pixbuf (buffer, count, &err),
211                                     err);
212                 }
213         }
214         else if (evt->keyval == 'p') {
215                 if (pixbuf == NULL) {
216                         fprintf (stderr, "PIXBUF NULL\n");
217                         return;
218                 }
219
220                 if (!gdk_pixbuf_save (pixbuf, "foo.png", "png", 
221                                       &err,
222                                       "tEXt::Software", "testpixbuf-save",
223                                       NULL)) {
224                         fprintf (stderr, "%s", err->message);
225                         g_error_free (err);
226                 } else {
227                         do_compare(pixbuf,
228                                    gdk_pixbuf_new_from_file ("foo.png", &err),
229                                    err);
230                 }
231         }
232
233         if (evt->keyval == 'i' && (evt->state & GDK_CONTROL_MASK)) {
234                 /* save to callback */
235                 if (pixbuf == NULL) {
236                         fprintf (stderr, "PIXBUF NULL\n");
237                         return;
238                 }
239
240                 loader = gdk_pixbuf_loader_new ();
241                 if (!gdk_pixbuf_save_to_callback (pixbuf, save_to_loader, loader, "ico",
242                                                   &err,
243                                                   NULL)
244                     || !gdk_pixbuf_loader_close (loader, &err)) {
245                         fprintf (stderr, "%s", err->message);
246                         g_error_free (err);
247                 } else {
248                         do_compare (pixbuf,
249                                     g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)),
250                                     err);
251                         g_object_unref (loader);
252                 }
253         }
254         else if (evt->keyval == 'I') {
255                 /* save to buffer */
256                 if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &count, "ico",
257                                                 &err,
258                                                 NULL)) {
259                         fprintf (stderr, "%s", err->message);
260                         g_error_free (err);
261                 } else {
262                         do_compare (pixbuf,
263                                     buffer_to_pixbuf (buffer, count, &err),
264                                     err);
265                 }
266         }
267         else if (evt->keyval == 'i') {
268                 if (pixbuf == NULL) {
269                         fprintf (stderr, "PIXBUF NULL\n");
270                         return;
271                 }
272
273                 if (!gdk_pixbuf_save (pixbuf, "foo.ico", "ico", 
274                                       &err,
275                                       NULL)) {
276                         fprintf (stderr, "%s", err->message);
277                         g_error_free (err);
278                 } else {
279                         do_compare(pixbuf,
280                                    gdk_pixbuf_new_from_file ("foo.ico", &err),
281                                    err);
282                 }
283         }
284
285         if (evt->keyval == 'a') {
286                 if (pixbuf == NULL) {
287                         fprintf (stderr, "PIXBUF NULL\n");
288                         return;
289                 } else {
290                         GdkPixbuf *alpha_buf;
291
292                         alpha_buf = gdk_pixbuf_add_alpha (pixbuf,
293                                                           FALSE, 0, 0, 0);
294
295                         g_object_set_data_full (G_OBJECT (da),
296                                                 "pixbuf", alpha_buf,
297                                                 (GDestroyNotify) g_object_unref);
298                 }
299         }
300 }
301
302
303 static int
304 close_app (GtkWidget *widget, gpointer data)
305 {
306         gtk_main_quit ();
307         return TRUE;
308 }
309
310 static gboolean
311 draw_cb (GtkWidget *drawing_area, cairo_t *cr, gpointer data)
312 {
313         GdkPixbuf *pixbuf;
314          
315         pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),
316                                                   "pixbuf");
317
318         gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
319         cairo_paint (cr);
320
321         return FALSE;
322 }
323
324 static int
325 configure_cb (GtkWidget *drawing_area, GdkEventConfigure *evt, gpointer data)
326 {
327         GdkPixbuf *pixbuf;
328                            
329         pixbuf = (GdkPixbuf *) g_object_get_data (G_OBJECT (drawing_area),   
330                                                   "pixbuf");
331     
332         g_print ("X:%d Y:%d\n", evt->width, evt->height);
333         if (evt->width != gdk_pixbuf_get_width (pixbuf) || evt->height != gdk_pixbuf_get_height (pixbuf)) {
334                 GdkWindow *root;
335                 GdkPixbuf *new_pixbuf;
336
337                 root = gdk_get_default_root_window ();
338                 new_pixbuf = gdk_pixbuf_get_from_window (root,
339                                                          0, 0, evt->width, evt->height);
340                 g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", new_pixbuf,
341                                         (GDestroyNotify) g_object_unref);
342         }
343
344         return FALSE;
345 }
346
347 int
348 main (int argc, char **argv)
349 {   
350         GdkWindow     *root;
351         GtkWidget     *window;
352         GtkWidget     *vbox;
353         GtkWidget     *drawing_area;
354         GdkPixbuf     *pixbuf;    
355    
356         gtk_init (&argc, &argv);   
357
358         root = gdk_get_default_root_window ();
359         pixbuf = gdk_pixbuf_get_from_window (root,
360                                              0, 0, 150, 160);
361    
362         window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
363         g_signal_connect (window, "delete_event",
364                           G_CALLBACK (close_app), NULL);
365         g_signal_connect (window, "destroy",   
366                           G_CALLBACK (close_app), NULL);
367    
368         vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
369         gtk_container_add (GTK_CONTAINER (window), vbox);  
370    
371         drawing_area = gtk_drawing_area_new ();
372         gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
373                                      gdk_pixbuf_get_width (pixbuf),
374                                      gdk_pixbuf_get_height (pixbuf));
375         g_signal_connect (drawing_area, "draw",
376                           G_CALLBACK (draw_cb), NULL);
377
378         g_signal_connect (drawing_area, "configure_event",
379                           G_CALLBACK (configure_cb), NULL);
380         g_signal_connect (window, "key_press_event", 
381                           G_CALLBACK (keypress_check), drawing_area);    
382         g_object_set_data_full (G_OBJECT (drawing_area), "pixbuf", pixbuf,
383                                 (GDestroyNotify) g_object_unref);
384         gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
385    
386         gtk_widget_show_all (window);
387         gtk_main ();
388         return 0;
389 }