if (!cd->thumb_loader || !g_list_find(cd->list, cd->thumb_info)) return;
- pixbuf = thumb_loader_get_pixbuf(cd->thumb_loader, TRUE);
+ pixbuf = thumb_loader_get_pixbuf(cd->thumb_loader);
collection_info_set_thumb(cd->thumb_info, pixbuf);
g_object_unref(pixbuf);
di = dw->thumb_item;
if (di->pixbuf) g_object_unref(di->pixbuf);
- di->pixbuf = thumb_loader_get_pixbuf(dw->thumb_loader, TRUE);
+ di->pixbuf = thumb_loader_get_pixbuf(dw->thumb_loader);
dupe_listview_set_thumb(dw, di, NULL);
}
pi->queued = FALSE;
if (pi->pixbuf) g_object_unref(pi->pixbuf);
- pi->pixbuf = thumb_loader_get_pixbuf(tl, TRUE);
+ pi->pixbuf = thumb_loader_get_pixbuf(tl);
rc = pi->refcount;
image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height);
return NULL;
}
+gint pixbuf_scale_aspect(gint req_w, gint req_h, gint old_w, gint old_h,
+ gint *new_w, gint *new_h)
+{
+ if (((gdouble)req_w / old_w) < ((gdouble)req_h / old_h))
+ {
+ *new_w = req_w;
+ *new_h = (gdouble)*new_w / old_w * old_h;
+ if (*new_h < 1) *new_h = 1;
+ }
+ else
+ {
+ *new_h = req_h;
+ *new_w = (gdouble)*new_h / old_h * old_w;
+ if (*new_w < 1) *new_w = 1;
+ }
+
+ return (*new_w != old_w || *new_h != old_h);
+}
+
+GdkPixbuf *pixbuf_fallback(FileData *fd, gint requested_width, gint requested_height)
+{
+ GdkPixbuf *pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); /* FIXME use different images according to FORMAT_CLASS */
+
+ if (requested_width && requested_height)
+ {
+ gint w = gdk_pixbuf_get_width(pixbuf);
+ gint h = gdk_pixbuf_get_height(pixbuf);
+
+ if (w > requested_width || h > requested_height)
+ {
+ gint nw, nh;
+
+ if (pixbuf_scale_aspect(requested_width, requested_height,
+ w, h, &nw, &nh))
+ {
+ GdkPixbuf *tmp;
+
+ tmp = pixbuf;
+ pixbuf = gdk_pixbuf_scale_simple(tmp, nw, nh, GDK_INTERP_TILES);
+ g_object_unref(G_OBJECT(tmp));
+ }
+ }
+ }
+ return pixbuf;
+}
+
+
/*
*-----------------------------------------------------------------------------
* misc utils
GdkPixbuf *pixbuf_inline(const gchar *key);
+GdkPixbuf *pixbuf_fallback(FileData *fd, gint requested_width, gint requested_height);
+
+gint pixbuf_scale_aspect(gint req_w, gint req_h, gint old_w, gint old_h, gint *new_w, gint *new_h);
#define PIXBUF_INLINE_FOLDER_CLOSED "folder_closed"
#define PIXBUF_INLINE_FOLDER_LOCKED "folder_locked"
if (!tl->fd) tl->fd = file_data_ref(fd);
+ if (tl->fd->thumb_pixbuf) g_object_unref(tl->fd->thumb_pixbuf);
+ tl->fd->thumb_pixbuf = pixbuf_fallback(tl->fd, tl->max_w, tl->max_h);
+
if (tl->cache_enable)
{
cache_path = cache_find_location(CACHE_TYPE_THUMB, tl->fd->path);
}
#endif
-GdkPixbuf *thumb_loader_get_pixbuf(ThumbLoader *tl, gint with_fallback)
+GdkPixbuf *thumb_loader_get_pixbuf(ThumbLoader *tl)
{
GdkPixbuf *pixbuf;
if (tl && tl->standard_loader)
{
- return thumb_loader_std_get_pixbuf((ThumbLoaderStd *)tl, with_fallback);
+ return thumb_loader_std_get_pixbuf((ThumbLoaderStd *)tl);
}
if (tl && tl->fd && tl->fd->thumb_pixbuf)
pixbuf = tl->fd->thumb_pixbuf;
g_object_ref(pixbuf);
}
- else if (with_fallback)
- {
- gint w, h;
-
- pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
- w = gdk_pixbuf_get_width(pixbuf);
- h = gdk_pixbuf_get_height(pixbuf);
- if ((w > tl->max_w || h > tl->max_h) &&
- normalize_thumb(&w, &h, tl->max_w, tl->max_h))
- {
- GdkPixbuf *tmp;
-
- tmp = pixbuf;
- pixbuf = gdk_pixbuf_scale_simple(tmp, w, h, GDK_INTERP_NEAREST);
- gdk_pixbuf_unref(tmp);
- }
- }
else
{
- pixbuf = NULL;
+ pixbuf = pixbuf_fallback(NULL, tl->max_w, tl->max_h);
}
return pixbuf;
w = gdk_pixbuf_get_width(pixbuf);
h = gdk_pixbuf_get_height(pixbuf);
- if ((w > max_w || h > max_h) &&
- normalize_thumb(&w, &h, max_w, max_h))
+ if (pixbuf_scale_aspect(w, h, max_w, max_h, &w, &h))
{
/* scale */
GdkPixbuf *tmp;
}
#undef XV_BUFFER
-static gint normalize_thumb(gint *width, gint *height, gint max_w, gint max_h)
-{
- gdouble scale;
- gint new_w, new_h;
-
- scale = MIN((gdouble) max_w / *width, (gdouble) max_h / *height);
- new_w = *width * scale;
- new_h = *height * scale;
-
- if (new_w != *width || new_h != *height)
- {
- *width = new_w;
- *height = new_h;
- return TRUE;
- }
-
- return FALSE;
-}
-
static void free_rgb_buffer(guchar *pixels, gpointer data)
{
g_free(pixels);
pixbuf = gdk_pixbuf_new_from_data(rgb_data, GDK_COLORSPACE_RGB, FALSE, 8,
width, height, 3 * width, free_rgb_buffer, NULL);
- if (normalize_thumb(&width, &height, max_w, max_h))
+ if (pixbuf_scale_aspect(width, height, max_w, max_h, &width, &height))
{
/* scale */
GdkPixbuf *tmp;
gint thumb_loader_start(ThumbLoader *tl, FileData *fd);
void thumb_loader_free(ThumbLoader *tl);
-GdkPixbuf *thumb_loader_get_pixbuf(ThumbLoader *tl, gint with_fallback);
+GdkPixbuf *thumb_loader_get_pixbuf(ThumbLoader *tl);
#endif
g_object_unref(G_OBJECT(pixbuf));
}
-static gint thumb_loader_std_scale_aspect(gint req_w, gint req_h, gint old_w, gint old_h,
- gint *new_w, gint *new_h)
-{
- if (((gdouble)req_w / old_w) < ((gdouble)req_h / old_h))
- {
- *new_w = req_w;
- *new_h = (gdouble)*new_w / old_w * old_h;
- if (*new_h < 1) *new_h = 1;
- }
- else
- {
- *new_h = req_h;
- *new_w = (gdouble)*new_h / old_h * old_w;
- if (*new_w < 1) *new_w = 1;
- }
-
- return (*new_w != old_w || *new_h != old_h);
-}
-
static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf, gint shrunk)
{
GdkPixbuf *pixbuf_thumb = NULL;
{
gint thumb_w, thumb_h;
- if (thumb_loader_std_scale_aspect(cache_w, cache_h, sw, sh,
+ if (pixbuf_scale_aspect(cache_w, cache_h, sw, sh,
&thumb_w, &thumb_h))
{
pixbuf_thumb = gdk_pixbuf_scale_simple(pixbuf, thumb_w, thumb_h,
sh = gdk_pixbuf_get_height(pixbuf);
}
- if (thumb_loader_std_scale_aspect(tl->requested_width, tl->requested_height, sw, sh,
+ if (pixbuf_scale_aspect(tl->requested_width, tl->requested_height, sw, sh,
&thumb_w, &thumb_h))
{
result = gdk_pixbuf_scale_simple(pixbuf, thumb_w, thumb_h,
if (!tl || !fd) return FALSE;
thumb_loader_std_reset(tl);
+
+ if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf);
+ fd->thumb_pixbuf = pixbuf_fallback(fd, tl->requested_width, tl->requested_height);
+
if (!stat_utf8(fd->path, &st)) return FALSE;
g_free(tl);
}
-GdkPixbuf *thumb_loader_std_get_pixbuf(ThumbLoaderStd *tl, gint with_fallback)
+GdkPixbuf *thumb_loader_std_get_pixbuf(ThumbLoaderStd *tl)
{
GdkPixbuf *pixbuf;
pixbuf = tl->fd->thumb_pixbuf;
g_object_ref(pixbuf);
}
- else if (with_fallback)
- {
- gint w, h;
-
- pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
- w = gdk_pixbuf_get_width(pixbuf);
- h = gdk_pixbuf_get_height(pixbuf);
-
- if (w > tl->requested_width || h > tl->requested_height)
- {
- gint nw, nh;
-
- if (thumb_loader_std_scale_aspect(tl->requested_width, tl->requested_height,
- w, h, &nw, &nh))
- {
- GdkPixbuf *tmp;
-
- tmp = pixbuf;
- pixbuf = gdk_pixbuf_scale_simple(tmp, nw, nh, GDK_INTERP_TILES);
- g_object_unref(G_OBJECT(tmp));
- }
- }
- }
else
{
- pixbuf = NULL;
+ pixbuf = pixbuf_fallback(NULL, tl->requested_width, tl->requested_height);
}
return pixbuf;
GdkPixbuf *pixbuf;
gint valid = FALSE;
- pixbuf = thumb_loader_std_get_pixbuf(tv->tl, FALSE);
+ /* this function is called on success, so the pixbuf should not be a fallback*/
+ pixbuf = thumb_loader_std_get_pixbuf(tv->tl);
if (pixbuf)
{
const gchar *uri;
TMaintMove *tm = data;
GdkPixbuf *pixbuf;
- pixbuf = thumb_loader_std_get_pixbuf(tm->tl, FALSE);
+ /* this function is called on success, so the pixbuf should not be a fallback*/
+ pixbuf = thumb_loader_std_get_pixbuf(tm->tl);
if (pixbuf)
{
const gchar *uri;
DEBUG_1("thumb move unlink: %s", tm->thumb_path);
unlink_file(tm->thumb_path);
+ g_object_unref(pixbuf);
}
thumb_std_maint_move_step(tm);
gint thumb_loader_std_start(ThumbLoaderStd *tl, FileData *fd);
void thumb_loader_std_free(ThumbLoaderStd *tl);
-GdkPixbuf *thumb_loader_std_get_pixbuf(ThumbLoaderStd *tl, gint with_fallback);
+GdkPixbuf *thumb_loader_std_get_pixbuf(ThumbLoaderStd *tl);
/* validates a non local thumbnail file,