aboutsummaryrefslogtreecommitdiff
path: root/fiv-thumbnail.c
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2022-06-08 02:45:45 +0200
committerPřemysl Eric Janouch <p@janouch.name>2022-06-08 02:51:55 +0200
commit84f8c9436ffb84ca5d443b906f1ffb7be42a50e2 (patch)
tree5b9a614080f5b74806e7d37e7292982f9f401406 /fiv-thumbnail.c
parenta8f7532abdd9eade6ccc7587968e63eea3b5d159 (diff)
downloadfiv-84f8c9436ffb84ca5d443b906f1ffb7be42a50e2.tar.gz
fiv-84f8c9436ffb84ca5d443b906f1ffb7be42a50e2.tar.xz
fiv-84f8c9436ffb84ca5d443b906f1ffb7be42a50e2.zip
Downscale embedded thumbnails within minions
Otherwise the UI would become unresponsive during loading.
Diffstat (limited to 'fiv-thumbnail.c')
-rw-r--r--fiv-thumbnail.c133
1 files changed, 70 insertions, 63 deletions
diff --git a/fiv-thumbnail.c b/fiv-thumbnail.c
index aee3d49..1a9213a 100644
--- a/fiv-thumbnail.c
+++ b/fiv-thumbnail.c
@@ -130,69 +130,6 @@ render(GFile *target, GBytes *data, gboolean *color_managed, GError **error)
return surface;
}
-cairo_surface_t *
-fiv_thumbnail_extract(GFile *target, GError **error)
-{
- const char *path = g_file_peek_path(target);
- if (!path) {
- set_error(error, "thumbnails will only be extracted from local files");
- return NULL;
- }
-
- GMappedFile *mf = g_mapped_file_new(path, FALSE, error);
- if (!mf)
- return NULL;
-
- cairo_surface_t *surface = NULL;
-#ifndef HAVE_LIBRAW
- // TODO(p): Implement our own thumbnail extractors.
- set_error(error, "unsupported file");
-#else // HAVE_LIBRAW
- libraw_data_t *iprc = libraw_init(
- LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
- if (!iprc) {
- set_error(error, "failed to obtain a LibRaw handle");
- goto fail;
- }
-
- int err = 0;
- if ((err = libraw_open_buffer(iprc, (void *) g_mapped_file_get_contents(mf),
- g_mapped_file_get_length(mf))) ||
- (err = libraw_unpack_thumb(iprc))) {
- set_error(error, libraw_strerror(err));
- goto fail_libraw;
- }
-
- libraw_processed_image_t *image = libraw_dcraw_make_mem_thumb(iprc, &err);
- if (!image) {
- set_error(error, libraw_strerror(err));
- goto fail_libraw;
- }
-
- gboolean dummy = FALSE;
- switch (image->type) {
- case LIBRAW_IMAGE_JPEG:
- surface = render(
- target, g_bytes_new(image->data, image->data_size), &dummy, error);
- break;
- case LIBRAW_IMAGE_BITMAP:
- // TODO(p): Implement this one as well.
- default:
- set_error(error, "unsupported embedded thumbnail");
- }
-
- libraw_dcraw_clear_mem(image);
-fail_libraw:
- libraw_close(iprc);
-#endif // HAVE_LIBRAW
-
-fail:
- g_mapped_file_unref(mf);
- return surface;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
// In principle similar to rescale_thumbnail() from fiv-browser.c.
static cairo_surface_t *
adjust_thumbnail(cairo_surface_t *thumbnail, double row_height)
@@ -264,6 +201,76 @@ adjust_thumbnail(cairo_surface_t *thumbnail, double row_height)
return scaled;
}
+cairo_surface_t *
+fiv_thumbnail_extract(GFile *target, FivThumbnailSize max_size, GError **error)
+{
+ const char *path = g_file_peek_path(target);
+ if (!path) {
+ set_error(error, "thumbnails will only be extracted from local files");
+ return NULL;
+ }
+
+ GMappedFile *mf = g_mapped_file_new(path, FALSE, error);
+ if (!mf)
+ return NULL;
+
+ cairo_surface_t *surface = NULL;
+#ifndef HAVE_LIBRAW
+ // TODO(p): Implement our own thumbnail extractors.
+ set_error(error, "unsupported file");
+#else // HAVE_LIBRAW
+ libraw_data_t *iprc = libraw_init(
+ LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
+ if (!iprc) {
+ set_error(error, "failed to obtain a LibRaw handle");
+ goto fail;
+ }
+
+ int err = 0;
+ if ((err = libraw_open_buffer(iprc, (void *) g_mapped_file_get_contents(mf),
+ g_mapped_file_get_length(mf))) ||
+ (err = libraw_unpack_thumb(iprc))) {
+ set_error(error, libraw_strerror(err));
+ goto fail_libraw;
+ }
+
+ libraw_processed_image_t *image = libraw_dcraw_make_mem_thumb(iprc, &err);
+ if (!image) {
+ set_error(error, libraw_strerror(err));
+ goto fail_libraw;
+ }
+
+ gboolean dummy = FALSE;
+ switch (image->type) {
+ case LIBRAW_IMAGE_JPEG:
+ surface = render(
+ target, g_bytes_new(image->data, image->data_size), &dummy, error);
+ break;
+ case LIBRAW_IMAGE_BITMAP:
+ // TODO(p): Implement this one as well.
+ default:
+ set_error(error, "unsupported embedded thumbnail");
+ }
+
+ libraw_dcraw_clear_mem(image);
+fail_libraw:
+ libraw_close(iprc);
+#endif // HAVE_LIBRAW
+
+fail:
+ g_mapped_file_unref(mf);
+ if (!surface || max_size < FIV_THUMBNAIL_SIZE_MIN ||
+ max_size > FIV_THUMBNAIL_SIZE_MAX)
+ return surface;
+
+ cairo_surface_t *result =
+ adjust_thumbnail(surface, fiv_thumbnail_sizes[max_size].size);
+ cairo_surface_destroy(surface);
+ return result;
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
static WebPData
encode_thumbnail(cairo_surface_t *surface)
{