Beispiel #1
0
void
vnr_tools_apply_embedded_orientation (GdkPixbufAnimation **anim)
{
    GdkPixbuf *pixbuf;
    GdkPixbuf *original;

    if(!gdk_pixbuf_animation_is_static_image (*anim))
        return;

    pixbuf = gdk_pixbuf_animation_get_static_image (*anim);
    original = pixbuf;
    pixbuf = gdk_pixbuf_apply_embedded_orientation(pixbuf);

    if(original == pixbuf)
    {
        g_object_unref(pixbuf);
        return;
    }

    GdkPixbufSimpleAnim *s_anim;

    s_anim = gdk_pixbuf_simple_anim_new (gdk_pixbuf_get_width(pixbuf),
                                         gdk_pixbuf_get_height(pixbuf),
                                         -1);
    gdk_pixbuf_simple_anim_add_frame(s_anim, pixbuf);

    g_object_unref(pixbuf);
    g_object_unref(*anim);

    *anim = GDK_PIXBUF_ANIMATION(s_anim);
}
Beispiel #2
0
static void
file_buffer_ready_cb (void     **buffer,
		      gsize      count,
		      GError    *error,
		      gpointer   user_data)
{
	GthPixbufListTask *self = user_data;
	GInputStream      *istream;
	GdkPixbuf         *pixbuf;

	if (error != NULL) {
		gth_task_completed (GTH_TASK (self), error);
		return;
	}

	istream = g_memory_input_stream_new_from_data (*buffer, count, NULL);
	pixbuf = gdk_pixbuf_new_from_stream (istream, gth_task_get_cancellable (GTH_TASK (self)), &error);
	if (pixbuf != NULL) {
		self->priv->original_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
		g_object_unref (pixbuf);
	}
	else
		self->priv->original_pixbuf = NULL;

	g_object_unref (istream);

	if (self->priv->original_pixbuf == NULL) {
		gth_task_completed (GTH_TASK (self), error);
		return;
	}

	gth_pixbuf_task_set_source (GTH_PIXBUF_TASK (self->priv->task), self->priv->original_pixbuf);
	gth_task_exec (self->priv->task, gth_task_get_cancellable (GTH_TASK (self)));
}
GdkPixbuf *
hd_pixbuf_utils_load_scaled_and_cropped (GFile         *file,
                                         HDImageSize   *size,
                                         char         **etag,
                                         GCancellable  *cancellable,
                                         GError       **error)
{
  GFileInputStream *stream = NULL;
  GdkPixbufLoader *loader = NULL;
  GdkPixbuf *pixbuf = NULL;

  /* Open file for read */
  stream = g_file_read (file, cancellable, error);

  if (!stream)
    goto cleanup;

  /* Create pixbuf loader */
  loader = gdk_pixbuf_loader_new ();
  g_signal_connect (loader, "size-prepared",
                    G_CALLBACK (size_prepared_cb),
                    size);

  if (!get_etag_from_file_input_stream (stream,
                                        etag,
                                        cancellable,
                                        error))
    goto cleanup;

  if (!read_from_input_stream_into_pixbuf_loader (G_INPUT_STREAM (stream),
                                                  loader,
                                                  cancellable,
                                                  error))
    goto cleanup;

  /* Set resulting pixbuf */
  pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
  if (pixbuf)
    {
      GdkPixbuf *rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
      pixbuf = scale_and_crop_pixbuf (rotated, size);
      g_object_unref (rotated);
    }
  else
    g_set_error_literal (error,
                         GDK_PIXBUF_ERROR,
                         GDK_PIXBUF_ERROR_FAILED,
                         "NULL Pixbuf returned from loader");

cleanup:
  if (stream)
    g_object_unref (stream);
  if (loader)
    g_object_unref (loader);

  return pixbuf;
}
Beispiel #4
0
static GthImage *
facebook_thumbnail_loader (GInputStream  *istream,
			   GthFileData   *file_data,
			   int            requested_size,
			   int           *original_width,
			   int           *original_height,
			   gboolean      *loaded_original,
			   gpointer       user_data,
			   GCancellable  *cancellable,
			   GError       **error)
{
	GthImage      *image = NULL;
	FacebookPhoto *photo;
	const char    *uri;

	photo = (FacebookPhoto *) g_file_info_get_attribute_object (file_data->info, "facebook::object");

	uri = facebook_photo_get_thumbnail_url (photo, requested_size);
	if (uri == NULL)
		uri = facebook_photo_get_original_url (photo);

	if (uri != NULL) {
		GFile *file;
		void  *buffer;
		gsize  size;

		file = g_file_new_for_uri (uri);
		if (_g_file_load_in_buffer (file, &buffer, &size, cancellable, error)) {
			GInputStream *stream;
			GdkPixbuf    *pixbuf;

			stream = g_memory_input_stream_new_from_data (buffer, size, g_free);
			pixbuf = gdk_pixbuf_new_from_stream (stream, cancellable, error);
			if (pixbuf != NULL) {
				GdkPixbuf *rotated;

				rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
				g_object_unref (pixbuf);
				pixbuf = rotated;

				image = gth_image_new_for_pixbuf (pixbuf);
			}

			g_object_unref (pixbuf);
			g_object_unref (stream);
		}

		g_object_unref (file);
	}
	else
		*error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");

	return image;
}
Beispiel #5
0
static void
update_preview_cb (GtkFileChooser *file_chooser,
                   gpointer        data)
{
  GtkImage *preview = GTK_IMAGE (data);
  g_autofree char *filename = gtk_file_chooser_get_preview_filename (file_chooser);
  gint preview_width = 0;
  gint preview_height = 0;
  struct g_stat st_buf;
  g_autoptr(GdkPixbuf) pixbuf = NULL;

  GdkPixbufFormat *preview_format = gdk_pixbuf_get_file_info (filename,
                                                              &preview_width,
                                                              &preview_height);

  if (!filename || g_stat (filename, &st_buf) || (!S_ISREG (st_buf.st_mode))) {
    gtk_file_chooser_set_preview_widget_active (file_chooser, FALSE);
    return; // stat failed or file is not regular
  }

  if (!preview_format ||
      preview_width <= 0 || preview_height <= 0 ||
      preview_width > MAX_PREVIEW_SOURCE_SIZE ||
      preview_height > MAX_PREVIEW_SOURCE_SIZE) {
    gtk_file_chooser_set_preview_widget_active (file_chooser, FALSE);
    return; // unpreviewable, 0px, or unsafely large
  }

  if (preview_width > MAX_PREVIEW_SIZE || preview_height > MAX_PREVIEW_SIZE) {
    pixbuf = gdk_pixbuf_new_from_file_at_size (filename,
                                               MAX_PREVIEW_SIZE,
                                               MAX_PREVIEW_SIZE,
                                               NULL);
  } else {
    pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
  }

  pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);

  gtk_widget_set_size_request (GTK_WIDGET (preview),
                               gdk_pixbuf_get_width (pixbuf) + 6,
                               gdk_pixbuf_get_height (pixbuf) + 6);

  gtk_image_set_from_pixbuf (preview, pixbuf);
  gtk_file_chooser_set_preview_widget_active (file_chooser, pixbuf != NULL);
}
Beispiel #6
0
GdkPixbuf *
file_to_pixbuf (const char  *path,
		guint        destination_size,
	        GError     **error)
{
	GdkPixbuf *pixbuf, *tmp_pixbuf;
	GFile *file;
	char *uri;
	int original_width, original_height;

	file = g_file_new_for_path (path);
	uri = g_file_get_uri (file);
	pixbuf = _gdk_pixbuf_new_from_uri_at_scale (uri, destination_size, error);
	if (pixbuf == NULL)
		return NULL;

	tmp_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
	gdk_pixbuf_copy_options (pixbuf, tmp_pixbuf);
	gdk_pixbuf_remove_option (tmp_pixbuf, "orientation");
	g_object_unref (pixbuf);
	pixbuf = tmp_pixbuf;

        original_width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf),
                                                             "gnome-original-width"));
        original_height = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf),
                                                              "gnome-original-height"));

	if (original_width > 0 && original_height > 0) {
		char *tmp;

		tmp = g_strdup_printf ("%d", original_width);
		gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", tmp);
		g_free (tmp);

		tmp = g_strdup_printf ("%d", original_height);
		gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", tmp);
		g_free (tmp);
	}

	return pixbuf;
}
static GdkPixbuf *
impl_load_pixbuf_data (const guchar   *data,
                       gsize           size,
                       int             available_width,
                       int             available_height,
                       int             scale,
                       GError        **error)
{
  GdkPixbufLoader *pixbuf_loader = NULL;
  GdkPixbuf *rotated_pixbuf = NULL;
  GdkPixbuf *pixbuf;
  gboolean success;
  Dimensions available_dimensions;
  int width_before_rotation, width_after_rotation;

  pixbuf_loader = gdk_pixbuf_loader_new ();

  available_dimensions.width = available_width;
  available_dimensions.height = available_height;
  available_dimensions.scale = scale;
  g_signal_connect (pixbuf_loader, "size-prepared",
                    G_CALLBACK (on_image_size_prepared), &available_dimensions);

  success = gdk_pixbuf_loader_write (pixbuf_loader, data, size, error);
  if (!success)
    goto out;
  success = gdk_pixbuf_loader_close (pixbuf_loader, error);
  if (!success)
    goto out;

  pixbuf = gdk_pixbuf_loader_get_pixbuf (pixbuf_loader);

  width_before_rotation = gdk_pixbuf_get_width (pixbuf);

  rotated_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
  width_after_rotation = gdk_pixbuf_get_width (rotated_pixbuf);

  /* There is currently no way to tell if the pixbuf will need to be rotated before it is loaded,
   * so we only check that once it is loaded, and reload it again if it needs to be rotated in order
   * to use the available width and height correctly.
   * See http://bugzilla.gnome.org/show_bug.cgi?id=579003
   */
  if (width_before_rotation != width_after_rotation)
    {
      g_object_unref (pixbuf_loader);
      g_object_unref (rotated_pixbuf);
      rotated_pixbuf = NULL;

      pixbuf_loader = gdk_pixbuf_loader_new ();

      /* We know that the image will later be rotated, so we reverse the available dimensions. */
      available_dimensions.width = available_height;
      available_dimensions.height = available_width;
      available_dimensions.scale = scale;
      g_signal_connect (pixbuf_loader, "size-prepared",
                        G_CALLBACK (on_image_size_prepared), &available_dimensions);

      success = gdk_pixbuf_loader_write (pixbuf_loader, data, size, error);
      if (!success)
        goto out;

      success = gdk_pixbuf_loader_close (pixbuf_loader, error);
      if (!success)
        goto out;

      pixbuf = gdk_pixbuf_loader_get_pixbuf (pixbuf_loader);

      rotated_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
    }

out:
  if (pixbuf_loader)
    g_object_unref (pixbuf_loader);
  return rotated_pixbuf;
}
static GdkPixbuf* _vfs_thumbnail_load( const char* file_path, const char* uri,
                                                    int size, time_t mtime )
{
#if GLIB_CHECK_VERSION(2, 16, 0)
    GChecksum *cs;
#else
    md5_state_t md5_state;
    md5_byte_t md5[ 16 ];
#endif
    char file_name[ 40 ];
    char* thumbnail_file;
    char mtime_str[ 32 ];
    const char* thumb_mtime;
    int i, w, h;
    struct stat statbuf;
    GdkPixbuf* thumbnail, *result = NULL;
    int create_size;
    
    if ( size > 256 )
        create_size = 512;
    else if ( size > 128 )
        create_size = 256;
    else
        create_size = 128;
    
    gboolean file_is_video = FALSE;
#ifdef HAVE_FFMPEG
    VFSMimeType* mimetype = vfs_mime_type_get_from_file_name( file_path );
    if ( mimetype )
    {
        if ( strncmp( vfs_mime_type_get_type( mimetype ), "video/", 6 ) == 0 )
            file_is_video = TRUE;
        vfs_mime_type_unref( mimetype );
    }
#endif


    if ( file_is_video == FALSE )
    {
        if ( !gdk_pixbuf_get_file_info( file_path, &w, &h ) )
            return NULL;   /* image format cannot be recognized */

        /* If the image itself is very small, we should load it directly */
        if ( w <= create_size && h <= create_size )
        {
            if( w <= size && h <= size )
                return gdk_pixbuf_new_from_file( file_path, NULL );
            return gdk_pixbuf_new_from_file_at_size( file_path, size, size, NULL );
        }
    }

#if GLIB_CHECK_VERSION(2, 16, 0)
    cs = g_checksum_new(G_CHECKSUM_MD5);
    g_checksum_update(cs, uri, strlen(uri));
    memcpy( file_name, g_checksum_get_string(cs), 32 );
    g_checksum_free(cs);
#else
    md5_init( &md5_state );
    md5_append( &md5_state, ( md5_byte_t * ) uri, strlen( uri ) );
    md5_finish( &md5_state, md5 );

    for ( i = 0; i < 16; ++i )
        sprintf( ( file_name + i * 2 ), "%02x", md5[ i ] );
#endif
    strcpy( ( file_name + 32 ), ".png" );

    thumbnail_file = g_build_filename( g_get_home_dir(),
                                       ".thumbnails/normal",
                                       file_name, NULL );

    if( G_UNLIKELY( 0 == mtime ) )
    {
        if( stat( file_path, &statbuf ) != -1 )
            mtime = statbuf.st_mtime;
    }

    if ( file_is_video && time( NULL ) - mtime < 5 )
        /* if mod time of video being thumbnailed is less than 5 sec ago,
         * don't create a thumbnail (is copying?)
         * FIXME: This means that a newly saved file may not show a thumbnail
         * until refresh. */
        return NULL;

    /* load existing thumbnail */
    thumbnail = gdk_pixbuf_new_from_file( thumbnail_file, NULL );
    if ( thumbnail )
    {
        w = gdk_pixbuf_get_width( thumbnail );
        h = gdk_pixbuf_get_height( thumbnail );
    }
    if ( !thumbnail || ( w < size && h < size ) ||
                !( thumb_mtime = gdk_pixbuf_get_option( thumbnail,
                                                "tEXt::Thumb::MTime" ) ) ||
                atol( thumb_mtime ) != mtime )
    {
        if( thumbnail )
            g_object_unref( thumbnail );
        /* create new thumbnail */
        if ( file_is_video == FALSE )
        {
            thumbnail = gdk_pixbuf_new_from_file_at_size( file_path,
                                            create_size, create_size, NULL );
            if ( thumbnail )
            {
                // Note: gdk_pixbuf_apply_embedded_orientation returns a new
                // pixbuf or same with incremented ref count, so unref
                GdkPixbuf* thumbnail_old = thumbnail;
                thumbnail = gdk_pixbuf_apply_embedded_orientation( thumbnail );
                g_object_unref( thumbnail_old );
                sprintf( mtime_str, "%lu", mtime );
                gdk_pixbuf_save( thumbnail, thumbnail_file, "png", NULL,
                                 "tEXt::Thumb::URI", uri, "tEXt::Thumb::MTime",
                                 mtime_str, NULL );
                chmod( thumbnail_file, 0600 );  /* only the owner can read it. */
            }
        }
#ifdef HAVE_FFMPEG
        else
        {
            video_thumbnailer* video_thumb = video_thumbnailer_create();


            /* Setting a callback to allow silencing of stdout/stderr messages
             * from the library. This is no longer required since v2.0.11, where
             * silence is the default.  It can be used for debugging in 2.0.11
             * and later. */
            //video_thumbnailer_set_log_callback(on_video_thumbnailer_log_message);

            if ( video_thumb )
            {
                video_thumb->seek_percentage = 25;
                video_thumb->overlay_film_strip = 1;
                video_thumb->thumbnail_size = create_size;
                video_thumbnailer_generate_thumbnail_to_file( video_thumb,
                                                file_path, thumbnail_file );
                video_thumbnailer_destroy( video_thumb );

                chmod( thumbnail_file, 0600 );  /* only the owner can read it. */
                thumbnail = gdk_pixbuf_new_from_file( thumbnail_file, NULL );
            }
        }
#endif
    }

    if ( thumbnail )
    {
        w = gdk_pixbuf_get_width( thumbnail );
        h = gdk_pixbuf_get_height( thumbnail );

        if ( w > h )
        {
            h = h * size / w;
            w = size;
        }
        else if ( h > w )
        {
            w = w * size / h;
            h = size;
        }
        else
        {
            w = h = size;
        }
        if ( w > 0 && h > 0 )
            result = gdk_pixbuf_scale_simple(
                         thumbnail,
                         w, h, GDK_INTERP_BILINEAR );
        g_object_unref( thumbnail );
    }

    g_free( thumbnail_file );
    return result;
}
static GthImage *
flickr_thumbnail_loader (GInputStream  *istream,
			 GthFileData   *file_data,
			 int            requested_size,
			 int           *original_width,
			 int           *original_height,
			 gboolean      *loaded_original,
			 gpointer       user_data,
			 GCancellable  *cancellable,
		         GError       **error)
{
	GthImage       *image = NULL;
	GthThumbLoader *thumb_loader = user_data;
	FlickrPhoto    *photo;
	const char     *uri = NULL;

	photo = (FlickrPhoto *) g_file_info_get_attribute_object (file_data->info, "flickr::object");
	requested_size = gth_thumb_loader_get_requested_size (thumb_loader);
	if (requested_size == FLICKR_SIZE_SMALL_SQUARE)
		uri = photo->url[FLICKR_URL_SQ];
	else if (requested_size == FLICKR_SIZE_THUMBNAIL)
		uri = photo->url[FLICKR_URL_T];
	else if (requested_size == FLICKR_SIZE_SMALL)
		uri = photo->url[FLICKR_URL_S];
	else if (requested_size == FLICKR_SIZE_MEDIUM)
		uri = photo->url[FLICKR_URL_M];

	if (uri == NULL)
		uri = photo->url[FLICKR_URL_O];

	if (uri != NULL) {
		GFile *file;
		void  *buffer;
		gsize  size;

		file = g_file_new_for_uri (uri);
		if (_g_file_load_in_buffer (file, &buffer, &size, cancellable, error)) {
			GInputStream *stream;
			GdkPixbuf    *pixbuf;

			stream = g_memory_input_stream_new_from_data (buffer, size, g_free);
			pixbuf = gdk_pixbuf_new_from_stream (stream, cancellable, error);
			if (pixbuf != NULL) {
				GdkPixbuf *rotated;

				rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
				g_object_unref (pixbuf);
				pixbuf = rotated;

				image = gth_image_new_for_pixbuf (pixbuf);
			}

			g_object_unref (pixbuf);
			g_object_unref (stream);
		}

		g_object_unref (file);
	}
	else
		*error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");

	return image;
}
Beispiel #10
0
GthImage *
gth_pixbuf_new_from_file (GInputStream  *istream,
			  GthFileData   *file_data,
			  int            requested_size,
			  int           *original_width,
			  int           *original_height,
			  gboolean      *loaded_original,
			  gboolean       scale_to_original,
			  GCancellable  *cancellable,
			  GError       **error)
{
	ScaleData        scale_data;
	GdkPixbufLoader *pixbuf_loader;
	GdkPixbuf       *pixbuf;
	GthImage        *image;
	gboolean         original_size_rotated = FALSE;

	if (original_width != NULL)
		*original_width = -1;
	if (original_height != NULL)
		*original_height = -1;

	scale_data.requested_size = requested_size;
	scale_data.original_width = -1;
	scale_data.original_height = -1;
	scale_data.loader_width = -1;
	scale_data.loader_height = -1;

	pixbuf_loader = gdk_pixbuf_loader_new ();
	g_signal_connect (pixbuf_loader,
			  "size-prepared",
			  G_CALLBACK (pixbuf_loader_size_prepared_cb),
			  &scale_data);
	pixbuf = load_from_stream (pixbuf_loader, istream, requested_size, cancellable, error);

	g_object_unref (pixbuf_loader);

	if ((pixbuf != NULL) && scale_to_original) {
		GdkPixbuf *tmp;

		tmp = _gdk_pixbuf_scale_simple_safe (pixbuf, scale_data.original_width, scale_data.original_height, GDK_INTERP_NEAREST);
		g_object_unref (pixbuf);
		pixbuf = tmp;
	}

	if ((original_width != NULL) && (original_height != NULL)) {
		if (file_data != NULL) {
			char *path;

			path = g_file_get_path (file_data->file);
			if (path != NULL) {
				gdk_pixbuf_get_file_info (path, &scale_data.original_width, &scale_data.original_height);
				original_size_rotated = TRUE;
				g_free (path);
			}
		}
	}

	if (pixbuf != NULL) {
		GdkPixbuf *rotated;

		rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
		if (rotated != NULL) {
			if (! original_size_rotated) {
				/* swap width and height */
				int tmp = scale_data.original_width;
				scale_data.original_width = scale_data.original_height;
				scale_data.original_height =tmp;
			}

			g_object_unref (pixbuf);
			pixbuf = rotated;
		}
	}

	image = gth_image_new ();
	if (pixbuf != NULL) {
		cairo_surface_t          *surface;
		cairo_surface_metadata_t *metadata;

		surface = _cairo_image_surface_create_from_pixbuf (pixbuf);
		metadata = _cairo_image_surface_get_metadata (surface);
		metadata->original_width = scale_data.original_width;
		metadata->original_height = scale_data.original_height;
		metadata->has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
		gth_image_set_cairo_surface (image, surface);
	}

	if (original_width != NULL)
		*original_width = scale_data.original_width;
	if (original_height != NULL)
		*original_height = scale_data.original_height;
	if (loaded_original != NULL)
		*loaded_original = (pixbuf != NULL) && (scale_data.original_width == gdk_pixbuf_get_width (pixbuf)) && (scale_data.original_height == gdk_pixbuf_get_height (pixbuf));

	_g_object_unref (pixbuf);

	return image;
}
Beispiel #11
0
GthImage *
gth_pixbuf_new_from_file (GInputStream  *istream,
			  GthFileData   *file_data,
			  int            requested_size,
			  int           *original_width,
			  int           *original_height,
			  gboolean       scale_to_original,
			  GCancellable  *cancellable,
			  GError       **error)
{
	ScaleData        scale_data;
	GdkPixbufLoader *pixbuf_loader;
	GdkPixbuf       *pixbuf;
	GthImage        *image;

	if (original_width != NULL)
		*original_width = -1;
	if (original_height != NULL)
		*original_height = -1;

	scale_data.requested_size = requested_size;
	scale_data.original_width = -1;
	scale_data.original_height = -1;
	scale_data.loader_width = -1;
	scale_data.loader_height = -1;

	pixbuf_loader = gdk_pixbuf_loader_new ();
	g_signal_connect (pixbuf_loader,
			  "size-prepared",
			  G_CALLBACK (pixbuf_loader_size_prepared_cb),
			  &scale_data);
	pixbuf = load_from_stream (pixbuf_loader, istream, requested_size, cancellable, error);

	g_object_unref (pixbuf_loader);

	if ((pixbuf != NULL) && scale_to_original) {
		GdkPixbuf *tmp;

		tmp = _gdk_pixbuf_scale_simple_safe (pixbuf, scale_data.original_width, scale_data.original_height, GDK_INTERP_NEAREST);
		g_object_unref (pixbuf);
		pixbuf = tmp;
	}

	if (pixbuf != NULL) {
		GdkPixbuf *rotated;

		rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
		if (rotated != NULL) {
			scale_data.original_width = gdk_pixbuf_get_width (rotated);
			scale_data.original_height = gdk_pixbuf_get_height (rotated);
			g_object_unref (pixbuf);
			pixbuf = rotated;
		}
	}

	image = gth_image_new_for_pixbuf (pixbuf);

	if (original_width != NULL)
		*original_width = scale_data.original_width;
	if (original_height != NULL)
		*original_height = scale_data.original_height;

	_g_object_unref (pixbuf);

	return image;
}
static GthImage *
picasa_web_thumbnail_loader (GInputStream  *istream,
			     GthFileData   *file_data,
			     int            requested_size,
			     int           *original_width,
			     int           *original_height,
			     gboolean      *loaded_original,
			     gpointer       user_data,
			     GCancellable  *cancellable,
			     GError       **error)
{
	GthImage       *image = NULL;
	GthThumbLoader *thumb_loader = user_data;
	PicasaWebPhoto *photo;
	const char     *uri;

	photo = (PicasaWebPhoto *) g_file_info_get_attribute_object (file_data->info, "gphoto::object");
	requested_size = gth_thumb_loader_get_requested_size (thumb_loader);
	if (requested_size == 72)
		uri = photo->thumbnail_72;
	else if (requested_size == 144)
		uri = photo->thumbnail_144;
	else if (requested_size == 288)
		uri = photo->thumbnail_288;
	else
		uri = NULL;

	if (uri == NULL)
		uri = photo->uri;

	if (uri != NULL) {
		GFile *file;
		void  *buffer;
		gsize  size;

		file = g_file_new_for_uri (uri);
		if (_g_file_load_in_buffer (file, &buffer, &size, cancellable, error)) {
			GInputStream *stream;
			GdkPixbuf    *pixbuf;

			stream = g_memory_input_stream_new_from_data (buffer, size, g_free);
			pixbuf = gdk_pixbuf_new_from_stream (stream, cancellable, error);
			if (pixbuf != NULL) {
				GdkPixbuf *rotated;

				rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
				g_object_unref (pixbuf);
				pixbuf = rotated;

				image = gth_image_new_for_pixbuf (pixbuf);
			}

			g_object_unref (pixbuf);
			g_object_unref (stream);
		}

		g_object_unref (file);
	}
	else
		*error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");

	return image;
}
Beispiel #13
0
void generate_thumbnails_with_gdk_pixbuf(ThumbnailTask* task)
{
    /* FIXME: only formats supported by GdkPixbuf should be handled this way. */
    GFile* gf = fm_path_to_gfile(task->fi->path);
    GFileInputStream* ins;
    GdkPixbuf* normal_pix = NULL;
    GdkPixbuf* large_pix = NULL;

    DEBUG("generate thumbnail for %s", task->fi->path->name);

    if( ins = g_file_read(gf, generator_cancellable, NULL) )
    {
        GdkPixbuf* ori_pix;
        gssize len;
        ori_pix = gdk_pixbuf_new_from_stream(G_INPUT_STREAM(ins), generator_cancellable, NULL);
        if(ori_pix) /* if the original image is successfully loaded */
        {
            const char* orientation_str = gdk_pixbuf_get_option(ori_pix, "orientation");
            int width = gdk_pixbuf_get_width(ori_pix);
            int height = gdk_pixbuf_get_height(ori_pix);
            gboolean need_save;

            if(task->flags & GENERATE_NORMAL)
            {
                /* don't create thumbnails for images which are too small */
                if(width <=128 && height <= 128)
                {
                    normal_pix = (GdkPixbuf*)g_object_ref(ori_pix);
                    need_save = FALSE;
                }
                else
                {
                    normal_pix = scale_pix(ori_pix, 128);
                    need_save = TRUE;
                }
                if(orientation_str)
                {
                    GdkPixbuf* rotated;
                    gdk_pixbuf_set_option(normal_pix, "orientation", orientation_str);
                    rotated = gdk_pixbuf_apply_embedded_orientation(normal_pix);
                    g_object_unref(normal_pix);
                    normal_pix = rotated;
                }
                if(need_save)
                    save_thumbnail_to_disk(task, normal_pix, task->normal_path);
            }

            if(task->flags & GENERATE_LARGE)
            {
                /* don't create thumbnails for images which are too small */
                if(width <=256 && height <= 256)
                {
                    large_pix = (GdkPixbuf*)g_object_ref(ori_pix);
                    need_save = FALSE;
                }
                else
                {
                    large_pix = scale_pix(ori_pix, 256);
                    need_save = TRUE;
                }
                if(orientation_str)
                {
                    GdkPixbuf* rotated;
                    gdk_pixbuf_set_option(large_pix, "orientation", orientation_str);
                    rotated = gdk_pixbuf_apply_embedded_orientation(large_pix);
                    g_object_unref(large_pix);
                    large_pix = rotated;
                }
                if(need_save)
                    save_thumbnail_to_disk(task, large_pix, task->large_path);
            }
            g_object_unref(ori_pix);
        }
        g_input_stream_close(G_INPUT_STREAM(ins), NULL, NULL);
    }

    G_LOCK(queue);
    thumbnail_task_finish(task, normal_pix, large_pix);
    cur_generating = NULL;
    G_UNLOCK(queue);

    if(normal_pix)
        g_object_unref(normal_pix);
    if(large_pix)
        g_object_unref(large_pix);

    g_object_unref(gf);
}