From af2eb411d92028b50f5b54b4b69bbc73cc0cae34 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Mon, 27 Dec 2021 23:51:38 +0100 Subject: Try to regenerate low quality thumbnails --- fiv-browser.c | 11 ++++++++--- fiv-io.c | 26 +++++++++++++++++++++++--- fiv-io.h | 3 +++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/fiv-browser.c b/fiv-browser.c index 597fc85..b85caeb 100644 --- a/fiv-browser.c +++ b/fiv-browser.c @@ -351,6 +351,8 @@ rescale_thumbnail(cairo_surface_t *thumbnail, double row_height) pixman_image_unref(src); pixman_image_unref(dest); + cairo_surface_set_user_data( + scaled, &fiv_io_key_thumbnail_lq, (void *) (intptr_t) 1, NULL); cairo_surface_destroy(thumbnail); cairo_surface_mark_dirty(scaled); return scaled; @@ -490,6 +492,7 @@ on_thumbnailer_ready(GObject *object, GAsyncResult *res, gpointer user_data) static void thumbnailer_next(FivBrowser *self) { + // TODO(p): At least launch multiple thumbnailers in parallel. GList *link = self->thumbnail_queue; if (!link) return; @@ -540,15 +543,17 @@ thumbnailer_start(FivBrowser *self) { thumbnailer_abort(self); - // TODO(p): Also collect rescaled images. - GList *missing = NULL, *rescaled = NULL; + GList *missing = NULL, *lq = NULL; for (guint i = self->entries->len; i--; ) { Entry *entry = &g_array_index(self->entries, Entry, i); if (entry->icon) missing = g_list_prepend(missing, entry); + else if (cairo_surface_get_user_data( + entry->thumbnail, &fiv_io_key_thumbnail_lq)) + lq = g_list_prepend(lq, entry); } - self->thumbnail_queue = g_list_concat(missing, rescaled); + self->thumbnail_queue = g_list_concat(missing, lq); thumbnailer_next(self); } diff --git a/fiv-io.c b/fiv-io.c index 97d10ed..eb2ea81 100644 --- a/fiv-io.c +++ b/fiv-io.c @@ -2288,6 +2288,8 @@ cairo_user_data_key_t fiv_io_key_loops; cairo_user_data_key_t fiv_io_key_page_next; cairo_user_data_key_t fiv_io_key_page_previous; +cairo_user_data_key_t fiv_io_key_thumbnail_lq; + cairo_surface_t * fiv_io_open( const gchar *path, FivIoProfile profile, gboolean enhance, GError **error) @@ -2764,6 +2766,13 @@ FivIoThumbnailSizeInfo // TODO(p): Put the constant in a header file, share with fiv-browser.c. static const double g_wide_thumbnail_factor = 2; +static void +mark_thumbnail_lq(cairo_surface_t *surface) +{ + cairo_surface_set_user_data( + surface, &fiv_io_key_thumbnail_lq, (void *) (intptr_t) 1, NULL); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // In principle similar to rescale_thumbnail() from fiv-browser.c. @@ -2804,6 +2813,7 @@ rescale_thumbnail(cairo_surface_t *thumbnail, double row_height) cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_destroy(cr); + mark_thumbnail_lq(scaled); return scaled; } @@ -2849,6 +2859,8 @@ fiv_io_produce_thumbnail(GFile *target, FivIoThumbnailSize size, GError **error) gchar *sum = g_compute_checksum_for_string(G_CHECKSUM_MD5, uri, -1); gchar *cache_dir = get_xdg_home_dir("XDG_CACHE_HOME", ".cache"); + // TODO(p): Never produce thumbnails for thumbnail directories. + for (int use = size; use >= FIV_IO_THUMBNAIL_SIZE_MIN; use--) { cairo_surface_t *scaled = rescale_thumbnail(surface, fiv_io_thumbnail_sizes[use].size); @@ -3058,7 +3070,7 @@ fiv_io_lookup_thumbnail(GFile *target, FivIoThumbnailSize size) cairo_surface_t *result = NULL; GError *error = NULL; for (int i = 0; i < FIV_IO_THUMBNAIL_SIZE_COUNT; i++) { - int use = size + i; + FivIoThumbnailSize use = size + i; if (use > FIV_IO_THUMBNAIL_SIZE_MAX) use = FIV_IO_THUMBNAIL_SIZE_MAX - i; @@ -3071,8 +3083,13 @@ fiv_io_lookup_thumbnail(GFile *target, FivIoThumbnailSize size) g_clear_error(&error); } g_free(wide); - if (result) + if (result) { + // Higher up we can't distinguish images smaller than the thumbnail. + // Also, try not to rescale the already rescaled. + if (use != size) + mark_thumbnail_lq(result); break; + } gchar *path = g_strdup_printf("%s/thumbnails/%s/%s.png", cache_dir, name, sum); @@ -3082,8 +3099,11 @@ fiv_io_lookup_thumbnail(GFile *target, FivIoThumbnailSize size) g_clear_error(&error); } g_free(path); - if (result) + if (result) { + // Whatever produced it, we may be able to outclass it. + mark_thumbnail_lq(result); break; + } } // TODO(p): We can definitely extract embedded thumbnails, but it should be diff --git a/fiv-io.h b/fiv-io.h index ae39601..29d9807 100644 --- a/fiv-io.h +++ b/fiv-io.h @@ -67,6 +67,9 @@ extern cairo_user_data_key_t fiv_io_key_page_next; /// There is no wrap-around. This is a weak pointer. extern cairo_user_data_key_t fiv_io_key_page_previous; +/// If non-NULL, indicates a thumbnail of insufficient quality. +extern cairo_user_data_key_t fiv_io_key_thumbnail_lq; + cairo_surface_t *fiv_io_open( const gchar *path, FivIoProfile profile, gboolean enhance, GError **error); cairo_surface_t *fiv_io_open_from_data(const char *data, size_t len, -- cgit v1.2.3-70-g09d2