Mercurial > geeqie
annotate src/image-load.c @ 1012:fe82830ab8fd
converted image loader to a GObject and use signals for notification
author | nadvornik |
---|---|
date | Fri, 29 Aug 2008 20:53:53 +0000 |
parents | 616b14da08c2 |
children | 4d3c98219246 |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
9 | 3 * (C) 2004 John Ellis |
475 | 4 * Copyright (C) 2008 The Geeqie Team |
9 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
13 | |
281 | 14 #include "main.h" |
9 | 15 #include "image-load.h" |
507 | 16 |
17 #include "exif.h" | |
586 | 18 #include "filedata.h" |
9 | 19 #include "ui_fileops.h" |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
20 #include "gq-marshal.h" |
9 | 21 |
22 #include <fcntl.h> | |
1008 | 23 #include <sys/mman.h> |
9 | 24 |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
25 enum { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
26 SIGNAL_AREA_READY = 0, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
27 SIGNAL_ERROR, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
28 SIGNAL_DONE, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
29 SIGNAL_PERCENT, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
30 SIGNAL_COUNT |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
31 }; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
32 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
33 static guint signals[SIGNAL_COUNT] = { 0 }; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
34 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
35 static void image_loader_init (GTypeInstance *instance, gpointer g_class); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
36 static void image_loader_class_init (ImageLoaderClass *class); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
37 static void image_loader_finalize(GObject *object); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
38 static void image_loader_stop(ImageLoader *il); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
39 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
40 GType image_loader_get_type (void) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
41 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
42 static GType type = 0; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
43 if (type == 0) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
44 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
45 static const GTypeInfo info = { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
46 sizeof (ImageLoaderClass), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
47 NULL, /* base_init */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
48 NULL, /* base_finalize */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
49 (GClassInitFunc)image_loader_class_init, /* class_init */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
50 NULL, /* class_finalize */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
51 NULL, /* class_data */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
52 sizeof (ImageLoader), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
53 0, /* n_preallocs */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
54 (GInstanceInitFunc)image_loader_init, /* instance_init */ |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
55 }; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
56 type = g_type_register_static (G_TYPE_OBJECT, "ImageLoaderType", &info, 0); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
57 } |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
58 return type; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
59 } |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
60 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
61 static void image_loader_init (GTypeInstance *instance, gpointer g_class) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
62 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
63 ImageLoader *il = (ImageLoader *)instance; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
64 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
65 il->pixbuf = NULL; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
66 il->idle_id = -1; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
67 il->idle_priority = G_PRIORITY_DEFAULT_IDLE; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
68 il->done = FALSE; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
69 il->loader = NULL; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
70 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
71 il->bytes_read = 0; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
72 il->bytes_total = 0; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
73 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
74 il->idle_done_id = -1; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
75 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
76 il->idle_read_loop_count = options->image.idle_read_loop_count; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
77 il->read_buffer_size = options->image.read_buffer_size; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
78 il->mapped_file = NULL; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
79 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
80 il->requested_width = 0; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
81 il->requested_height = 0; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
82 il->shrunk = FALSE; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
83 DEBUG_1("new image loader %p, bufsize=%u idle_loop=%u", il, il->read_buffer_size, il->idle_read_loop_count); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
84 } |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
85 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
86 static void image_loader_class_init (ImageLoaderClass *class) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
87 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
88 GObjectClass *gobject_class = G_OBJECT_CLASS (class); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
89 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
90 // gobject_class->set_property = image_loader_set_property; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
91 // gobject_class->get_property = image_loader_get_property; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
92 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
93 gobject_class->finalize = image_loader_finalize; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
94 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
95 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
96 signals[SIGNAL_AREA_READY] = |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
97 g_signal_new("area_ready", |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
98 G_OBJECT_CLASS_TYPE(gobject_class), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
99 G_SIGNAL_RUN_LAST, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
100 G_STRUCT_OFFSET(ImageLoaderClass, area_ready), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
101 NULL, NULL, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
102 gq_marshal_VOID__INT_INT_INT_INT, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
103 G_TYPE_NONE, 4, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
104 G_TYPE_INT, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
105 G_TYPE_INT, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
106 G_TYPE_INT, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
107 G_TYPE_INT); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
108 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
109 signals[SIGNAL_ERROR] = |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
110 g_signal_new("error", |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
111 G_OBJECT_CLASS_TYPE(gobject_class), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
112 G_SIGNAL_RUN_LAST, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
113 G_STRUCT_OFFSET(ImageLoaderClass, error), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
114 NULL, NULL, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
115 g_cclosure_marshal_VOID__VOID, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
116 G_TYPE_NONE, 1, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
117 GDK_TYPE_EVENT); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
118 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
119 signals[SIGNAL_DONE] = |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
120 g_signal_new("done", |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
121 G_OBJECT_CLASS_TYPE(gobject_class), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
122 G_SIGNAL_RUN_LAST, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
123 G_STRUCT_OFFSET(ImageLoaderClass, done), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
124 NULL, NULL, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
125 g_cclosure_marshal_VOID__VOID, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
126 G_TYPE_NONE, 0); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
127 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
128 signals[SIGNAL_PERCENT] = |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
129 g_signal_new("percent", |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
130 G_OBJECT_CLASS_TYPE(gobject_class), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
131 G_SIGNAL_RUN_LAST, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
132 G_STRUCT_OFFSET(ImageLoaderClass, percent), |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
133 NULL, NULL, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
134 g_cclosure_marshal_VOID__DOUBLE, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
135 G_TYPE_NONE, 1, |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
136 G_TYPE_DOUBLE); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
137 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
138 } |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
139 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
140 static void image_loader_finalize(GObject *object) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
141 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
142 ImageLoader *il = (ImageLoader *)object; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
143 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
144 image_loader_stop(il); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
145 if (il->idle_done_id != -1) g_source_remove(il->idle_done_id); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
146 if (il->pixbuf) gdk_pixbuf_unref(il->pixbuf); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
147 file_data_unref(il->fd); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
148 DEBUG_1("freeing image loader %p bytes_read=%d", il, il->bytes_read); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
149 } |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
150 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
151 void image_loader_free(ImageLoader *il) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
152 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
153 if (!il) return; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
154 g_object_unref(G_OBJECT(il)); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
155 } |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
156 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
157 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
158 ImageLoader *image_loader_new(FileData *fd) |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
159 { |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
160 ImageLoader *il; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
161 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
162 if (!fd) return NULL; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
163 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
164 il = (ImageLoader *) g_object_new(TYPE_IMAGE_LOADER, NULL); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
165 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
166 il->fd = file_data_ref(fd); |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
167 |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
168 return il; |
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
169 } |
9 | 170 |
171 static void image_loader_sync_pixbuf(ImageLoader *il) | |
172 { | |
173 GdkPixbuf *pb; | |
174 | |
175 if (!il->loader) return; | |
176 | |
177 pb = gdk_pixbuf_loader_get_pixbuf(il->loader); | |
178 | |
179 if (pb == il->pixbuf) return; | |
180 | |
181 if (il->pixbuf) gdk_pixbuf_unref(il->pixbuf); | |
182 il->pixbuf = pb; | |
183 if (il->pixbuf) gdk_pixbuf_ref(il->pixbuf); | |
184 } | |
185 | |
500 | 186 static void image_loader_area_updated_cb(GdkPixbufLoader *loader, |
9 | 187 guint x, guint y, guint w, guint h, |
188 gpointer data) | |
189 { | |
190 ImageLoader *il = data; | |
191 | |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
192 if (!il->pixbuf) |
9 | 193 { |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
194 image_loader_sync_pixbuf(il); |
9 | 195 if (!il->pixbuf) |
196 { | |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
197 log_printf("critical: area_ready signal with NULL pixbuf (out of mem?)\n"); |
9 | 198 } |
199 } | |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
200 g_signal_emit(il, signals[SIGNAL_AREA_READY], 0, x, y, w, h); |
9 | 201 } |
202 | |
500 | 203 static void image_loader_area_prepared_cb(GdkPixbufLoader *loader, gpointer data) |
204 { | |
205 GdkPixbuf *pb; | |
206 guchar *pix; | |
207 size_t h, rs; | |
961
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
208 |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
209 /* a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669 */ |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
210 gchar *format = gdk_pixbuf_format_get_name(gdk_pixbuf_loader_get_format(loader)); |
995 | 211 if (strcmp(format, "svg") == 0) |
961
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
212 { |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
213 g_free(format); |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
214 return; |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
215 } |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
216 |
3f03282ec40e
a workaround for http://bugzilla.gnome.org/show_bug.cgi?id=547669
nadvornik
parents:
890
diff
changeset
|
217 g_free(format); |
500 | 218 |
219 pb = gdk_pixbuf_loader_get_pixbuf(loader); | |
220 | |
221 h = gdk_pixbuf_get_height(pb); | |
222 rs = gdk_pixbuf_get_rowstride(pb); | |
223 pix = gdk_pixbuf_get_pixels(pb); | |
224 | |
225 memset(pix, 0, rs * h); /*this should be faster than pixbuf_fill */ | |
226 | |
227 } | |
228 | |
9 | 229 static void image_loader_size_cb(GdkPixbufLoader *loader, |
230 gint width, gint height, gpointer data) | |
231 { | |
232 ImageLoader *il = data; | |
233 GdkPixbufFormat *format; | |
234 gchar **mime_types; | |
235 gint scale = FALSE; | |
236 gint n; | |
237 | |
238 if (il->requested_width < 1 || il->requested_height < 1) return; | |
239 | |
240 format = gdk_pixbuf_loader_get_format(loader); | |
241 if (!format) return; | |
242 | |
243 mime_types = gdk_pixbuf_format_get_mime_types(format); | |
244 n = 0; | |
245 while (mime_types[n]) | |
246 { | |
247 if (strstr(mime_types[n], "jpeg")) scale = TRUE; | |
248 n++; | |
249 } | |
250 g_strfreev(mime_types); | |
442 | 251 |
9 | 252 if (!scale) return; |
253 | |
254 if (width > il->requested_width || height > il->requested_height) | |
255 { | |
256 gint nw, nh; | |
257 | |
258 if (((gdouble)il->requested_width / width) < ((gdouble)il->requested_height / height)) | |
259 { | |
260 nw = il->requested_width; | |
261 nh = (gdouble)nw / width * height; | |
262 if (nh < 1) nh = 1; | |
263 } | |
264 else | |
265 { | |
266 nh = il->requested_height; | |
267 nw = (gdouble)nh / height * width; | |
268 if (nw < 1) nw = 1; | |
269 } | |
442 | 270 |
9 | 271 gdk_pixbuf_loader_set_size(loader, nw, nh); |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
272 il->shrunk = TRUE; |
9 | 273 } |
274 } | |
275 | |
276 static void image_loader_stop(ImageLoader *il) | |
277 { | |
278 if (!il) return; | |
279 | |
280 if (il->idle_id != -1) | |
281 { | |
282 g_source_remove(il->idle_id); | |
283 il->idle_id = -1; | |
284 } | |
285 | |
286 if (il->loader) | |
287 { | |
288 /* some loaders do not have a pixbuf till close, order is important here */ | |
289 gdk_pixbuf_loader_close(il->loader, NULL); | |
290 image_loader_sync_pixbuf(il); | |
291 g_object_unref(G_OBJECT(il->loader)); | |
292 il->loader = NULL; | |
293 } | |
294 | |
1008 | 295 if (il->mapped_file) |
9 | 296 { |
1008 | 297 if (il->preview) |
298 { | |
299 exif_free_preview(il->mapped_file); | |
300 } | |
301 else | |
302 { | |
303 munmap(il->mapped_file, il->bytes_total); | |
304 } | |
305 il->mapped_file = NULL; | |
9 | 306 } |
307 | |
308 il->done = TRUE; | |
309 } | |
310 | |
311 static void image_loader_done(ImageLoader *il) | |
312 { | |
313 image_loader_stop(il); | |
314 | |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
315 g_signal_emit(il, signals[SIGNAL_DONE], 0); |
9 | 316 } |
317 | |
318 static gint image_loader_done_delay_cb(gpointer data) | |
319 { | |
320 ImageLoader *il = data; | |
321 | |
322 il->idle_done_id = -1; | |
323 image_loader_done(il); | |
324 return FALSE; | |
325 } | |
326 | |
327 static void image_loader_done_delay(ImageLoader *il) | |
328 { | |
329 if (il->idle_done_id == -1) il->idle_done_id = g_idle_add_full(il->idle_priority, | |
330 image_loader_done_delay_cb, il, NULL); | |
331 } | |
332 | |
333 static void image_loader_error(ImageLoader *il) | |
334 { | |
335 image_loader_stop(il); | |
336 | |
1009
dd311dae857a
fixed thumbnail loader for the new raw preview interface
nadvornik
parents:
1008
diff
changeset
|
337 DEBUG_1("pixbuf_loader reported load error for: %s", il->fd->path); |
9 | 338 |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
339 g_signal_emit(il, signals[SIGNAL_ERROR], 0); |
9 | 340 } |
341 | |
342 static gint image_loader_idle_cb(gpointer data) | |
343 { | |
344 ImageLoader *il = data; | |
345 gint b; | |
346 gint c; | |
347 | |
348 if (!il) return FALSE; | |
349 | |
350 if (il->idle_id == -1) return FALSE; | |
351 | |
413
9e521adbf312
Add two new options to control image read buffer at runtime.
zas_
parents:
281
diff
changeset
|
352 c = il->idle_read_loop_count ? il->idle_read_loop_count : 1; |
9 | 353 while (c > 0) |
354 { | |
1008 | 355 b = MIN(il->read_buffer_size, il->bytes_total - il->bytes_read); |
9 | 356 |
357 if (b == 0) | |
358 { | |
359 image_loader_done(il); | |
360 return FALSE; | |
361 } | |
362 | |
1008 | 363 if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, il->mapped_file + il->bytes_read, b, NULL))) |
9 | 364 { |
365 image_loader_error(il); | |
366 return FALSE; | |
367 } | |
368 | |
369 il->bytes_read += b; | |
370 | |
371 c--; | |
372 } | |
373 | |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
374 if (il->bytes_total > 0) |
9 | 375 { |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
376 g_signal_emit(il, signals[SIGNAL_PERCENT], 0, (gdouble)il->bytes_read / il->bytes_total); |
9 | 377 } |
378 | |
379 return TRUE; | |
380 } | |
381 | |
382 static gint image_loader_begin(ImageLoader *il) | |
383 { | |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
384 gint b; |
9 | 385 |
386 if (!il->loader || il->pixbuf) return FALSE; | |
442 | 387 |
1008 | 388 b = MIN(il->read_buffer_size, il->bytes_total - il->bytes_read); |
45
7cfa60beda76
Thu May 26 13:57:19 2005 John Ellis <johne@verizon.net>
gqview
parents:
43
diff
changeset
|
389 |
9 | 390 if (b < 1) |
391 { | |
392 image_loader_stop(il); | |
393 return FALSE; | |
394 } | |
395 | |
1008 | 396 if (!gdk_pixbuf_loader_write(il->loader, il->mapped_file + il->bytes_read, b, NULL)) |
9 | 397 { |
398 image_loader_stop(il); | |
399 return FALSE; | |
400 } | |
401 | |
1008 | 402 il->bytes_read += b; |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
403 |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
404 /* read until size is known */ |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
405 while (il->loader && !gdk_pixbuf_loader_get_pixbuf(il->loader) && b > 0) |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
406 { |
1008 | 407 b = MIN(il->read_buffer_size, il->bytes_total - il->bytes_read); |
408 if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, il->mapped_file + il->bytes_read, b, NULL))) | |
60
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
409 { |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
410 image_loader_stop(il); |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
411 return FALSE; |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
412 } |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
413 il->bytes_read += b; |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
414 } |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
415 if (!il->pixbuf) image_loader_sync_pixbuf(il); |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
416 |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
417 if (il->bytes_read == il->bytes_total || b < 1) |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
418 { |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
419 /* done, handle (broken) loaders that do not have pixbuf till close */ |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
420 image_loader_stop(il); |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
421 |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
422 if (!il->pixbuf) return FALSE; |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
423 |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
424 image_loader_done_delay(il); |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
425 return TRUE; |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
426 } |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
427 |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
428 if (!il->pixbuf) |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
429 { |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
430 image_loader_stop(il); |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
431 return FALSE; |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
432 } |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
433 |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
434 /* finally, progressive loading :) */ |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
435 il->idle_id = g_idle_add_full(il->idle_priority, image_loader_idle_cb, il, NULL); |
9c0c402b0ef3
Mon Jun 13 17:31:46 2005 John Ellis <johne@verizon.net>
gqview
parents:
54
diff
changeset
|
436 |
9 | 437 return TRUE; |
438 } | |
439 | |
440 static gint image_loader_setup(ImageLoader *il) | |
441 { | |
442 struct stat st; | |
443 gchar *pathl; | |
444 | |
1008 | 445 if (!il || il->loader || il->mapped_file) return FALSE; |
446 | |
447 il->mapped_file = NULL; | |
448 | |
449 if (il->fd) | |
450 { | |
451 ExifData *exif = exif_read_fd(il->fd); | |
452 | |
453 il->mapped_file = exif_get_preview(exif, &il->bytes_total); | |
454 | |
455 if (il->mapped_file) | |
456 { | |
457 il->preview = TRUE; | |
1009
dd311dae857a
fixed thumbnail loader for the new raw preview interface
nadvornik
parents:
1008
diff
changeset
|
458 DEBUG_1("Raw file %s contains embedded image", il->fd->path); |
1008 | 459 } |
460 exif_free_fd(il->fd, exif); | |
461 } | |
9 | 462 |
1008 | 463 |
464 if (!il->mapped_file) | |
465 { | |
466 /* normal file */ | |
467 gint load_fd; | |
468 | |
1009
dd311dae857a
fixed thumbnail loader for the new raw preview interface
nadvornik
parents:
1008
diff
changeset
|
469 pathl = path_from_utf8(il->fd->path); |
1008 | 470 load_fd = open(pathl, O_RDONLY | O_NONBLOCK); |
471 g_free(pathl); | |
472 if (load_fd == -1) return FALSE; | |
9 | 473 |
1008 | 474 if (fstat(load_fd, &st) == 0) |
475 { | |
476 il->bytes_total = st.st_size; | |
477 } | |
478 else | |
479 { | |
480 close(load_fd); | |
481 return FALSE; | |
482 } | |
483 | |
484 il->mapped_file = mmap(0, il->bytes_total, PROT_READ|PROT_WRITE, MAP_PRIVATE, load_fd, 0); | |
485 close(load_fd); | |
486 if (il->mapped_file == MAP_FAILED) | |
487 { | |
488 il->mapped_file = 0; | |
489 return FALSE; | |
490 } | |
491 il->preview = FALSE; | |
9 | 492 } |
493 | |
1008 | 494 |
9 | 495 il->loader = gdk_pixbuf_loader_new(); |
496 g_signal_connect(G_OBJECT(il->loader), "area_updated", | |
500 | 497 G_CALLBACK(image_loader_area_updated_cb), il); |
9 | 498 g_signal_connect(G_OBJECT(il->loader), "size_prepared", |
499 G_CALLBACK(image_loader_size_cb), il); | |
500 | 500 g_signal_connect(G_OBJECT(il->loader), "area_prepared", |
501 G_CALLBACK(image_loader_area_prepared_cb), il); | |
9 | 502 |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
503 il->shrunk = FALSE; |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
504 |
9 | 505 return image_loader_begin(il); |
506 } | |
507 | |
508 | |
509 /* don't forget to gdk_pixbuf_ref() it if you want to use it after image_loader_free() */ | |
510 GdkPixbuf *image_loader_get_pixbuf(ImageLoader *il) | |
511 { | |
512 if (!il) return NULL; | |
513 | |
514 return il->pixbuf; | |
515 } | |
516 | |
517 gchar *image_loader_get_format(ImageLoader *il) | |
518 { | |
519 GdkPixbufFormat *format; | |
520 gchar **mimev; | |
521 gchar *mime; | |
522 | |
523 if (!il || !il->loader) return NULL; | |
524 | |
525 format = gdk_pixbuf_loader_get_format(il->loader); | |
526 if (!format) return NULL; | |
527 | |
528 mimev = gdk_pixbuf_format_get_mime_types(format); | |
529 if (!mimev) return NULL; | |
530 | |
531 /* return first member of mimev, as GdkPixbufLoader has no way to tell us which exact one ? */ | |
532 mime = g_strdup(mimev[0]); | |
533 g_strfreev(mimev); | |
534 | |
535 return mime; | |
536 } | |
537 | |
538 void image_loader_set_requested_size(ImageLoader *il, gint width, gint height) | |
539 { | |
540 if (!il) return; | |
541 | |
542 il->requested_width = width; | |
543 il->requested_height = height; | |
544 } | |
545 | |
413
9e521adbf312
Add two new options to control image read buffer at runtime.
zas_
parents:
281
diff
changeset
|
546 void image_loader_set_buffer_size(ImageLoader *il, guint count) |
9 | 547 { |
548 if (!il) return; | |
549 | |
413
9e521adbf312
Add two new options to control image read buffer at runtime.
zas_
parents:
281
diff
changeset
|
550 il->idle_read_loop_count = count ? count : 1; |
9 | 551 } |
552 | |
553 void image_loader_set_priority(ImageLoader *il, gint priority) | |
554 { | |
555 if (!il) return; | |
556 | |
557 il->idle_priority = priority; | |
558 } | |
559 | |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
560 gint image_loader_start(ImageLoader *il) |
9 | 561 { |
562 if (!il) return FALSE; | |
563 | |
1009
dd311dae857a
fixed thumbnail loader for the new raw preview interface
nadvornik
parents:
1008
diff
changeset
|
564 if (!il->fd) return FALSE; |
9 | 565 |
566 return image_loader_setup(il); | |
567 } | |
568 | |
569 gdouble image_loader_get_percent(ImageLoader *il) | |
570 { | |
571 if (!il || il->bytes_total == 0) return 0.0; | |
572 | |
573 return (gdouble)il->bytes_read / il->bytes_total; | |
574 } | |
575 | |
576 gint image_loader_get_is_done(ImageLoader *il) | |
577 { | |
578 if (!il) return FALSE; | |
579 | |
580 return il->done; | |
581 } | |
582 | |
1011 | 583 FileData *image_loader_get_fd(ImageLoader *il) |
584 { | |
585 if (!il) return NULL; | |
586 | |
587 return il->fd; | |
588 | |
589 } | |
590 | |
591 gint image_loader_get_shrunk(ImageLoader *il) | |
592 { | |
593 if (!il) return FALSE; | |
594 | |
595 return il->shrunk; | |
596 | |
597 } | |
598 | |
599 | |
138 | 600 gint image_load_dimensions(FileData *fd, gint *width, gint *height) |
9 | 601 { |
602 ImageLoader *il; | |
603 gint success; | |
604 | |
138 | 605 il = image_loader_new(fd); |
9 | 606 |
1012
fe82830ab8fd
converted image loader to a GObject and use signals for notification
nadvornik
parents:
1011
diff
changeset
|
607 success = image_loader_start(il); |
9 | 608 |
609 if (success && il->pixbuf) | |
610 { | |
611 if (width) *width = gdk_pixbuf_get_width(il->pixbuf); | |
612 if (height) *height = gdk_pixbuf_get_height(il->pixbuf);; | |
613 } | |
614 else | |
615 { | |
616 if (width) *width = -1; | |
617 if (height) *height = -1; | |
618 } | |
619 | |
620 image_loader_free(il); | |
621 | |
622 return success; | |
623 } |