Downscale embedded thumbnails within minions
Otherwise the UI would become unresponsive during loading.
This commit is contained in:
		
							
								
								
									
										133
									
								
								fiv-thumbnail.c
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								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)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user