diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2022-06-08 02:45:45 +0200 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2022-06-08 02:51:55 +0200 | 
| commit | 84f8c9436ffb84ca5d443b906f1ffb7be42a50e2 (patch) | |
| tree | 5b9a614080f5b74806e7d37e7292982f9f401406 /fiv-thumbnail.c | |
| parent | a8f7532abdd9eade6ccc7587968e63eea3b5d159 (diff) | |
| download | fiv-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.c | 133 | 
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)  {  | 
