Commit 95c31a31 authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

image preloader: implemented a smarter cache

parent 1e8f2388
......@@ -149,6 +149,7 @@ _cairo_image_surface_create_from_jpeg (GInputStream *istream,
int requested_size,
int *original_width_p,
int *original_height_p,
gboolean *loaded_original_p,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......@@ -536,6 +537,8 @@ _cairo_image_surface_create_from_jpeg (GInputStream *istream,
*original_width_p = original_width;
if (original_height_p != NULL)
*original_height_p = original_height;
if (loaded_original_p != NULL)
*loaded_original_p = ! load_scaled;
jpeg_finish_decompress (&srcinfo);
jpeg_destroy_decompress (&srcinfo);
......
......@@ -32,6 +32,7 @@ GthImage * _cairo_image_surface_create_from_jpeg (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error);
......
......@@ -136,6 +136,7 @@ _cairo_image_surface_create_from_png (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -32,6 +32,7 @@ GthImage * _cairo_image_surface_create_from_png (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error);
......
......@@ -168,6 +168,7 @@ _cairo_image_surface_create_from_svg (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -32,6 +32,7 @@ GthImage * _cairo_image_surface_create_from_svg (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error);
......
......@@ -35,6 +35,7 @@ _cairo_image_surface_create_from_webp (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -32,6 +32,7 @@ GthImage * _cairo_image_surface_create_from_webp (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error);
......
......@@ -954,6 +954,7 @@ _cairo_image_surface_create_from_xcf (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -32,6 +32,7 @@ GthImage * _cairo_image_surface_create_from_xcf (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error);
......
......@@ -933,6 +933,7 @@ image_loader_ready_cb (GObject *source_object,
&image,
&original_width,
&original_height,
NULL,
&error))
{
gth_task_completed (GTH_TASK (self), error);
......
......@@ -404,6 +404,7 @@ facebook_thumbnail_loader (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -411,6 +411,7 @@ flickr_thumbnail_loader (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -119,6 +119,7 @@ image_loader_ready_cb (GObject *source_object,
&image,
NULL,
NULL,
NULL,
&error);
if (error == NULL)
......
......@@ -267,7 +267,7 @@ different_quality_ready_cb (GObject *source_object,
return;
}
if (! _g_file_equal (requested->file, self->priv->file_data->file))
if (! (self->priv->image_changed && requested == NULL) && ! _g_file_equal (requested->file, self->priv->file_data->file))
goto clear_data;
if (image == NULL)
......@@ -295,11 +295,14 @@ clear_data:
static void
update_image_quality_if_required (GthImageViewerPage *self)
{
double zoom;
GthFileData *file_data;
double zoom;
if (self->priv->image_changed || self->priv->loading_image)
if (self->priv->loading_image)
return;
file_data = self->priv->image_changed ? GTH_MODIFIED_IMAGE : self->priv->file_data;
zoom = gth_image_viewer_get_zoom (GTH_IMAGE_VIEWER (self->priv->viewer));
if (zoom >= 1.0) {
int requested_size;
......@@ -312,7 +315,7 @@ update_image_quality_if_required (GthImageViewerPage *self)
&original_height);
if ((requested_size > 0) && (MAX (original_width, original_height) > requested_size)) {
gth_image_preloader_load (self->priv->preloader,
self->priv->file_data,
file_data,
GTH_ORIGINAL_SIZE,
NULL,
different_quality_ready_cb,
......@@ -329,7 +332,7 @@ update_image_quality_if_required (GthImageViewerPage *self)
new_requested_size = _gth_image_preloader_get_requested_size (self);
if (old_requested_size != new_requested_size) {
gth_image_preloader_load (self->priv->preloader,
self->priv->file_data,
file_data,
new_requested_size,
NULL,
different_quality_ready_cb,
......@@ -1395,6 +1398,8 @@ _gth_image_viewer_page_set_image (GthImageViewerPage *self,
if (image == NULL)
return;
if (requested_size == -1)
gth_image_preloader_set_modified_image (self->priv->preloader, image);
gth_image_viewer_set_surface (GTH_IMAGE_VIEWER (self->priv->viewer), image, -1, -1);
gth_image_viewer_set_requested_size (GTH_IMAGE_VIEWER (self->priv->viewer), requested_size);
......
......@@ -337,6 +337,7 @@ picasa_web_thumbnail_loader (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -97,6 +97,7 @@ _libraw_read_jpeg_data (void *buffer,
NULL,
NULL,
NULL,
NULL,
cancellable,
error);
......@@ -226,6 +227,7 @@ _cairo_image_surface_create_from_raw (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......@@ -268,6 +270,9 @@ _cairo_image_surface_create_from_raw (GInputStream *istream,
if (requested_size > 0) {
if (loaded_original != NULL)
*loaded_original = FALSE;
/* read the thumbnail */
result = libraw_unpack_thumb (raw_data);
......@@ -464,6 +469,7 @@ dcraw_pixbuf_animation_new_from_file (GInputStream *istream,
int requested_size,
int *original_width,
int *original_height,
gboolean *loaded_original,
gpointer user_data,
GCancellable *cancellable,
GError **error)
......
......@@ -2569,6 +2569,7 @@ image_loader_ready_cb (GObject *source_object,
&image,
NULL,
NULL,
NULL,
NULL))
{
load_next_file (self);
......
......@@ -26,6 +26,7 @@
#include "cairo-utils.h"
#include "cairo-scale.h"
#include "gfixed.h"
#include "glib-utils.h"
#define CLAMP_PIXEL(v) (((v) <= 0) ? 0 : ((v) >= 255) ? 255 : (v));
......@@ -503,13 +504,14 @@ _cairo_image_surface_scale (cairo_surface_t *image,
scale_filter_t filter,
GthAsyncTask *task)
{
int src_width;
int src_height;
cairo_surface_t *scaled;
resize_filter_t *resize_filter;
ScaleReal x_factor;
ScaleReal y_factor;
cairo_surface_t *tmp;
int src_width;
int src_height;
cairo_surface_t *scaled;
cairo_surface_metadata_t *metadata;
resize_filter_t *resize_filter;
ScaleReal x_factor;
ScaleReal y_factor;
cairo_surface_t *tmp;
src_width = cairo_image_surface_get_width (image);
src_height = cairo_image_surface_get_height (image);
......@@ -520,6 +522,10 @@ _cairo_image_surface_scale (cairo_surface_t *image,
scaled = _cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
scaled_width,
scaled_height);
metadata = _cairo_image_surface_get_metadata (scaled);
metadata->original_width = src_width;
metadata->original_height = src_height;
if (scaled == NULL)
return NULL;
......@@ -905,3 +911,115 @@ _cairo_image_surface_scale_bilinear (cairo_surface_t *image,
return tmp2;
}
/* -- _cairo_image_surface_scale_async -- */
typedef struct {
cairo_surface_t *original;
int new_width;
int new_height;
scale_filter_t quality;
cairo_surface_t *scaled;
GthTask *task;
} ScaleData;
static ScaleData *
scale_data_new (cairo_surface_t *image,
int new_width,
int new_height,
scale_filter_t quality,
GCancellable *cancellable)
{
ScaleData *scale_data;
scale_data = g_new0 (ScaleData, 1);
scale_data->original = cairo_surface_reference (image);
scale_data->new_width = new_width;
scale_data->new_height = new_height;
scale_data->quality = quality;
scale_data->scaled = NULL;
scale_data->task = gth_async_task_new (NULL, NULL, NULL, NULL, NULL);
gth_task_set_cancellable (scale_data->task, cancellable);
return scale_data;
}
static void
scale_data_free (ScaleData *scale_data)
{
_g_object_unref (scale_data->task);
cairo_surface_destroy (scale_data->scaled);
cairo_surface_destroy (scale_data->original);
g_free (scale_data);
}
static void
scale_image_thread (GSimpleAsyncResult *result,
GObject *object,
GCancellable *cancellable)
{
ScaleData *scale_data;
scale_data = g_simple_async_result_get_op_res_gpointer (result);
scale_data->scaled = _cairo_image_surface_scale (scale_data->original,
scale_data->new_width,
scale_data->new_height,
scale_data->quality,
GTH_ASYNC_TASK (scale_data->task));
}
void
_cairo_image_surface_scale_async (cairo_surface_t *image,
int new_width,
int new_height,
scale_filter_t quality,
GCancellable *cancellable,
GAsyncReadyCallback ready_callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
result = g_simple_async_result_new (NULL,
ready_callback,
user_data,
_cairo_image_surface_scale_async);
g_simple_async_result_set_op_res_gpointer (result,
scale_data_new (image,
new_width,
new_height,
quality,
cancellable),
(GDestroyNotify) scale_data_free);
g_simple_async_result_run_in_thread (result,
scale_image_thread,
G_PRIORITY_DEFAULT,
cancellable);
g_object_unref (result);
}
cairo_surface_t *
_cairo_image_surface_scale_finish (GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
ScaleData *scale_data;
g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, _cairo_image_surface_scale_async), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
scale_data = g_simple_async_result_get_op_res_gpointer (simple);
return cairo_surface_reference (scale_data->scaled);
}
......@@ -47,21 +47,30 @@ typedef enum /*< skip >*/ {
} scale_filter_t;
cairo_surface_t * _cairo_image_surface_scale_nearest (cairo_surface_t *image,
int new_width,
int new_height);
cairo_surface_t * _cairo_image_surface_scale (cairo_surface_t *image,
int width,
int height,
scale_filter_t quality,
GthAsyncTask *task);
cairo_surface_t * _cairo_image_surface_scale_squared (cairo_surface_t *image,
int size,
scale_filter_t quality,
GthAsyncTask *task);
cairo_surface_t * _cairo_image_surface_scale_bilinear (cairo_surface_t *image,
int new_width,
int new_height);
cairo_surface_t * _cairo_image_surface_scale_nearest (cairo_surface_t *image,
int new_width,
int new_height);
cairo_surface_t * _cairo_image_surface_scale (cairo_surface_t *image,
int width,
int height,
scale_filter_t quality,
GthAsyncTask *task);
cairo_surface_t * _cairo_image_surface_scale_squared (cairo_surface_t *image,
int size,
scale_filter_t quality,
GthAsyncTask *task);
cairo_surface_t * _cairo_image_surface_scale_bilinear (cairo_surface_t *image,
int new_width,
int new_height);
void _cairo_image_surface_scale_async (cairo_surface_t *image,
int new_width,
int new_height,
scale_filter_t quality,
GCancellable *cancellable,
GAsyncReadyCallback ready_callback,
gpointer user_data);
cairo_surface_t * _cairo_image_surface_scale_finish (GAsyncResult *result,
GError **error);
G_END_DECLS
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment