~noskcaj/ubuntu/vivid/gthumb/flickr-https

« back to all changes in this revision

Viewing changes to gthumb/gth-thumb-loader.c

  • Committer: Package Import Robot
  • Author(s): Jackson Doak
  • Date: 2014-04-08 06:31:09 UTC
  • mfrom: (1.3.20)
  • Revision ID: package-import@ubuntu.com-20140408063109-tk845map8ji6uxvd
Tags: 3:3.3.1.is.3.2.7-0ubuntu1
* Revert to newest upstream stable release. LP: #1290691
  - Refresh patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#define GDK_PIXBUF_ENABLE_BACKEND
30
30
#include <gtk/gtk.h>
31
31
#include <gdk-pixbuf/gdk-pixbuf.h>
32
 
#include "cairo-scale.h"
33
 
#include "cairo-utils.h"
34
32
#include "gio-utils.h"
35
33
#include "glib-utils.h"
36
34
#define GNOME_DESKTOP_USE_UNSTABLE_API
119
117
                    int            requested_size,
120
118
                    int           *original_width,
121
119
                    int           *original_height,
122
 
                    gboolean      *loaded_original,
123
120
                    gpointer       user_data,
124
121
                    GCancellable  *cancellable,
125
122
                    GError       **error)
175
172
                g_object_unref (pixbuf);
176
173
        }
177
174
        else {
 
175
                GthImageFormat     preferred_format;
178
176
                GthImageLoaderFunc thumbnailer;
179
177
 
180
 
                /* prefer the GTH_IMAGE_FORMAT_CAIRO_SURFACE format to give
181
 
                 * priority to the internal loaders. */
182
 
 
183
 
                thumbnailer = gth_main_get_image_loader_func (mime_type, GTH_IMAGE_FORMAT_CAIRO_SURFACE);
 
178
                /* Prefer the internal loader for jpeg images to load rotated
 
179
                 * images correctly. */
 
180
                if (strcmp (mime_type, "image/jpeg") == 0)
 
181
                        preferred_format = GTH_IMAGE_FORMAT_CAIRO_SURFACE;
 
182
                else
 
183
                        preferred_format = GTH_IMAGE_FORMAT_GDK_PIXBUF;
 
184
                thumbnailer = gth_main_get_image_loader_func (mime_type, preferred_format);
184
185
                if (thumbnailer != NULL)
185
186
                        image = thumbnailer (istream,
186
187
                                             file_data,
188
189
                                             original_width,
189
190
                                             original_height,
190
191
                                             NULL,
191
 
                                             NULL,
192
192
                                             cancellable,
193
193
                                             error);
194
194
        }
208
208
                       int            requested_size,
209
209
                       int           *original_width,
210
210
                       int           *original_height,
211
 
                       gboolean      *loaded_original,
212
211
                       gpointer       user_data,
213
212
                       GCancellable  *cancellable,
214
213
                       GError       **error)
215
214
{
 
215
        GthImage  *image = NULL;
 
216
        char      *filename;
 
217
        GdkPixbuf *pixbuf;
 
218
 
216
219
        if (file_data == NULL) {
217
 
                g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
 
220
                if (error != NULL)
 
221
                        *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, "Could not load file");
218
222
                return NULL;
219
223
        }
220
224
 
221
 
        return gth_image_new_from_stream (istream,
222
 
                                          requested_size,
223
 
                                          original_width,
224
 
                                          original_height,
225
 
                                          cancellable,
226
 
                                          error);
 
225
        filename = g_file_get_path (file_data->file);
 
226
        pixbuf = gdk_pixbuf_new_from_file (filename, error);
 
227
        if (pixbuf != NULL) {
 
228
                image = gth_image_new_for_pixbuf (pixbuf);
 
229
                g_object_unref (pixbuf);
 
230
        }
 
231
 
 
232
        g_free (filename);
 
233
 
 
234
        return image;
227
235
}
228
236
 
229
237
 
359
367
 
360
368
 
361
369
typedef struct {
362
 
        GthFileData     *file_data;
363
 
        cairo_surface_t *image;
 
370
        GthFileData *file_data;
 
371
        GdkPixbuf   *pixbuf;
364
372
} LoadResult;
365
373
 
366
374
 
368
376
load_result_unref (LoadResult *load_result)
369
377
{
370
378
        g_object_unref (load_result->file_data);
371
 
        cairo_surface_destroy (load_result->image);
 
379
        _g_object_unref (load_result->pixbuf);
372
380
        g_free (load_result);
373
381
}
374
382
 
413
421
}
414
422
 
415
423
 
416
 
static cairo_surface_t *
417
 
_cairo_image_surface_scale_for_thumbnail (cairo_surface_t *image,
418
 
                                          int              new_width,
419
 
                                          int              new_height)
420
 
{
421
 
        cairo_surface_t *scaled;
422
 
 
423
 
        scaled = _cairo_image_surface_scale (image, new_width, new_height, SCALE_FILTER_GOOD, NULL);
424
 
        _cairo_image_surface_copy_metadata (image, scaled);
425
 
 
426
 
        return scaled;
427
 
}
428
 
 
429
 
 
430
424
static void
431
425
cache_image_ready_cb (GObject      *source_object,
432
426
                      GAsyncResult *res,
433
427
                      gpointer      user_data)
434
428
{
435
 
        LoadData        *load_data = user_data;
436
 
        GthThumbLoader  *self = load_data->thumb_loader;
437
 
        GthImage        *image = NULL;
438
 
        cairo_surface_t *surface;
439
 
        int              width;
440
 
        int              height;
441
 
        gboolean         modified;
442
 
        LoadResult      *load_result;
 
429
        LoadData       *load_data = user_data;
 
430
        GthThumbLoader *self = load_data->thumb_loader;
 
431
        GthImage       *image = NULL;
 
432
        GdkPixbuf      *pixbuf;
 
433
        int             width;
 
434
        int             height;
 
435
        gboolean        modified;
 
436
        LoadResult     *load_result;
443
437
 
444
438
        if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
445
439
                                            res,
446
440
                                            &image,
447
441
                                            NULL,
448
442
                                            NULL,
449
 
                                            NULL,
450
443
                                            NULL))
451
444
        {
452
445
                /* error loading the thumbnail from the cache, try to generate
466
459
        /* Thumbnail correctly loaded from the cache. Scale if the user wants
467
460
         * a different size. */
468
461
 
469
 
        surface = gth_image_get_cairo_surface (image);
470
 
 
471
 
        g_return_if_fail (surface != NULL);
472
 
 
473
 
        width = cairo_image_surface_get_width (surface);
474
 
        height = cairo_image_surface_get_height (surface);
 
462
        pixbuf = gth_image_get_pixbuf (image);
 
463
 
 
464
        g_return_if_fail (pixbuf != NULL);
 
465
 
 
466
        width = gdk_pixbuf_get_width (pixbuf);
 
467
        height = gdk_pixbuf_get_height (pixbuf);
475
468
        modified = normalize_thumb (&width,
476
469
                                    &height,
477
470
                                    self->priv->requested_size,
478
471
                                    self->priv->cache_max_size);
479
472
        if (modified) {
480
 
                cairo_surface_t *tmp = surface;
481
 
                surface = _cairo_image_surface_scale_for_thumbnail (tmp, width, height);
482
 
                cairo_surface_destroy (tmp);
 
473
                GdkPixbuf *tmp = pixbuf;
 
474
                pixbuf = _gdk_pixbuf_scale_simple_safe (tmp, width, height, GDK_INTERP_BILINEAR);
 
475
                g_object_unref (tmp);
483
476
        }
484
477
 
485
478
        load_result = g_new0 (LoadResult, 1);
486
479
        load_result->file_data = g_object_ref (load_data->file_data);
487
 
        load_result->image = surface;
 
480
        load_result->pixbuf = pixbuf;
488
481
        g_simple_async_result_set_op_res_gpointer (load_data->simple, load_result, (GDestroyNotify) load_result_unref);
489
482
        g_simple_async_result_complete_in_idle (load_data->simple);
490
483
 
517
510
 
518
511
 
519
512
static gboolean
520
 
_gth_thumb_loader_save_to_cache (GthThumbLoader  *self,
521
 
                                 GthFileData     *file_data,
522
 
                                 cairo_surface_t *image,
523
 
                                 int              original_width,
524
 
                                 int              original_height)
 
513
_gth_thumb_loader_save_to_cache (GthThumbLoader *self,
 
514
                                 GthFileData    *file_data,
 
515
                                 GdkPixbuf      *pixbuf)
525
516
{
526
 
        char                     *uri;
527
 
        cairo_surface_metadata_t *metadata;
528
 
        GdkPixbuf                *pixbuf;
 
517
        char  *uri;
529
518
 
530
 
        if ((self == NULL) || (image == NULL))
 
519
        if ((self == NULL) || (pixbuf == NULL))
531
520
                return FALSE;
532
521
 
533
522
        uri = g_file_get_uri (file_data->file);
540
529
                return FALSE;
541
530
        }
542
531
 
543
 
        if ((original_width > 0) && (original_height > 0)) {
544
 
                metadata = _cairo_image_surface_get_metadata (image);
545
 
                metadata->thumbnail.image_width = original_width;
546
 
                metadata->thumbnail.image_height = original_height;
547
 
        }
548
 
        pixbuf = _gdk_pixbuf_new_from_cairo_surface (image);
549
 
        if (pixbuf == NULL)
550
 
                return FALSE;
551
 
 
552
532
        gnome_desktop_thumbnail_factory_save_thumbnail (self->priv->thumb_factory,
553
533
                                                        pixbuf,
554
534
                                                        uri,
555
535
                                                        gth_file_data_get_mtime (file_data));
556
536
 
557
 
        g_object_unref (pixbuf);
558
 
 
559
537
        return TRUE;
560
538
}
561
539
 
