50
GthFileData *file_data;
55
gboolean loaded_original;
47
GthImagePreloader *self;
48
GthFileData *file_data;
53
GthImageLoader *loader;
63
GthImagePreloader *preloader;
64
GList *files; /* List of GthFileData */
66
GList *requested_file;
68
GSimpleAsyncResult *result;
69
GCancellable *cancellable;
62
GthImagePreloader *self;
63
GthFileData *requested;
73
71
struct _GthImagePreloaderPrivate {
74
GList *requests; /* List of LoadRequest */
75
LoadRequest *current_request;
76
LoadRequest *last_request;
77
GthImageLoader *loader;
72
GthLoadPolicy load_policy;
74
Preloader **loader; /* Array of loaders, each loader
75
* will load an image. */
76
int requested; /* This is the loader with the
77
* requested image. The
78
* requested image is the image
79
* the user has expressly
80
* requested to view, when this
82
* requested_ready signal is
84
* Other images do not trigger
86
GFile *requested_file;
88
int current; /* This is the loader that has
89
* a loading underway. */
91
GCancellable *cancellable;
93
LoadData *next_load_data;
97
static guint gth_image_preloader_signals[LAST_SIGNAL] = { 0 };
83
100
G_DEFINE_TYPE (GthImagePreloader, gth_image_preloader, G_TYPE_OBJECT)
92
CacheData *cache_data;
94
cache_data = g_new0 (CacheData, 1);
96
cache_data->file_data = NULL;
97
cache_data->image = NULL;
98
cache_data->original_width = -1;
99
cache_data->original_height = -1;
100
cache_data->requested_size = -1;
101
cache_data->error = NULL;
102
cache_data->loaded_original = FALSE;
109
cache_data_ref (CacheData *cache_data)
117
cache_data_unref (CacheData *cache_data)
119
if (cache_data == NULL)
121
if (--cache_data->ref > 0)
124
g_clear_error (&cache_data->error);
125
_g_object_unref (cache_data->image);
126
_g_object_unref (cache_data->file_data);
131
static inline gboolean
132
cache_data_file_matches (CacheData *cache_data,
133
GthFileData *file_data)
135
if ((file_data == GTH_MODIFIED_IMAGE) && (cache_data->file_data == GTH_MODIFIED_IMAGE))
138
if ((file_data == GTH_MODIFIED_IMAGE) || (cache_data->file_data == GTH_MODIFIED_IMAGE))
141
if (g_file_equal (cache_data->file_data->file, file_data->file)
142
&& (_g_time_val_cmp (gth_file_data_get_modification_time (file_data),
143
gth_file_data_get_modification_time (cache_data->file_data)) == 0))
153
cache_data_is_valid_for_request (CacheData *cache_data,
154
GthFileData *file_data,
157
if (! cache_data_file_matches (cache_data, file_data))
160
return cache_data->requested_size == requested_size;
165
cache_data_has_better_quality_for_request (CacheData *cache_data,
166
GthFileData *file_data,
169
if (! cache_data_file_matches (cache_data, file_data))
172
if (requested_size == GTH_ORIGINAL_SIZE)
175
return (cache_data->requested_size > requested_size) || (cache_data->requested_size == GTH_ORIGINAL_SIZE);
179
/* -- LoadRequest -- */
183
load_request_new (GthImagePreloader *preloader)
185
LoadRequest *request;
187
request = g_new0 (LoadRequest, 1);
189
request->finalized = FALSE;
190
request->preloader = preloader;
191
request->files = NULL;
192
request->current_file = NULL;
193
request->requested_size = GTH_ORIGINAL_SIZE;
194
request->result = NULL;
195
request->cancellable = NULL;
202
load_request_ref (LoadRequest *request)
210
load_request_unref (LoadRequest *request)
214
if (--request->ref > 0)
217
_g_object_unref (request->cancellable);
218
_g_object_unref (request->result);
219
_g_object_list_unref (request->files);
103
/* -- Preloader -- */
107
preloader_new (GthImagePreloader *self)
109
Preloader *preloader;
111
preloader = g_new0 (Preloader, 1);
113
preloader->self = self;
114
preloader->file_data = NULL;
115
preloader->loaded = FALSE;
116
preloader->error = FALSE;
117
preloader->finalized = FALSE;
118
preloader->loader = gth_image_loader_new (NULL, NULL);
119
gth_image_loader_set_preferred_format (preloader->loader, GTH_IMAGE_FORMAT_CAIRO_SURFACE);
120
preloader->image = NULL;
121
preloader->original_width = -1;
122
preloader->original_height = -1;
129
preloader_ref (Preloader *preloader)
137
preloader_unref (Preloader *preloader)
139
if (preloader == NULL)
141
if (--preloader->ref > 0)
143
_g_object_unref (preloader->image);
144
_g_object_unref (preloader->loader);
145
_g_object_unref (preloader->file_data);
151
preloader_set_file_data (Preloader *preloader,
152
GthFileData *file_data)
154
g_return_if_fail (preloader != NULL);
156
if (preloader->file_data != file_data) {
157
_g_object_unref (preloader->file_data);
158
preloader->file_data = NULL;
161
if (file_data != NULL)
162
preloader->file_data = g_object_ref (file_data);
164
preloader->loaded = FALSE;
165
preloader->error = FALSE;
170
preloader_has_valid_content_for_file (Preloader *preloader,
171
GthFileData *file_data)
173
return ((preloader->file_data != NULL)
175
&& ! preloader->error
176
&& (preloader->image != NULL)
177
&& g_file_equal (preloader->file_data->file, file_data->file)
178
&& (_g_time_val_cmp (gth_file_data_get_modification_time (file_data),
179
gth_file_data_get_modification_time (preloader->file_data)) == 0));
184
preloader_needs_to_load (Preloader *preloader)
186
return ((preloader->token == preloader->self->priv->token)
187
&& (preloader->file_data != NULL)
188
&& ! preloader->error
189
&& ! preloader->loaded);
194
preloader_needs_second_step (Preloader *preloader)
196
return ((preloader->token == preloader->self->priv->token)
197
&& ! preloader->error
198
&& (preloader->requested_size != -1)
199
&& ((preloader->original_width > preloader->requested_size) || (preloader->original_height > preloader->requested_size))
200
&& (preloader->image != NULL)
201
&& ! gth_image_is_animation (preloader->image));
206
preloader_signal_to_emit (Preloader *preloader)
210
switch (preloader->self->priv->load_policy) {
211
case GTH_LOAD_POLICY_ONE_STEP:
212
signal = REQUESTED_READY;
215
case GTH_LOAD_POLICY_TWO_STEPS:
216
if (preloader->self->priv->requested_size == -1)
217
signal = ORIGINAL_SIZE_READY;
219
signal = REQUESTED_READY;
223
g_assert (signal != -1);
224
229
/* -- GthImagePreloader -- */
232
static void load_data_free (LoadData *load_data);
228
236
gth_image_preloader_finalize (GObject *object)
230
238
GthImagePreloader *self;
233
241
g_return_if_fail (object != NULL);
234
242
g_return_if_fail (GTH_IS_IMAGE_PRELOADER (object));
236
244
self = GTH_IMAGE_PRELOADER (object);
238
if (self->priv->load_next_id != 0)
239
g_source_remove (self->priv->load_next_id);
240
load_request_unref (self->priv->last_request);
241
load_request_unref (self->priv->current_request);
243
for (scan = self->priv->requests; scan; scan = scan->next) {
244
LoadRequest *request = scan->data;
246
request->finalized = TRUE;
247
load_request_unref (request);
249
g_list_free (self->priv->requests);
251
g_object_unref (self->priv->loader);
252
g_queue_free_full (self->priv->cache, (GDestroyNotify) cache_data_unref);
246
if (self->priv->load_id != 0) {
247
g_source_remove (self->priv->load_id);
248
self->priv->load_id = 0;
251
if (self->priv->next_load_data != NULL) {
252
load_data_free (self->priv->next_load_data);
253
self->priv->next_load_data = NULL;
256
for (i = 0; i < self->priv->n_preloaders; i++) {
257
self->priv->loader[i]->finalized = TRUE;
258
preloader_unref (self->priv->loader[i]);
259
self->priv->loader[i] = NULL;
261
g_free (self->priv->loader);
262
_g_object_unref (self->priv->requested_file);
263
g_object_unref (self->priv->cancellable);
254
265
G_OBJECT_CLASS (gth_image_preloader_parent_class)->finalize (object);
271
311
gth_image_preloader_init (GthImagePreloader *self)
273
313
self->priv = GTH_IMAGE_PRELOADER_GET_PRIVATE (self);
274
self->priv->requests = NULL;
275
self->priv->current_request = NULL;
276
self->priv->last_request = NULL;
277
self->priv->loader = gth_image_loader_new (NULL, NULL);
278
self->priv->cache = g_queue_new ();
279
self->priv->load_next_id = 0;
314
self->priv->loader = NULL;
315
self->priv->requested = -1;
316
self->priv->requested_file = NULL;
317
self->priv->current = -1;
318
self->priv->load_policy = GTH_LOAD_POLICY_ONE_STEP;
319
self->priv->cancellable = g_cancellable_new ();
320
self->priv->token = 0;
283
324
GthImagePreloader *
284
gth_image_preloader_new (void)
286
return (GthImagePreloader *) g_object_new (GTH_TYPE_IMAGE_PRELOADER, NULL);
325
gth_image_preloader_new (GthLoadPolicy load_policy,
328
GthImagePreloader *self;
331
g_return_val_if_fail (n_preloaders > 0, NULL);
333
self = g_object_new (GTH_TYPE_IMAGE_PRELOADER, NULL);
335
self->priv->n_preloaders = n_preloaders;
336
self->priv->load_policy = load_policy;
337
self->priv->loader = g_new0 (Preloader *, self->priv->n_preloaders);
338
for (i = 0; i < self->priv->n_preloaders; i++)
339
self->priv->loader[i] = preloader_new (self);
346
gth_image_prelaoder_set_load_policy (GthImagePreloader *self,
347
GthLoadPolicy policy)
349
self->priv->load_policy = policy;
354
gth_image_prelaoder_get_load_policy (GthImagePreloader *self)
356
return self->priv->load_policy;
290
360
/* -- gth_image_preloader_load -- */
294
_gth_image_preloader_lookup_same_size (GthImagePreloader *self,
295
GthFileData *requested_file,
300
for (scan = self->priv->cache->head; scan; scan = scan->next) {
301
CacheData *cache_data = scan->data;
302
if (cache_data_is_valid_for_request (cache_data, requested_file, requested_size))
311
_gth_image_preloader_lookup_bigger_size (GthImagePreloader *self,
312
GthFileData *requested_file,
317
if (requested_file != GTH_MODIFIED_IMAGE)
320
if (requested_size == GTH_ORIGINAL_SIZE)
323
for (scan = self->priv->cache->head; scan; scan = scan->next) {
324
CacheData *cache_data = scan->data;
325
if (cache_data_has_better_quality_for_request (cache_data, requested_file, requested_size))
334
_gth_image_preloader_request_finished (GthImagePreloader *self,
335
LoadRequest *load_request)
337
if (self->priv->last_request == load_request)
338
self->priv->last_request = NULL;
339
load_request_unref (self->priv->current_request);
340
self->priv->current_request = NULL;
341
load_request_unref (load_request);
346
_gth_image_preloader_load_current_file (GthImagePreloader *self,
347
LoadRequest *request);
363
static void start_next_loader (GthImagePreloader *self);
351
load_current_file (gpointer user_data)
367
load_next (gpointer data)
353
LoadRequest *request = user_data;
354
GthImagePreloader *self = request->preloader;
356
g_return_val_if_fail (request->current_file != NULL, FALSE);
358
if (self->priv->load_next_id > 0) {
359
g_source_remove (self->priv->load_next_id);
360
self->priv->load_next_id = 0;
369
GthImagePreloader *self = data;
371
if (self->priv->load_id != 0) {
372
g_source_remove (self->priv->load_id);
373
self->priv->load_id = 0;
362
_gth_image_preloader_load_current_file (self, request);
375
start_next_loader (self);
369
_gth_image_preloader_request_completed (GthImagePreloader *self,
370
LoadRequest *request,
371
CacheData *cache_data)
373
if (request->current_file == request->requested_file) {
374
if (cache_data != NULL) {
375
#ifdef DEBUG_PRELOADER
377
cairo_surface_t *image;
381
if (cache_data->image != NULL)
382
image = gth_image_get_cairo_surface (cache_data->image);
384
w = cairo_image_surface_get_width (image);
385
h = cairo_image_surface_get_height (image);
392
g_print (" --> done @%d [%dx%d]\n",
393
cache_data->requested_size,
399
g_simple_async_result_set_op_res_gpointer (request->result,
400
cache_data_ref (cache_data),
401
(GDestroyNotify) cache_data_unref);
402
g_simple_async_result_complete_in_idle (request->result);
407
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "");
408
g_simple_async_result_set_from_error (request->result, error);
410
g_error_free (error);
414
/* queue the next file */
416
g_return_if_fail (request->current_file != NULL);
420
GthFileData *requested_file;
422
request->current_file = request->current_file->next;
423
if (request->current_file == NULL) {
424
_gth_image_preloader_request_finished (self, request);
428
requested_file = (GthFileData *) request->current_file->data;
429
cache_data = _gth_image_preloader_lookup_same_size (self,
431
request->requested_size);
433
while (cache_data != NULL);
435
if (self->priv->load_next_id > 0)
436
g_source_remove (self->priv->load_next_id);
437
self->priv->load_next_id = g_timeout_add (LOAD_NEXT_FILE_DELAY,
444
_gth_image_preloader_start_request (GthImagePreloader *self,
445
LoadRequest *request);
449
_gth_image_preloader_add_to_cache (GthImagePreloader *self,
450
CacheData *cache_data)
452
if (g_queue_get_length (self->priv->cache) > CACHE_MAX_SIZE) {
453
CacheData *oldest = g_queue_pop_tail (self->priv->cache);
454
cache_data_unref (oldest);
456
g_queue_push_head (self->priv->cache, cache_data);
461
LoadRequest *request;
462
gboolean resize_to_requested_size;
467
load_data_new (LoadRequest *request,
468
gboolean resize_image)
472
load_data = g_new0 (LoadData, 1);
473
load_data->request = load_request_ref (request);
474
load_data->resize_to_requested_size = resize_image;
481
load_data_free (LoadData *load_data)
483
load_request_unref (load_data->request);
488
#ifdef RESIZE_TO_REQUESTED_SIZE
491
image_scale_ready_cb (GObject *source_object,
492
GAsyncResult *result,
495
LoadData *load_data = user_data;
496
LoadRequest *request = load_data->request;
497
GthImagePreloader *self = request->preloader;
498
cairo_surface_t *surface;
499
GError *error = NULL;
502
CacheData *cache_data;
504
if (request->finalized) {
505
load_data_free (load_data);
509
surface = _cairo_image_surface_scale_finish (result, &error);
511
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
512
|| (self->priv->last_request != request))
514
load_data_free (load_data);
516
g_error_free (error);
517
cairo_surface_destroy (surface);
518
_gth_image_preloader_request_finished (self, request);
520
if (self->priv->last_request != NULL)
521
_gth_image_preloader_start_request (self, self->priv->last_request);
526
if (! _cairo_image_surface_get_original_size (surface, &original_width, &original_height)) {
527
original_width = cairo_image_surface_get_width (surface);
528
original_height = cairo_image_surface_get_height (surface);
530
cache_data = cache_data_new ();
531
cache_data->file_data = _g_object_ref (request->current_file->data);
532
cache_data->image = (surface != NULL) ? gth_image_new_for_surface (surface) : NULL;
533
cache_data->original_width = (surface != NULL) ? original_width : -1;
534
cache_data->original_height = (surface != NULL) ? original_height : -1;
535
cache_data->requested_size = request->requested_size;
536
cache_data->error = error;
537
_gth_image_preloader_add_to_cache (self, cache_data);
538
_gth_image_preloader_request_completed (self, request, cache_data);
540
cairo_surface_destroy (surface);
541
load_data_free (load_data);
546
_gth_image_preloader_resize_at_requested_size (GthImagePreloader *self,
547
LoadRequest *request,
550
cairo_surface_t *surface;
555
surface = gth_image_get_cairo_surface (image);
556
new_width = cairo_image_surface_get_width (surface);
557
new_height = cairo_image_surface_get_height (surface);
558
scaled = scale_keeping_ratio (&new_width,
560
request->requested_size,
561
request->requested_size,
565
_cairo_image_surface_scale_async (surface,
569
request->cancellable,
570
image_scale_ready_cb,
571
load_data_new (request, FALSE));
573
cairo_surface_destroy (surface);
382
Preloader *preloader;
383
GthFileData *file_data;
389
load_request_free (LoadRequest *load_request)
391
preloader_unref (load_request->preloader);
392
g_object_unref (load_request->file_data);
393
g_free (load_request);
397
static void assign_loaders (LoadData *load_data);
583
402
GAsyncResult *result,
584
403
gpointer user_data)
586
LoadData *load_data = user_data;
587
LoadRequest *request = load_data->request;
588
GthImagePreloader *self = request->preloader;
589
GthImage *image = NULL;
592
gboolean loaded_original;
593
GError *error = NULL;
595
CacheData *cache_data;
405
LoadRequest *load_request = user_data;
406
Preloader *preloader = load_request->preloader;
407
GthImagePreloader *self = preloader->self;
408
GthImage *image = NULL;
411
GError *error = NULL;
598
if (request->finalized) {
599
#ifdef DEBUG_PRELOADER
600
g_print (" --> cancelled\n");
602
load_data_free (load_data);
415
if (preloader->finalized) {
416
load_request_free (load_request);
420
self->priv->current = -1;
606
422
success = gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
610
426
&original_height,
614
429
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
615
|| (self->priv->last_request != request))
430
|| ! g_file_equal (load_request->file_data->file, preloader->file_data->file)
431
|| (preloader->token != self->priv->token))
617
#ifdef DEBUG_PRELOADER
618
g_print (" --> cancelled\n");
620
load_data_free (load_data);
433
load_request_free (load_request);
621
434
if (error != NULL)
622
435
g_error_free (error);
623
436
_g_object_unref (image);
624
_gth_image_preloader_request_finished (self, request);
626
if (self->priv->last_request != NULL)
627
_gth_image_preloader_start_request (self, self->priv->last_request);
438
if (self->priv->next_load_data != NULL) {
439
assign_loaders (self->priv->next_load_data);
440
start_next_loader (self);
442
load_data_free (self->priv->next_load_data);
443
self->priv->next_load_data = NULL;
632
cache_data = cache_data_new ();
633
cache_data->file_data = g_object_ref (request->current_file->data);
634
cache_data->image = success ? _g_object_ref (image) : NULL;
635
cache_data->original_width = success ? original_width : -1;
636
cache_data->original_height = success ? original_height : -1;
637
cache_data->requested_size = request->requested_size;
638
cache_data->loaded_original = loaded_original;
639
cache_data->error = error;
640
_gth_image_preloader_add_to_cache (self, cache_data);
642
if ((request->requested_size > 0) && loaded_original)
643
load_data->resize_to_requested_size = TRUE;
645
if ((image != NULL) && (gth_image_get_is_zoomable (image) || gth_image_get_is_animation (image)))
646
load_data->resize_to_requested_size = FALSE;
649
#ifdef RESIZE_TO_REQUESTED_SIZE
650
if (load_data->resize_to_requested_size)
651
resized = _gth_image_preloader_resize_at_requested_size (self, request, cache_data->image);
655
_gth_image_preloader_request_completed (self, request, cache_data);
449
interval = NOT_REQUESTED_INTERVAL;
451
_g_object_unref (preloader->image);
452
preloader->image = _g_object_ref (image);
453
preloader->original_width = original_width;
454
preloader->original_height = original_height;
455
preloader->loaded = success;
456
preloader->error = ! success;
457
preloader->requested_size = load_request->requested_size;
459
if (_g_file_equal (load_request->file_data->file, self->priv->requested_file)) {
461
debug (DEBUG_INFO, "loaded [requested] %s => %s [size: %d]", (error == NULL) ? "ready" : "error", g_file_get_uri (preloader->file_data->file), preloader->requested_size);
464
g_signal_emit (G_OBJECT (self),
465
gth_image_preloader_signals[preloader_signal_to_emit (preloader)],
467
preloader->file_data,
469
preloader->original_width,
470
preloader->original_height,
473
/* Reload only if the original size is bigger then the
474
* requested size, and if the image is not an animation. */
476
if (preloader_needs_second_step (preloader)) {
477
/* Reload the image at the original size */
478
preloader->loaded = FALSE;
479
preloader->requested_size = -1;
480
interval = SECOND_STEP_INTERVAL;
483
interval = REQUESTED_INTERVAL;
487
debug (DEBUG_INFO, "loaded [non-requested] %s => %s [size: %d]", (error == NULL) ? "ready" : "error", g_file_get_uri (preloader->file_data->file), preloader->requested_size);
490
if (self->priv->load_id == 0)
491
self->priv->load_id = g_timeout_add (interval, load_next, self);
493
load_request_free (load_request);
657
494
_g_object_unref (image);
658
load_data_free (load_data);
663
_gth_image_preloader_load_current_file (GthImagePreloader *self,
664
LoadRequest *request)
666
GthFileData *requested_file;
667
CacheData *cache_data;
668
gboolean ignore_requested_size;
670
g_return_if_fail (request->current_file != NULL);
671
requested_file = (GthFileData *) request->current_file->data;
673
/* search the file at the requested size */
675
cache_data = _gth_image_preloader_lookup_same_size (self,
677
request->requested_size);
678
if (cache_data != NULL) {
679
_gth_image_preloader_request_completed (self, request, cache_data);
683
/* search the file at a bigger size */
685
cache_data = _gth_image_preloader_lookup_bigger_size (self,
687
request->requested_size);
688
if (cache_data != NULL) {
689
#ifdef RESIZE_TO_REQUESTED_SIZE
690
if (! _gth_image_preloader_resize_at_requested_size (self, request, cache_data->image))
692
_gth_image_preloader_request_completed (self, request, cache_data);
696
/* load the file at the requested size */
698
if (requested_file == GTH_MODIFIED_IMAGE) {
700
_gth_image_preloader_request_completed (self, request, NULL);
704
ignore_requested_size = (request->requested_size > 0) && ! g_file_is_native (requested_file->file);
706
#ifdef DEBUG_PRELOADER
707
g_print ("load %s @%d\n", g_file_get_uri (requested_file->file), ignore_requested_size ? -1 : request->requested_size);
710
gth_image_loader_load (self->priv->loader,
712
ignore_requested_size ? -1 : request->requested_size,
713
(request->current_file == request->files) ? G_PRIORITY_HIGH : G_PRIORITY_DEFAULT,
714
request->cancellable,
715
image_loader_ready_cb,
716
load_data_new (request, ignore_requested_size));
721
_gth_image_preloader_start_request (GthImagePreloader *self,
722
LoadRequest *request)
724
load_request_unref (self->priv->current_request);
725
self->priv->current_request = load_request_ref (request);
727
request->current_file = request->files;
728
_gth_image_preloader_load_current_file (self, request);
733
_gth_image_preloader_cancel_current_request (GthImagePreloader *self)
735
if (self->priv->current_request == NULL)
738
if (self->priv->load_next_id > 0) {
739
g_source_remove (self->priv->load_next_id);
740
self->priv->load_next_id = 0;
742
_gth_image_preloader_request_finished (self, self->priv->current_request);
743
_gth_image_preloader_start_request (self, self->priv->last_request);
499
current_preloader (GthImagePreloader *self)
501
return (self->priv->current == -1) ? NULL : self->priv->loader[self->priv->current];
506
requested_preloader (GthImagePreloader *self)
508
return (self->priv->requested == -1) ? NULL : self->priv->loader[self->priv->requested];
513
start_next_loader (GthImagePreloader *self)
516
Preloader *preloader;
520
if (preloader_needs_to_load (requested_preloader (self))) {
521
i = self->priv->requested;
526
if (self->priv->current == -1)
529
i = (self->priv->current + 1) % self->priv->n_preloaders;
531
for (i = 0; n < self->priv->n_preloaders; i = (i + 1) % self->priv->n_preloaders) {
532
if (preloader_needs_to_load (self->priv->loader[i]))
537
if (n >= self->priv->n_preloaders)
541
self->priv->current = i;
542
preloader = current_preloader (self);
544
if (preloader != NULL) {
545
LoadRequest *load_request;
551
uri = g_file_get_uri (preloader->file_data->file);
552
debug (DEBUG_INFO, "load %s [size: %d]", uri, preloader->requested_size);
557
_g_object_unref (preloader->image);
558
preloader->image = NULL;
560
load_request = g_new0 (LoadRequest, 1);
561
load_request->preloader = preloader_ref (preloader);
562
load_request->file_data = g_object_ref (preloader->file_data);
563
load_request->requested_size = preloader->requested_size;
565
g_cancellable_reset (preloader->self->priv->cancellable);
566
gth_image_loader_load (preloader->loader,
567
preloader->file_data,
568
preloader->requested_size,
569
(i == self->priv->requested) ? G_PRIORITY_HIGH : G_PRIORITY_DEFAULT,
570
preloader->self->priv->cancellable,
571
image_loader_ready_cb,
746
g_cancellable_cancel (self->priv->current_request->cancellable);
576
debug (DEBUG_INFO, "done");
582
load_data_free (LoadData *load_data)
586
if (load_data == NULL)
589
for (i = 0; i < load_data->n_files; i++)
590
g_object_unref (load_data->files[i]);
591
g_free (load_data->files);
597
assign_loaders (LoadData *load_data)
599
GthImagePreloader *self = load_data->self;
600
gboolean *file_assigned;
601
gboolean *loader_assigned;
604
if (load_data->token != self->priv->token)
607
file_assigned = g_new (gboolean, self->priv->n_preloaders);
608
loader_assigned = g_new (gboolean, self->priv->n_preloaders);
609
for (i = 0; i < self->priv->n_preloaders; i++) {
610
Preloader *preloader = self->priv->loader[i];
612
loader_assigned[i] = FALSE;
613
file_assigned[i] = FALSE;
615
if (preloader->loaded && ! preloader->error)
616
preloader->token = load_data->token;
619
self->priv->requested = -1;
621
for (j = 0; j < load_data->n_files; j++) {
622
GthFileData *file_data = load_data->files[j];
624
if (file_data == NULL)
627
/* check whether the image has already been loaded. */
629
for (i = 0; i < self->priv->n_preloaders; i++) {
630
Preloader *preloader = self->priv->loader[i];
632
if (preloader_has_valid_content_for_file (preloader, file_data)) {
633
loader_assigned[i] = TRUE;
634
file_assigned[j] = TRUE;
636
if (_g_file_equal (file_data->file, load_data->requested->file)) {
637
self->priv->requested = i;
639
g_signal_emit (G_OBJECT (self),
640
gth_image_preloader_signals[preloader_signal_to_emit (preloader)],
642
preloader->file_data,
644
preloader->original_width,
645
preloader->original_height,
649
debug (DEBUG_INFO, "[requested] preloaded %s [size: %d]", g_file_get_uri (preloader->file_data->file), preloader->requested_size);
652
if (preloader_needs_second_step (preloader)) {
653
/* Reload the image at the original size */
654
preloader->loaded = FALSE;
655
preloader->requested_size = -1;
663
uri = g_file_get_uri (file_data->file);
664
debug (DEBUG_INFO, "[=] [%d] <- %s", i, uri);
674
/* assign the remaining files */
676
for (j = 0; j < load_data->n_files; j++) {
677
GthFileData *file_data = load_data->files[j];
678
Preloader *preloader;
681
if (file_data == NULL)
684
if (file_assigned[j])
687
/* find the first non-assigned loader */
688
for (k = 0; (k < self->priv->n_preloaders) && loader_assigned[k]; k++)
691
g_return_if_fail (k < self->priv->n_preloaders);
693
loader_assigned[k] = TRUE;
695
preloader = self->priv->loader[k];
696
preloader_set_file_data (preloader, file_data);
697
preloader->requested_size = _g_file_equal (file_data->file, load_data->requested->file) ? load_data->requested_size : -1;
698
/* force the use of the single step policy if the file is not local, in order to speed-up loading. */
699
if (! g_file_is_native (file_data->file))
700
preloader->requested_size = -1;
701
preloader->token = load_data->token;
703
if (_g_file_equal (file_data->file, load_data->requested->file)) {
704
self->priv->requested = k;
710
uri = g_file_get_uri (file_data->file);
711
debug (DEBUG_INFO, "[requested] %s", uri);
721
uri = g_file_get_uri (file_data->file);
722
debug (DEBUG_INFO, "[+] [%d] <- %s", k, uri);
728
g_free (loader_assigned);
729
g_free (file_assigned);
767
gth_image_preloader_load (GthImagePreloader *self,
768
GthFileData *requested,
770
GCancellable *cancellable,
771
GAsyncReadyCallback callback,
750
gth_image_preloader_load (GthImagePreloader *self,
751
GthFileData *requested,
776
LoadRequest *request;
779
#ifdef DEBUG_PRELOADER
780
g_print ("request %s @%d\n", g_file_get_uri (requested->file), requested_size);
783
request = load_request_new (self);
784
request->requested_size = requested_size;
785
request->files = g_list_prepend (request->files, gth_file_data_dup (requested));
786
va_start (args, n_files);
787
while (n_files-- > 0) {
788
GthFileData *file_data;
789
GthFileData *checked_file_data;
791
file_data = va_arg (args, GthFileData *);
792
checked_file_data = check_file (file_data);
758
GthFileData *file_data;
762
_g_object_unref (self->priv->requested_file);
763
self->priv->requested_file = g_file_dup (requested->file);
765
if (self->priv->next_load_data != NULL) {
766
load_data_free (self->priv->next_load_data);
767
self->priv->next_load_data = NULL;
770
load_data = g_new0 (LoadData, 1);
771
load_data->self = self;
772
load_data->token = self->priv->token;
773
load_data->requested = gth_file_data_dup (requested);
774
load_data->requested_size = requested_size;
775
load_data->files = g_new0 (GthFileData *, self->priv->n_preloaders);
778
load_data->files[n++] = load_data->requested;
779
va_start (args, requested_size);
780
while ((n < self->priv->n_preloaders) && (file_data = va_arg (args, GthFileData *)) != NULL) {
781
GthFileData *checked_file_data = check_file (file_data);
793
782
if (checked_file_data != NULL)
794
request->files = g_list_prepend (request->files, checked_file_data);
783
load_data->files[n++] = checked_file_data;
797
request->files = g_list_reverse (request->files);
798
request->requested_file = request->files;
799
request->result = g_simple_async_result_new (G_OBJECT (self),
802
gth_image_preloader_load);
803
request->cancellable = (cancellable != NULL) ? g_object_ref (cancellable) : g_cancellable_new ();
805
self->priv->last_request = request;
806
if (self->priv->current_request != NULL)
807
_gth_image_preloader_cancel_current_request (self);
809
_gth_image_preloader_start_request (self, self->priv->last_request);
814
gth_image_preloader_load_finish (GthImagePreloader *self,
815
GAsyncResult *result,
816
GthFileData **requested,
820
int *original_height,
823
CacheData *cache_data;
825
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), gth_image_preloader_load), FALSE);
827
cache_data = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
828
g_return_val_if_fail (cache_data != NULL, FALSE);
830
if (cache_data->error != NULL) {
832
*error = g_error_copy (cache_data->error);
836
if (requested != NULL)
837
*requested = _g_object_ref (cache_data->file_data);
839
*image = _g_object_ref (cache_data->image);
840
if (requested_size != NULL)
841
*requested_size = cache_data->requested_size;
842
if (original_width != NULL)
843
*original_width = cache_data->original_width;
844
if (original_height != NULL)
845
*original_height = cache_data->original_height;
852
gth_image_preloader_set_modified_image (GthImagePreloader *self,
853
cairo_surface_t *image)
856
CacheData *cache_data;
858
/* delete the modified image from the cache */
860
for (scan = self->priv->cache->head; scan; /* void */) {
861
GList *next = scan->next;
863
cache_data = scan->data;
864
if (cache_data->file_data == GTH_MODIFIED_IMAGE)
865
g_queue_delete_link (self->priv->cache, scan);
872
/* add the modified image to the cache */
874
cache_data = cache_data_new ();
875
cache_data->file_data = GTH_MODIFIED_IMAGE;
876
cache_data->image = gth_image_new_for_surface (image);
877
cache_data->original_width = -1;
878
cache_data->original_height = -1;
879
cache_data->requested_size = -1;
880
cache_data->error = NULL;
881
_gth_image_preloader_add_to_cache (self, cache_data);
886
gth_image_preloader_get_modified_image (GthImagePreloader *self)
890
for (scan = self->priv->cache->head; scan; scan = scan->next) {
891
CacheData *cache_data = scan->data;
893
if ((cache_data->file_data == GTH_MODIFIED_IMAGE) && (cache_data->requested_size == -1))
894
return gth_image_get_cairo_surface (cache_data->image);
786
load_data->n_files = n;
788
if (self->priv->current != -1) {
789
Preloader *preloader;
791
preloader = current_preloader (self);
792
if (preloader != NULL) {
793
self->priv->next_load_data = load_data;
794
g_cancellable_cancel (preloader->self->priv->cancellable);
799
assign_loaders (load_data);
800
start_next_loader (self);
802
load_data_free (load_data);
807
gth_image_preloader_get_loader (GthImagePreloader *self,
808
GthFileData *file_data)
812
g_return_val_if_fail (self != NULL, NULL);
814
if (file_data == NULL)
817
for (i = 0; i < self->priv->n_preloaders; i++) {
818
Preloader *preloader = self->priv->loader[i];
820
if (preloader_has_valid_content_for_file (preloader, file_data))
821
return preloader->loader;
829
gth_image_preloader_get_requested (GthImagePreloader *self)
831
Preloader *preloader;
833
preloader = requested_preloader (self);
834
return (preloader != NULL) ? preloader->file_data : NULL;