1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2 
3 /*
4  * GImageView
5  * Copyright (C) 2001-2002 Takuro Ashie
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * $Id: gimv_image_loader.c,v 1.9 2004/03/07 11:53:30 makeinu Exp $
22  */
23 
24 #include "gimv_image_loader.h"
25 
26 #include "gimv_anim.h"
27 #include "gtk2-compat.h"
28 #include "fileutil.h"
29 
30 
31 typedef enum {
32    LOAD_START_SIGNAL,
33    PROGRESS_UPDATE_SIGNAL,
34    LOAD_END_SIGNAL,
35    LAST_SIGNAL
36 } GimvImageLoaderSignalType;
37 
38 
39 typedef enum
40 {
41    GIMV_IMAGE_LOADER_LOADING_FLAG   = 1 << 0,
42    GIMV_IMAGE_LOADER_CANCEL_FLAG    = 1 << 1,
43    GIMV_IMAGE_LOADER_SHOW_TIME_FLAG = 1 << 2,
44    GIMV_IMAGE_LOADER_DEBUG_FLAG     = 1 << 3
45 } GimvImageLoaderFlags;
46 
47 
48 struct GimvImageLoaderPriv_Tag
49 {
50    GimvIO      *gio;
51    gboolean     use_specified_gio;
52    GimvImage   *image;
53    GimvImageLoaderLoadType load_type;
54    gboolean     load_as_animation;
55 
56    gfloat       width_scale;
57    gfloat       height_scale;
58 
59    /* size request */
60    gint         max_width;
61    gint         max_height;
62    gboolean     keep_aspect;
63 
64    const gchar *temp_file;
65 
66    gint         flags;
67 
68    /* que */
69    GimvImageInfo *next_info;
70 };
71 
72 static void      gimv_image_loader_class_init (GimvImageLoaderClass *klass);
73 static void      gimv_image_loader_init       (GimvImageLoader      *loader);
74 static void      gimv_image_loader_destroy    (GtkObject        *object);
75 static gboolean  idle_gimv_image_loader_load  (gpointer          data);
76 
77 /* callback */
78 static void      gimv_image_loader_load_end   (GimvImageLoader      *loader);
79 
80 static GtkObjectClass *parent_class = NULL;
81 static gint gimv_image_loader_signals[LAST_SIGNAL] = {0};
82 
83 
84 /****************************************************************************
85  *
86  *  Plugin Management
87  *
88  ****************************************************************************/
89 static GList *gimv_image_loader_list = NULL;
90 
91 
92 static gint
comp_func_priority(GimvImageLoaderPlugin * plugin1,GimvImageLoaderPlugin * plugin2)93 comp_func_priority (GimvImageLoaderPlugin *plugin1,
94                     GimvImageLoaderPlugin *plugin2)
95 {
96    g_return_val_if_fail (plugin1, 1);
97    g_return_val_if_fail (plugin2, -1);
98 
99    return plugin1->priority_hint - plugin2->priority_hint;
100 }
101 
102 
103 gboolean
gimv_image_loader_plugin_regist(const gchar * plugin_name,const gchar * module_name,gpointer impl,gint size)104 gimv_image_loader_plugin_regist (const gchar *plugin_name,
105                                  const gchar *module_name,
106                                  gpointer impl,
107                                  gint     size)
108 {
109    GimvImageLoaderPlugin *image_loader = impl;
110 
111    g_return_val_if_fail (module_name, FALSE);
112    g_return_val_if_fail (image_loader, FALSE);
113    g_return_val_if_fail (size > 0, FALSE);
114    g_return_val_if_fail (image_loader->if_version == GIMV_IMAGE_LOADER_IF_VERSION,
115                          FALSE);
116    g_return_val_if_fail (image_loader->id, FALSE);
117 
118    gimv_image_loader_list = g_list_append (gimv_image_loader_list,
119                                            image_loader);
120 
121    gimv_image_loader_list = g_list_sort (gimv_image_loader_list,
122                                          (GCompareFunc) comp_func_priority);
123 
124    return TRUE;
125 }
126 
127 
128 
129 /****************************************************************************
130  *
131  *
132  *
133  ****************************************************************************/
134 GtkType
gimv_image_loader_get_type(void)135 gimv_image_loader_get_type (void)
136 {
137    static GtkType gimv_image_loader_type = 0;
138 
139    if (!gimv_image_loader_type) {
140       static const GtkTypeInfo gimv_image_loader_info = {
141          "GimvImageLoader",
142          sizeof (GimvImageLoader),
143          sizeof (GimvImageLoaderClass),
144          (GtkClassInitFunc) gimv_image_loader_class_init,
145          (GtkObjectInitFunc) gimv_image_loader_init,
146          NULL,
147          NULL,
148          (GtkClassInitFunc) NULL,
149       };
150 
151       gimv_image_loader_type = gtk_type_unique (gtk_object_get_type (),
152                                                 &gimv_image_loader_info);
153    }
154 
155    return gimv_image_loader_type;
156 }
157 
158 
159 static void
gimv_image_loader_class_init(GimvImageLoaderClass * klass)160 gimv_image_loader_class_init (GimvImageLoaderClass *klass)
161 {
162    GtkObjectClass *object_class;
163 
164    object_class = (GtkObjectClass *) klass;
165    parent_class = gtk_type_class (gtk_object_get_type ());
166 
167    gimv_image_loader_signals[LOAD_START_SIGNAL]
168       = gtk_signal_new ("load_start",
169                         GTK_RUN_FIRST,
170                         GTK_CLASS_TYPE (object_class),
171                         GTK_SIGNAL_OFFSET (GimvImageLoaderClass, load_start),
172                         gtk_signal_default_marshaller,
173                         GTK_TYPE_NONE, 0);
174 
175    gimv_image_loader_signals[PROGRESS_UPDATE_SIGNAL]
176       = gtk_signal_new ("progress_update",
177                         GTK_RUN_FIRST,
178                         GTK_CLASS_TYPE (object_class),
179                         GTK_SIGNAL_OFFSET (GimvImageLoaderClass, load_end),
180                         gtk_signal_default_marshaller,
181                         GTK_TYPE_NONE, 0);
182 
183    gimv_image_loader_signals[LOAD_END_SIGNAL]
184       = gtk_signal_new ("load_end",
185                         GTK_RUN_FIRST,
186                         GTK_CLASS_TYPE (object_class),
187                         GTK_SIGNAL_OFFSET (GimvImageLoaderClass, load_end),
188                         gtk_signal_default_marshaller,
189                         GTK_TYPE_NONE, 0);
190 
191    gtk_object_class_add_signals (object_class,
192                                  gimv_image_loader_signals, LAST_SIGNAL);
193 
194    object_class->destroy  = gimv_image_loader_destroy;
195 
196    klass->load_start      = NULL;
197    klass->progress_update = NULL;
198    klass->load_end        = gimv_image_loader_load_end;
199 }
200 
201 
202 static void
gimv_image_loader_init(GimvImageLoader * loader)203 gimv_image_loader_init (GimvImageLoader *loader)
204 {
205    loader->info                    = NULL;
206    loader->timer                   = g_timer_new ();
207 
208    loader->priv                    = g_new0 (GimvImageLoaderPriv, 1);
209    loader->priv->gio               = NULL;
210    loader->priv->use_specified_gio = FALSE;
211    loader->priv->image             = NULL;
212    loader->priv->load_type         = GIMV_IMAGE_LOADER_LOAD_NORMAL;
213    loader->priv->load_as_animation = FALSE;
214    loader->priv->width_scale       = -1.0;
215    loader->priv->height_scale      = -1.0;
216    loader->priv->max_width         = -1;
217    loader->priv->max_height        = -1;
218    loader->priv->keep_aspect       = TRUE;
219    loader->priv->temp_file         = NULL;
220    loader->priv->flags             = 0;
221    loader->priv->next_info         = NULL;
222 
223 #ifdef USE_GTK2
224    gtk_object_ref (GTK_OBJECT (loader));
225    gtk_object_sink (GTK_OBJECT (loader));
226 #endif
227 }
228 
229 
230 GimvImageLoader *
gimv_image_loader_new(void)231 gimv_image_loader_new (void)
232 {
233    GimvImageLoader *loader
234       = GIMV_IMAGE_LOADER (gtk_type_new (gimv_image_loader_get_type ()));
235 
236    return loader;
237 }
238 
239 
240 GimvImageLoader *
gimv_image_loader_new_with_image_info(GimvImageInfo * info)241 gimv_image_loader_new_with_image_info (GimvImageInfo *info)
242 {
243    GimvImageLoader *loader;
244 
245    loader = gimv_image_loader_new ();
246    gimv_image_loader_set_image_info (loader, info);
247 
248    return loader;
249 }
250 
251 
252 GimvImageLoader *
gimv_image_loader_new_with_file_name(const gchar * filename)253 gimv_image_loader_new_with_file_name (const gchar *filename)
254 {
255    GimvImageLoader *loader;
256    GimvImageInfo *info;
257 
258    info = gimv_image_info_get (filename);
259    if (!info) return NULL;
260    loader = gimv_image_loader_new_with_image_info (info);
261 
262    return loader;
263 }
264 
265 
266 GimvImageLoader *
gimv_image_loader_ref(GimvImageLoader * loader)267 gimv_image_loader_ref (GimvImageLoader *loader)
268 {
269    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), NULL);
270 
271    gtk_object_ref (GTK_OBJECT (loader));
272 
273    return loader;
274 }
275 
276 
277 void
gimv_image_loader_unref(GimvImageLoader * loader)278 gimv_image_loader_unref (GimvImageLoader *loader)
279 {
280    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
281 
282    gtk_object_unref (GTK_OBJECT (loader));
283 }
284 
285 
286 static void
gimv_image_loader_destroy(GtkObject * object)287 gimv_image_loader_destroy (GtkObject *object)
288 {
289    GimvImageLoader *loader = GIMV_IMAGE_LOADER (object);
290 
291    if (gimv_image_loader_is_loading (loader))
292       gimv_image_loader_load_stop (loader);
293 
294    if (loader->info)
295       gimv_image_info_unref (loader->info);
296    loader->info = NULL;
297 
298    if (loader->timer)
299       g_timer_destroy (loader->timer);
300    loader->timer = NULL;
301 
302    if (loader->priv) {
303       if (loader->priv->next_info)
304          gimv_image_info_unref (loader->priv->next_info);
305       loader->priv->next_info = NULL;
306 
307       if (loader->priv->gio)
308          gimv_io_unref (loader->priv->gio);
309       loader->priv->gio = NULL;
310 
311       if (loader->priv->image)
312          gimv_image_unref (loader->priv->image);
313       loader->priv->image = NULL;
314 
315       if (loader->priv->temp_file)
316          g_free ((gchar *) loader->priv->temp_file);
317       loader->priv->temp_file = NULL;
318 
319       g_free (loader->priv);
320       loader->priv = NULL;
321    }
322 
323    if (GTK_OBJECT_CLASS (parent_class)->destroy)
324       (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
325 }
326 
327 
328 void
gimv_image_loader_set_image_info(GimvImageLoader * loader,GimvImageInfo * info)329 gimv_image_loader_set_image_info (GimvImageLoader *loader, GimvImageInfo *info)
330 {
331    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
332    g_return_if_fail (info);
333    g_return_if_fail (loader->priv);
334 
335    if (gimv_image_loader_is_loading (loader)) {
336       gimv_image_loader_load_stop (loader);
337       if (loader->priv->next_info)
338          gimv_image_info_unref (loader->priv->next_info);
339       loader->priv->next_info = gimv_image_info_ref (info);
340       return;
341    }
342 
343    if (loader->priv->image)
344       gimv_image_unref (loader->priv->image);
345    loader->priv->image = NULL;
346 
347    g_timer_reset (loader->timer);
348 
349    if (loader->priv->temp_file)
350       g_free ((gchar *)loader->priv->temp_file);
351    loader->priv->temp_file = NULL;
352 
353    if (loader->info)
354       gimv_image_info_unref (loader->info);
355 
356    if (info)
357       loader->info = gimv_image_info_ref (info);
358    else
359       loader->info = NULL;
360 }
361 
362 
363 void
gimv_image_loader_set_gio(GimvImageLoader * loader,GimvIO * gio)364 gimv_image_loader_set_gio (GimvImageLoader *loader, GimvIO *gio)
365 {
366    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
367    g_return_if_fail (!gimv_image_loader_is_loading (loader));
368    g_return_if_fail (loader->priv);
369 
370    loader->priv->gio = gimv_io_ref (gio);
371    if (gio)
372       loader->priv->use_specified_gio = TRUE;
373    else
374       loader->priv->use_specified_gio = FALSE;
375 }
376 
377 
378 gboolean
gimv_image_loader_set_as_animation(GimvImageLoader * loader,gboolean animation)379 gimv_image_loader_set_as_animation (GimvImageLoader *loader,
380                                     gboolean animation)
381 {
382    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
383    g_return_val_if_fail (!gimv_image_loader_is_loading (loader), FALSE);
384    g_return_val_if_fail (loader->priv, FALSE);
385 
386    loader->priv->load_as_animation = animation;
387 
388    return TRUE;
389 }
390 
391 
392 gboolean
gimv_image_loader_set_load_type(GimvImageLoader * loader,GimvImageLoaderLoadType type)393 gimv_image_loader_set_load_type (GimvImageLoader *loader,
394                                  GimvImageLoaderLoadType type)
395 {
396    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
397    g_return_val_if_fail (!gimv_image_loader_is_loading (loader), FALSE);
398    g_return_val_if_fail (loader->priv, FALSE);
399 
400    loader->priv->load_type = type;
401 
402    return TRUE;
403 }
404 
405 
406 gboolean
gimv_image_loader_set_scale(GimvImageLoader * loader,gfloat w_scale,gfloat h_scale)407 gimv_image_loader_set_scale (GimvImageLoader *loader,
408                              gfloat w_scale,
409                              gfloat h_scale)
410 {
411    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
412    g_return_val_if_fail (!gimv_image_loader_is_loading (loader), FALSE);
413    g_return_val_if_fail (loader->priv, FALSE);
414 
415    loader->priv->width_scale  = w_scale;
416    loader->priv->height_scale = h_scale;
417 
418    return TRUE;
419 }
420 
421 
422 gboolean
gimv_image_loader_set_size_request(GimvImageLoader * loader,gint max_width,gint max_height,gboolean keep_aspect)423 gimv_image_loader_set_size_request (GimvImageLoader *loader,
424                                     gint max_width,
425                                     gint max_height,
426                                     gboolean keep_aspect)
427 {
428    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
429    g_return_val_if_fail (!gimv_image_loader_is_loading (loader), FALSE);
430    g_return_val_if_fail (loader->priv, FALSE);
431 
432    loader->priv->max_width   = max_width;
433    loader->priv->max_height  = max_height;
434    loader->priv->keep_aspect = keep_aspect;
435 
436    return TRUE;
437 }
438 
439 
440 void
gimv_image_loader_load_start(GimvImageLoader * loader)441 gimv_image_loader_load_start (GimvImageLoader *loader)
442 {
443    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
444    g_return_if_fail (loader->info);
445    g_return_if_fail (loader->priv);
446 
447    g_return_if_fail (!gimv_image_loader_is_loading(loader));
448 
449    loader->priv->flags &= ~GIMV_IMAGE_LOADER_LOADING_FLAG;
450    loader->priv->flags &= ~GIMV_IMAGE_LOADER_CANCEL_FLAG;
451 
452    /* gtk_idle_add (idle_gimv_image_loader_load, loader); */
453    gimv_image_loader_load (loader);
454 }
455 
456 
457 void
gimv_image_loader_load_stop(GimvImageLoader * loader)458 gimv_image_loader_load_stop (GimvImageLoader *loader)
459 {
460    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
461    g_return_if_fail (loader->priv);
462 
463    if (loader->priv->flags & GIMV_IMAGE_LOADER_LOADING_FLAG) {
464       loader->priv->flags |= GIMV_IMAGE_LOADER_CANCEL_FLAG;
465    }
466 }
467 
468 
469 gboolean
gimv_image_loader_is_loading(GimvImageLoader * loader)470 gimv_image_loader_is_loading (GimvImageLoader *loader)
471 {
472    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
473 
474    if (loader->priv && (loader->priv->flags & GIMV_IMAGE_LOADER_LOADING_FLAG))
475       return TRUE;
476    else
477       return FALSE;
478 }
479 
480 
481 GimvImage *
gimv_image_loader_get_image(GimvImageLoader * loader)482 gimv_image_loader_get_image (GimvImageLoader *loader)
483 {
484    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), NULL);
485    g_return_val_if_fail (loader->priv, NULL);
486 
487    return loader->priv->image;
488 }
489 
490 
491 void
gimv_image_loader_unref_image(GimvImageLoader * loader)492 gimv_image_loader_unref_image (GimvImageLoader *loader)
493 {
494    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
495    g_return_if_fail (loader->priv);
496 
497    if (loader->priv->image)
498       gimv_image_unref (loader->priv->image);
499    loader->priv->image = NULL;
500 }
501 
502 
503 GimvIO *
gimv_image_loader_get_gio(GimvImageLoader * loader)504 gimv_image_loader_get_gio (GimvImageLoader *loader)
505 {
506    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), NULL);
507    g_return_val_if_fail (loader->priv, NULL);
508 
509    return loader->priv->gio;
510 }
511 
512 
513 const gchar *
gimv_image_loader_get_path(GimvImageLoader * loader)514 gimv_image_loader_get_path (GimvImageLoader *loader)
515 {
516    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), NULL);
517    g_return_val_if_fail (loader->priv, NULL);
518 
519    if (!loader->info) return NULL;
520 
521    if (gimv_image_info_need_temp_file (loader->info)) {
522       if (!loader->priv->temp_file)
523          loader->priv->temp_file
524             = gimv_image_info_get_temp_file_path (loader->info);
525       return loader->priv->temp_file;
526    }
527 
528    return gimv_image_info_get_path (loader->info);
529 }
530 
531 
532 GimvImageLoaderLoadType
gimv_image_loader_get_load_type(GimvImageLoader * loader)533 gimv_image_loader_get_load_type (GimvImageLoader *loader)
534 {
535    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader),
536                          GIMV_IMAGE_LOADER_LOAD_NORMAL);
537    g_return_val_if_fail (loader->priv,
538                          GIMV_IMAGE_LOADER_LOAD_NORMAL);
539 
540    return loader->priv->load_type;
541 }
542 
543 
544 gboolean
gimv_image_loader_load_as_animation(GimvImageLoader * loader)545 gimv_image_loader_load_as_animation (GimvImageLoader *loader)
546 {
547    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
548    g_return_val_if_fail (loader->priv, FALSE);
549 
550    return loader->priv->load_as_animation;
551 }
552 
553 
554 gboolean
gimv_image_loader_get_scale(GimvImageLoader * loader,gfloat * width_scale_ret,gfloat * height_scale_ret)555 gimv_image_loader_get_scale (GimvImageLoader *loader,
556                              gfloat *width_scale_ret,
557                              gfloat *height_scale_ret)
558 {
559    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
560    g_return_val_if_fail (width_scale_ret && height_scale_ret, FALSE);
561    g_return_val_if_fail (loader->priv, FALSE);
562 
563    *width_scale_ret  = loader->priv->width_scale;
564    *height_scale_ret = loader->priv->height_scale;
565 
566    if (*width_scale_ret < 0.0 || *height_scale_ret < 0.0)
567       return FALSE;
568 
569    return TRUE;
570 }
571 
572 
573 gboolean
gimv_image_loader_get_size_request(GimvImageLoader * loader,gint * max_width,gint * max_height,gboolean * keep_aspect)574 gimv_image_loader_get_size_request (GimvImageLoader *loader,
575                                     gint *max_width,
576                                     gint *max_height,
577                                     gboolean *keep_aspect)
578 {
579    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
580    g_return_val_if_fail (max_width && max_height && keep_aspect, FALSE);
581    g_return_val_if_fail (loader->priv, FALSE);
582 
583    *max_width   = loader->priv->max_width;
584    *max_height  = loader->priv->max_height;
585    *keep_aspect = loader->priv->keep_aspect;
586 
587    return TRUE;
588 }
589 
590 
591 gboolean
gimv_image_loader_progress_update(GimvImageLoader * loader)592 gimv_image_loader_progress_update (GimvImageLoader *loader)
593 {
594    g_return_val_if_fail (GIMV_IS_IMAGE_LOADER (loader), FALSE);
595    g_return_val_if_fail (gimv_image_loader_is_loading (loader), FALSE);
596    g_return_val_if_fail (loader->priv, FALSE);
597 
598    gtk_signal_emit (GTK_OBJECT(loader),
599                     gimv_image_loader_signals[PROGRESS_UPDATE_SIGNAL]);
600 
601    if (loader->priv->flags & GIMV_IMAGE_LOADER_CANCEL_FLAG)
602       return FALSE;
603    else
604       return TRUE;
605 }
606 
607 
608 void
gimv_image_loader_load(GimvImageLoader * loader)609 gimv_image_loader_load (GimvImageLoader *loader)
610 {
611    GList *node;
612    gboolean cancel = FALSE;
613 
614    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
615    g_return_if_fail (loader->priv);
616 
617    if (gimv_image_loader_is_loading (loader)) {
618       return;
619    }
620 
621    /* set flags */
622    loader->priv->flags &= ~GIMV_IMAGE_LOADER_LOADING_FLAG;
623    loader->priv->flags &= ~GIMV_IMAGE_LOADER_CANCEL_FLAG;
624    loader->priv->flags |= GIMV_IMAGE_LOADER_LOADING_FLAG;
625 
626    gtk_signal_emit (GTK_OBJECT(loader),
627                     gimv_image_loader_signals[LOAD_START_SIGNAL]);
628 
629    g_timer_reset (loader->timer);
630    g_timer_start (loader->timer);
631 
632    /* load GimvIO and name of temporary file */
633    if (loader->info) {
634       if (!loader->priv->use_specified_gio) {
635          if (loader->priv->gio)
636             gimv_io_unref (loader->priv->gio);
637          loader->priv->gio = gimv_image_info_get_gio (loader->info);
638 
639          if (gimv_image_info_need_temp_file (loader->info)) {
640             g_free ((gchar *) loader->priv->temp_file);
641             loader->priv->temp_file
642                = gimv_image_info_get_temp_file (loader->info);
643             if (!loader->priv->temp_file) {
644                if (loader->priv->gio) {
645                   gimv_io_unref (loader->priv->gio);
646                   loader->priv->gio = NULL;
647                }
648                g_timer_stop (loader->timer);
649                g_timer_reset (loader->timer);
650                return;
651             }
652          }
653       }
654    }
655 
656    /* free old image */
657    if (loader->priv->image)
658       gimv_image_unref (loader->priv->image);
659    loader->priv->image = NULL;
660 
661    /* try all loader */
662    for (node = gimv_image_loader_list; node; node = g_list_next (node)) {
663       GimvImageLoaderPlugin *plugin = node->data;
664 
665       cancel = !gimv_image_loader_progress_update (loader);
666       if (cancel) break;
667 
668       if (!plugin->loader) continue;
669 
670       if (loader->priv->gio)
671          gimv_io_seek (loader->priv->gio, 0, SEEK_SET);
672 
673       loader->priv->image = plugin->loader (loader, NULL);
674 
675       if (loader->priv->image) {
676          if (loader->info && !GIMV_IMAGE_INFO_IS_SYNCED(loader->info)) {
677             GimvImageInfoFlags flags = GIMV_IMAGE_INFO_SYNCED_FLAG;
678 
679             /* set image info */
680             if (GIMV_IS_ANIM (loader->priv->image)) {
681                flags |= GIMV_IMAGE_INFO_ANIMATION_FLAG;
682             }
683             gimv_image_info_set_size (loader->info,
684                                  gimv_image_width (loader->priv->image),
685                                  gimv_image_height (loader->priv->image));
686             gimv_image_info_set_flags (loader->info, flags);
687          }
688          break;
689       }
690 
691       if (loader->priv->flags & GIMV_IMAGE_LOADER_CANCEL_FLAG) break;
692    }
693 
694    /* free GimvIO if needed */
695    if (!loader->priv->use_specified_gio) {
696       if (loader->priv->gio)
697          gimv_io_unref (loader->priv->gio);
698       loader->priv->gio = NULL;
699    }
700 
701    g_timer_stop (loader->timer);
702 
703    if (loader->priv->flags & GIMV_IMAGE_LOADER_SHOW_TIME_FLAG)
704       g_print ("GimvImageLoader: %f[sec] (%s)\n",
705                g_timer_elapsed (loader->timer, NULL),
706                gimv_image_loader_get_path (loader));
707 
708    /* reset flags and emit signal */
709    loader->priv->flags &= ~GIMV_IMAGE_LOADER_LOADING_FLAG;
710    if (loader->priv->flags & GIMV_IMAGE_LOADER_CANCEL_FLAG) {
711       loader->priv->flags &= ~GIMV_IMAGE_LOADER_CANCEL_FLAG;
712       if (loader->priv->flags & GIMV_IMAGE_LOADER_DEBUG_FLAG)
713          g_print ("----- loading canceled -----\n");
714       /* emit canceled signal? */
715       gtk_signal_emit (GTK_OBJECT(loader),
716                        gimv_image_loader_signals[LOAD_END_SIGNAL]);
717    } else {
718       if (loader->priv->flags & GIMV_IMAGE_LOADER_DEBUG_FLAG)
719          g_print ("----- loading done -----\n");
720       gtk_signal_emit (GTK_OBJECT(loader),
721                        gimv_image_loader_signals[LOAD_END_SIGNAL]);
722    }
723 }
724 
725 
726 static gboolean
idle_gimv_image_loader_load(gpointer data)727 idle_gimv_image_loader_load (gpointer data)
728 {
729    GimvImageLoader *loader = data;
730 
731    gimv_image_loader_load (loader);
732 
733    return FALSE;
734 }
735 
736 
737 static void
gimv_image_loader_load_end(GimvImageLoader * loader)738 gimv_image_loader_load_end (GimvImageLoader *loader)
739 {
740    g_return_if_fail (GIMV_IS_IMAGE_LOADER (loader));
741    g_return_if_fail (loader->priv);
742 
743    if (!loader->priv->next_info)
744       return;
745 
746    loader->info = loader->priv->next_info;
747    loader->priv->next_info = NULL;
748    gtk_idle_add (idle_gimv_image_loader_load, loader);
749 }
750