563
541
static void
564
542
original_image_loaded_correctly (GthThumbLoader *self,
565
543
                                 LoadData        *load_data,
566
 
                                 cairo_surface_t *image,
567
 
                                 int              original_width,
568
 
                                 int              original_height)
 
544
                                 GdkPixbuf       *pixbuf)
569
545
{
570
 
        cairo_surface_t *local_image;
571
 
        int              width;
572
 
        int              height;
573
 
        gboolean         modified;
574
 
        LoadResult      *load_result;
575
 
 
576
 
        local_image = cairo_surface_reference (image);
577
 
 
578
 
        width = cairo_image_surface_get_width (local_image);
579
 
        height = cairo_image_surface_get_height (local_image);
 
546
        GdkPixbuf  *local_pixbuf;
 
547
        int         width;
 
548
        int         height;
 
549
        gboolean    modified;
 
550
        LoadResult *load_result;
 
551
 
 
552
        local_pixbuf = g_object_ref (pixbuf);
 
553
 
 
554
        width = gdk_pixbuf_get_width (local_pixbuf);
 
555
        height = gdk_pixbuf_get_height (local_pixbuf);
580
556
 
581
557
        if (self->priv->save_thumbnails) {
582
558
                gboolean modified;
591
567
                                                self->priv->cache_max_size,
592
568
                                                FALSE);
593
569
                if (modified) {
594
 
                        cairo_surface_t *tmp = local_image;
595
 
                        local_image = _cairo_image_surface_scale_for_thumbnail (tmp, width, height);
596
 
                        cairo_surface_destroy (tmp);
 
570
                        GdkPixbuf *tmp = local_pixbuf;
 
571
                        local_pixbuf = _gdk_pixbuf_scale_simple_safe (tmp, width, height, GDK_INTERP_BILINEAR);
 
572
                        g_object_unref (tmp);
597
573
                }
598
574
 
599
 
                _gth_thumb_loader_save_to_cache (self,
600
 
                                                 load_data->file_data,
601
 
                                                 local_image,
602
 
                                                 original_width,
603
 
                                                 original_height);
 
575
                _gth_thumb_loader_save_to_cache (self, load_data->file_data, local_pixbuf);
604
576
        }
605
577
 
606
578
        /* Scale if the user wants a different size. */
610
582
                                    self->priv->requested_size,
611
583
                                    self->priv->cache_max_size);
