10
10
* This library is distributed in the hope that it will be useful,
11
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
13
* GNU Library General Public License for more details.
15
* You should have received a copy of the GNU Library General
16
* Public License along with this library; if not, write to the
15
* You should have received a copy of the GNU Library General
16
* Public License along with this library; if not, write to the
17
17
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
18
* Boston, MA 02110-1301, USA.
96
generate_pixbuf (GdkPixbuf *source,
97
TumblerThumbnailFlavor *flavor)
96
pixbuf_thumbnailer_size_prepared (GdkPixbufLoader *loader,
99
TumblerThumbnail *thumbnail)
106
/* determine the source pixbuf dimensions */
107
source_width = gdk_pixbuf_get_width (source);
108
source_height = gdk_pixbuf_get_height (source);
110
/* determine the desired size for this flavor */
101
TumblerThumbnailFlavor *flavor;
107
g_return_if_fail (GDK_IS_PIXBUF_LOADER (loader));
108
g_return_if_fail (TUMBLER_IS_THUMBNAIL (thumbnail));
110
flavor = tumbler_thumbnail_get_flavor (thumbnail);
111
111
tumbler_thumbnail_flavor_get_size (flavor, &dest_width, &dest_height);
112
g_object_unref (flavor);
113
/* return the same pixbuf if no scaling is required */
114
114
if (source_width <= dest_width && source_height <= dest_height)
115
return g_object_ref (source);
117
/* determine which axis needs to be scaled down more */
118
wratio = (gdouble) source_width / (gdouble) dest_width;
119
hratio = (gdouble) source_height / (gdouble) dest_height;
121
/* adjust the other axis */
123
dest_width = rint (source_width / hratio);
116
/* do not scale the image */
117
dest_width = source_width;
118
dest_height = source_height;
125
dest_height = rint (source_height / wratio);
127
/* scale the pixbuf down to the desired size */
128
return gdk_pixbuf_scale_simple (source,
129
MAX (dest_width, 1), MAX (dest_height, 1),
130
GDK_INTERP_BILINEAR);
122
/* determine which axis needs to be scaled down more */
123
wratio = (gdouble) source_width / (gdouble) dest_width;
124
hratio = (gdouble) source_height / (gdouble) dest_height;
126
/* adjust the other axis */
128
dest_width = rint (source_width / hratio);
130
dest_height = rint (source_height / wratio);
133
gdk_pixbuf_loader_set_size (loader, MAX (dest_width, 1), MAX (dest_height, 1));
139
pixbuf_thumbnailer_new_from_stream (GInputStream *stream,
140
TumblerThumbnail *thumbnail,
141
GCancellable *cancellable,
144
GdkPixbufLoader *loader;
147
GdkPixbuf *pixbuf = NULL;
148
guchar buffer[65536];
150
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
152
/* prepare the loader */
153
loader = gdk_pixbuf_loader_new ();
154
g_signal_connect (loader, "size-prepared",
155
G_CALLBACK (pixbuf_thumbnailer_size_prepared), thumbnail);
160
n_read = g_input_stream_read (stream, buffer, sizeof (buffer),
173
if (!gdk_pixbuf_loader_write (loader, buffer, n_read, error))
181
if (!gdk_pixbuf_loader_close (loader, error))
189
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
190
if (G_LIKELY (pixbuf != NULL))
191
g_object_ref (pixbuf);
194
g_object_unref (loader);
137
203
GCancellable *cancellable,
138
204
TumblerFileInfo *info)
140
TumblerThumbnailFlavor *flavor;
141
GFileInputStream *stream;
142
TumblerImageData data;
143
TumblerThumbnail *thumbnail;
145
GdkPixbuf *source_pixbuf;
147
GError *error = NULL;
207
GFileInputStream *stream;
208
TumblerImageData data;
209
TumblerThumbnail *thumbnail;
212
GError *error = NULL;
150
215
g_return_if_fail (IS_PIXBUF_THUMBNAILER (thumbnailer));
151
216
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
152
217
g_return_if_fail (TUMBLER_IS_FILE_INFO (info));
154
219
/* do nothing if cancelled */
155
if (g_cancellable_is_cancelled (cancellable))
220
if (g_cancellable_is_cancelled (cancellable))
158
223
uri = tumbler_file_info_get_uri (info);
165
230
if (stream == NULL)
167
g_signal_emit_by_name (thumbnailer, "error", uri, error->code, error->message);
168
g_error_free (error);
172
source_pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream),
173
cancellable, &error);
174
g_object_unref (stream);
176
if (source_pixbuf == NULL)
178
g_signal_emit_by_name (thumbnailer, "error", uri, error->code, error->message);
179
g_error_free (error);
234
g_signal_emit_by_name (thumbnailer, "error", uri, error->code,
236
g_error_free (error);
240
g_signal_emit_by_name (thumbnailer, "error", uri, TUMBLER_ERROR_NO_CONTENT,
241
"Failed to open pixbuf stream");
183
247
thumbnail = tumbler_file_info_get_thumbnail (info);
185
248
g_assert (thumbnail != NULL);
187
/* generate a pixbuf for the thumbnail */
188
flavor = tumbler_thumbnail_get_flavor (thumbnail);
189
pixbuf = generate_pixbuf (source_pixbuf, flavor);
190
g_object_unref (flavor);
250
/* load the scaled pixbuf from the stream. this works like
251
* gdk_pixbuf_new_from_file_at_scale(), but without increasing the
253
pixbuf = pixbuf_thumbnailer_new_from_stream (G_INPUT_STREAM (stream), thumbnail,
254
cancellable, &error);
256
g_object_unref (stream);
262
g_signal_emit_by_name (thumbnailer, "error", uri, error->code,
264
g_error_free (error);
268
g_signal_emit_by_name (thumbnailer, "error", uri, TUMBLER_ERROR_NO_CONTENT,
269
"Failed to create pixbuf from stream");
272
g_object_unref (thumbnail);
192
276
g_assert (pixbuf != NULL);
199
283
data.rowstride = gdk_pixbuf_get_rowstride (pixbuf);
200
284
data.colorspace = (TumblerColorspace) gdk_pixbuf_get_colorspace (pixbuf);
202
tumbler_thumbnail_save_image_data (thumbnail, &data,
203
tumbler_file_info_get_mtime (info),
286
tumbler_thumbnail_save_image_data (thumbnail, &data,
287
tumbler_file_info_get_mtime (info),
206
290
if (error != NULL)