612
584
        if (modified) {
613
 
                cairo_surface_t *tmp = local_image;
614
 
                local_image = _cairo_image_surface_scale_for_thumbnail (tmp, width, height);
615
 
                cairo_surface_destroy (tmp);
 
585
                GdkPixbuf *tmp = local_pixbuf;
 
586
                local_pixbuf = _gdk_pixbuf_scale_simple_safe (tmp, width, height, GDK_INTERP_BILINEAR);
 
587
                g_object_unref (tmp);
616
588
        }
617
589
 
618
590
        load_result = g_new0 (LoadResult, 1);
619
591
        load_result->file_data = g_object_ref (load_data->file_data);
620
 
        load_result->image = cairo_surface_reference (local_image);
 
592
        load_result->pixbuf = g_object_ref (local_pixbuf);
621
593
        g_simple_async_result_set_op_res_gpointer (load_data->simple, load_result, (GDestroyNotify) load_result_unref);
622
594
        g_simple_async_result_complete_in_idle (load_data->simple);
623
595
 
624
 
        cairo_surface_destroy (local_image);
 
596
        g_object_unref (local_pixbuf);
625
597
}
626
598
 
627
599
 
730
702
                                                                             &load_data->thumbnailer_tmpfile);
731
703
 
732
704
        if (pixbuf != NULL) {
733
 
                cairo_surface_t *surface;
734
 
 
735
 
                surface = _cairo_image_surface_create_from_pixbuf (pixbuf);
736
 
                original_image_loaded_correctly (self, load_data, surface, 0, 0);
737
 
 
738
 
                cairo_surface_destroy (surface);
 
705
                original_image_loaded_correctly (self, load_data, pixbuf);
739
706
                g_object_unref (pixbuf);
740
707
        }
741
708
        else
748
715
                         GAsyncResult *res,
749
716
                         gpointer      user_data)
750
717
{
751
 
        LoadData        *load_data = user_data;
752
 
        GthThumbLoader  *self = load_data->thumb_loader;
753
 
        GthImage        *image = NULL;
754
 
        int              original_width;
755
 
        int              original_height;
756
 
        cairo_surface_t *surface = NULL;
757
 
        GError          *error = NULL;
 
718
        LoadData       *load_data = user_data;
 
719
        GthThumbLoader *self = load_data->thumb_loader;
 
720
        GthImage       *image = NULL;
 
721
        GdkPixbuf      *pixbuf = NULL;
 
722
        GError         *error = NULL;
758
723
 
759
724
        if (! gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
760
725
                                            res,
761
726
                                            &image,
762
 
                                            &original_width,
763
 
                                            &original_height,
 
727
                                            NULL,
764
728
                                            NULL,
765
729
                                            &error))
766
730
        {
806
770
                return;
807
771
        }
808
772
 
809
 
        surface = gth_image_get_cairo_surface (image);
810
 
        original_image_loaded_correctly (self,
811
 
                                         load_data,
812
 
                                         surface,
813
 
                                         original_width,
814
 
                                         original_height);
 
773
        pixbuf = gth_image_get_pixbuf (image);
 
774
        original_image_loaded_correctly (self, load_data, pixbuf);
815
775
 
816
 
        cairo_surface_destroy (surface);
 
776
        g_object_unref (pixbuf);
817
777
        g_object_unref (image);
818
778
        load_data_unref (load_data);
819
779
}
919
879
 
920
880
 
921
881
gboolean
922
 
gth_thumb_loader_load_finish (GthThumbLoader   *self,
923
 
                              GAsyncResult     *result,
924
 
                              cairo_surface_t **image,
925
 
                              GError          **error)
 
882
gth_thumb_loader_load_finish (GthThumbLoader  *self,
 
883
                              GAsyncResult    *result,
 
884
                              GdkPixbuf      **pixbuf,
 
885
                              GError         **error)
926
886
{
927
887
        GSimpleAsyncResult *simple;
928
888
        LoadResult         *load_result;
935
895
                return FALSE;
936
896
 
937
897
        load_result = g_simple_async_result_get_op_res_gpointer (simple);
938
 
        if (image != NULL)
939
 
                *image = cairo_surface_reference (load_result->image);
 
898
        if (pixbuf != NULL)
 
899
                *pixbuf = _g_object_ref (load_result->pixbuf);
940
900
 
941
901
        return TRUE;
942
902
}