Exemplo n.º 1
0
static void
gimp_thumbnail_set_info_from_pixbuf (GimpThumbnail *thumbnail,
                                     GdkPixbuf     *pixbuf)
{
  const gchar  *option;
  gint          num;

  g_object_freeze_notify (G_OBJECT (thumbnail));

  gimp_thumbnail_reset_info (thumbnail);

  g_free (thumbnail->image_mimetype);
  thumbnail->image_mimetype =
    g_strdup (gdk_pixbuf_get_option (pixbuf, TAG_THUMB_MIMETYPE));

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_IMAGE_WIDTH);
  if (option && sscanf (option, "%d", &num) == 1)
    thumbnail->image_width = num;

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_IMAGE_HEIGHT);
  if (option && sscanf (option, "%d", &num) == 1)
    thumbnail->image_height = num;

  thumbnail->image_type =
    g_strdup (gdk_pixbuf_get_option (pixbuf, TAG_THUMB_GIMP_TYPE));

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_GIMP_LAYERS);
  if (option && sscanf (option, "%d", &num) == 1)
    thumbnail->image_num_layers = num;

  g_object_thaw_notify (G_OBJECT (thumbnail));
}
void
histogram_imager_load_image_file (HistogramImager *self, const gchar *filename, GError **error)
{
    /* Try to open the given PNG file and load parameters from it */
    const gchar *params;
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, error);
    if (!pixbuf)
	return;

    params = gdk_pixbuf_get_option (pixbuf, "tEXt::fyre_params");

    /* For backward compatibility with de Jong Explorer and early versions of Fyre */
    if (!params)
	params = gdk_pixbuf_get_option (pixbuf, "tEXt::de_jong_params");

    if (params) {
	parameter_holder_load_string (PARAMETER_HOLDER (self), params);
    } else {
	if (error != NULL) {
	    GError *nerror = g_error_new (fyre_histogram_imager_error_quark(),
			                  FYRE_HISTOGRAM_IMAGER_ERROR_NO_METADATA,
				          "The image does not contain Fyre metadata");
	    *error = nerror;
	}
    }
    gdk_pixbuf_unref (pixbuf);
}
Exemplo n.º 3
0
static struct graphics_image_priv *
image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot)
{
	GdkPixbuf *pixbuf;
	struct graphics_image_priv *ret;
	const char *option;

	pixbuf=gdk_pixbuf_new_from_file(name, NULL);
	if (! pixbuf)
		return NULL;
	ret=g_new0(struct graphics_image_priv, 1);
	ret->pixbuf=pixbuf;
	ret->w=gdk_pixbuf_get_width(pixbuf);
	ret->h=gdk_pixbuf_get_height(pixbuf);
	*w=ret->w;
	*h=ret->h;
	if (hot) {
		option=gdk_pixbuf_get_option(pixbuf, "x_hot");
		if (option) 
			hot->x=atoi(option);
		else
			hot->x=ret->w/2-1;
		option=gdk_pixbuf_get_option(pixbuf, "y_hot");
		if (option) 
			hot->y=atoi(option);
		else
			hot->y=ret->h/2-1;
	}
	return ret;
}
Exemplo n.º 4
0
static gint thumb_loader_std_validate(ThumbLoaderStd *tl, GdkPixbuf *pixbuf)
{
	const gchar *valid_uri;
	const gchar *uri;
	const gchar *mtime_str;
	time_t mtime;
	gint w, h;

	if (!pixbuf) return FALSE;

	w = gdk_pixbuf_get_width(pixbuf);
	h = gdk_pixbuf_get_height(pixbuf);

	if (w != THUMB_SIZE_NORMAL && w != THUMB_SIZE_LARGE &&
	    h != THUMB_SIZE_NORMAL && h != THUMB_SIZE_LARGE) return FALSE;

	valid_uri = (tl->thumb_path_local) ? tl->local_uri : tl->thumb_uri;

	uri = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_URI);
	mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);

	if (!mtime_str || !uri || !valid_uri) return FALSE;
	if (strcmp(uri, valid_uri) != 0) return FALSE;

	mtime = strtol(mtime_str, NULL, 10);
	if (tl->source_mtime != mtime) return FALSE;

	return TRUE;
}
Exemplo n.º 5
0
/**
 * gimp_thumbnail_has_failed:
 * @thumbnail: a #GimpThumbnail object
 *
 * Checks if a valid failure thumbnail for the given thumbnail exists
 * in the global thumbnail repository. This may be the case even if
 * gimp_thumbnail_peek_thumb() doesn't return %GIMP_THUMB_STATE_FAILED
 * since there might be a real thumbnail and a failure thumbnail for
 * the same image file.
 *
 * The application should not attempt to create the thumbnail if a
 * valid failure thumbnail exists.
 *
 * Return value: %TRUE if a failure thumbnail exists or
 *
 * Since: 2.2
 **/
gboolean
gimp_thumbnail_has_failed (GimpThumbnail *thumbnail)
{
  GdkPixbuf   *pixbuf;
  const gchar *option;
  gchar       *filename;
  gint64       image_mtime;
  gint64       image_size;
  gboolean     failed = FALSE;

  g_return_val_if_fail (GIMP_IS_THUMBNAIL (thumbnail), FALSE);
  g_return_val_if_fail (thumbnail->image_uri != NULL, FALSE);

  GIMP_THUMB_DEBUG_CALL (thumbnail);

  filename = gimp_thumb_name_from_uri (thumbnail->image_uri,
                                       GIMP_THUMB_SIZE_FAIL);
  if (! filename)
    return FALSE;

  pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
  g_free (filename);

  if (! pixbuf)
    return FALSE;

  if (gimp_thumbnail_peek_image (thumbnail) < GIMP_THUMB_STATE_EXISTS)
    goto finish;

  /* URI and mtime from the thumbnail need to match our file */
  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_URI);
  if (! option || strcmp (option, thumbnail->image_uri))
    goto finish;

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_MTIME);
  if (!option || sscanf (option, "%" G_GINT64_FORMAT, &image_mtime) != 1)
    goto finish;

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_FILESIZE);
  if (option && sscanf (option, "%" G_GINT64_FORMAT, &image_size) != 1)
    goto finish;

  /* TAG_THUMB_FILESIZE is optional but must match if present */
  if (image_mtime == thumbnail->image_mtime &&
      (option == NULL || image_size == thumbnail->image_filesize))
    {
      failed = TRUE;
    }

 finish:
  g_object_unref (pixbuf);

  return failed;
}
Exemplo n.º 6
0
static void thumb_loader_std_thumb_file_validate_done_cb(ThumbLoaderStd *tl, gpointer data)
{
	ThumbValidate *tv = data;
	GdkPixbuf *pixbuf;
	gint valid = FALSE;

	pixbuf = thumb_loader_std_get_pixbuf(tv->tl, FALSE);
	if (pixbuf)
		{
		const gchar *uri;
		const gchar *mtime_str;

		uri = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_URI);
		mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);
		if (uri && mtime_str)
			{
			if (strncmp(uri, "file:", strlen("file:")) == 0)
				{
				struct stat st;
				gchar *target;

				target = g_filename_from_uri(uri, NULL, NULL);
				if (stat(target, &st) == 0 &&
				    st.st_mtime == strtol(mtime_str, NULL, 10))
					{
					valid = TRUE;
					}
				g_free(target);
				}
			else
				{
				struct stat st;

				if (debug) printf("thumb uri foreign, doing day check: %s\n", uri);

				if (stat_utf8(tv->path, &st))
					{
					time_t now;

					now = time(NULL);
					if (st.st_atime >= now - (time_t)tv->days * 24 * 60 * 60)
						{
						valid = TRUE;
						}
					}
				}
			}

		g_object_unref(pixbuf);
		}

	thumb_loader_std_thumb_file_validate_finish(tv, valid);
}
Exemplo n.º 7
0
static void thumb_std_maint_move_validate_cb(const gchar *path, gint valid, gpointer data)
{
	TMaintMove *tm = data;
	GdkPixbuf *pixbuf;

	pixbuf = thumb_loader_std_get_pixbuf(tm->tl, FALSE);
	if (pixbuf)
		{
		const gchar *uri;
		const gchar *mtime_str;

		uri = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_URI);
		mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);

		if (uri && mtime_str && strcmp(uri, tm->source_uri) == 0)
			{
			gchar *pathl;

			/* The validation utility abuses ThumbLoader, and we
			 * abuse the utility just to load the thumbnail,
			 * but the loader needs to look sane for the save to complete.
			 */

			tm->tl->cache_enable = TRUE;
			tm->tl->cache_hit = FALSE;
			tm->tl->cache_local = FALSE;

			g_free(tm->tl->source_path);
			tm->tl->source_path = g_strdup(tm->dest);
			tm->tl->source_mtime = strtol(mtime_str, NULL, 10);

			pathl = path_from_utf8(tm->tl->source_path);
			g_free(tm->tl->thumb_uri);
			tm->tl->thumb_uri = g_filename_to_uri(pathl, NULL, NULL);
			tm->tl->local_uri = filename_from_path(tm->tl->thumb_uri);
			g_free(pathl);

			g_free(tm->tl->thumb_path);
			tm->tl->thumb_path = NULL;
			tm->tl->thumb_path_local = FALSE;

			if (debug) printf("thumb move attempting save:\n");

			thumb_loader_std_save(tm->tl, pixbuf);
			}

		if (debug) printf("thumb move unlink: %s\n", tm->thumb_path);
		unlink_file(tm->thumb_path);
		}

	thumb_std_maint_move_step(tm);
}
Exemplo n.º 8
0
static void
update_image_preview (GtkFileChooser *chooser, GtkImage *image) {
    GdkPixbuf *image_pixbuf, *temp;
    static GdkPixbuf *emblem_pixbuf = NULL;
    gchar *filename;
    GdkPixmap *pixmap;
    gint width, height;

    if (emblem_pixbuf == NULL) {
	emblem_pixbuf = gdk_pixbuf_new_from_file (FYRE_DATADIR "/metadata-emblem.png", NULL);
	if (!emblem_pixbuf)
	    emblem_pixbuf = gdk_pixbuf_new_from_file (BR_DATADIR ("/fyre/metadata-emblem.png"), NULL);
    }

    filename = gtk_file_chooser_get_filename (chooser);
    if (filename == NULL) {
	gtk_file_chooser_set_preview_widget_active (chooser, FALSE);
	return;
    }

    image_pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 112, 112, NULL);
    if (image_pixbuf == NULL) {
	gtk_file_chooser_set_preview_widget_active (chooser, FALSE);
	return;
    }
    width = gdk_pixbuf_get_width (image_pixbuf);
    height = gdk_pixbuf_get_height (image_pixbuf);

    pixmap = gdk_pixmap_new (GTK_WIDGET (image)->window, width + 16, height + 16, -1);
    gdk_draw_rectangle (pixmap, GTK_WIDGET (image)->style->bg_gc[GTK_STATE_NORMAL], TRUE, 0, 0, width + 16, height + 16);
    gdk_draw_pixbuf (pixmap, NULL, image_pixbuf, 0, 0, 0, 0, width - 1, height - 1, GDK_RGB_DITHER_NONE, 0, 0);

    temp = gdk_pixbuf_new_from_file (filename, NULL);
    if (temp) {
        if (gdk_pixbuf_get_option (temp, "tEXt::fyre_params"))
            gdk_draw_pixbuf (pixmap, NULL, emblem_pixbuf, 0, 0, width - 16, height - 16, 31, 31, GDK_RGB_DITHER_NONE, 0, 0);
        else if (gdk_pixbuf_get_option (temp, "tEXt::de_jong_params"))
            gdk_draw_pixbuf (pixmap, NULL, emblem_pixbuf, 0, 0, width - 16, height - 16, 31, 31, GDK_RGB_DITHER_NONE, 0, 0);
        gdk_pixbuf_unref (temp);
    }

    if (image_pixbuf)
	gdk_pixbuf_unref (image_pixbuf);

    gtk_image_set_from_pixmap (GTK_IMAGE (image), pixmap, NULL);
    gdk_pixmap_unref (pixmap);
    gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
}
Exemplo n.º 9
0
/**
 * gimp_thumbnail_set_from_thumb:
 * @thumbnail: a #GimpThumbnail object
 * @filename: filename of a local thumbnail file
 * @error: return location for possible errors
 *
 * This function tries to load the thumbnail file pointed to by
 * @filename and retrieves the URI of the original image file from
 * it. This allows you to find the image file associated with a
 * thumbnail file.
 *
 * This will only work with thumbnails from the global thumbnail
 * directory that contain a valid Thumb::URI tag.
 *
 * Return value: %TRUE if the pixbuf could be loaded, %FALSE otherwise
 **/
gboolean
gimp_thumbnail_set_from_thumb (GimpThumbnail  *thumbnail,
                               const gchar    *filename,
                               GError        **error)
{
  GdkPixbuf   *pixbuf;
  const gchar *uri;

  g_return_val_if_fail (GIMP_IS_THUMBNAIL (thumbnail), FALSE);
  g_return_val_if_fail (filename != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  GIMP_THUMB_DEBUG_CALL (thumbnail);

  pixbuf = gdk_pixbuf_new_from_file (filename, error);
  if (! pixbuf)
    return FALSE;

  uri = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_URI);
  if (! uri)
    {
      g_set_error (error, GIMP_THUMB_ERROR, 0,
                   _("Thumbnail contains no Thumb::URI tag"));
      g_object_unref (pixbuf);
      return FALSE;
    }

  gimp_thumbnail_set_uri (thumbnail, uri);
  g_object_unref (pixbuf);

  return TRUE;
}
Exemplo n.º 10
0
static gboolean write_image(GObject* image, const char* filename)
{
    char *keys[11]; /* enough for known keys + 1 */
    char *vals[11];
    GdkPixbuf *pix = GDK_PIXBUF(image);
    char *known_keys[] = { "tEXt::Thumb::URI", "tEXt::Thumb::MTime",
                           "tEXt::Thumb::Size", "tEXt::Thumb::Mimetype",
                           "tEXt::Description", "tEXt::Software",
                           "tEXt::Thumb::Image::Width", "tEXt::Thumb::Image::Height",
                           "tEXt::Thumb::Document::Pages", "tEXt::Thumb::Movie::Length" };
    guint i, x;

    /* unfortunately GdkPixbuf APIs does not contain API to get
       list of options that are set, neither there is API to save
       the file with all options, so all we can do now is to scan
       options for known ones and save them into target file */
    for (i = 0, x = 0; i < G_N_ELEMENTS(known_keys); i++)
    {
        const char *val = gdk_pixbuf_get_option(pix, known_keys[i]);
        if (val)
        {
            keys[x] = known_keys[i];
            vals[x] = (char*)val;
            x++;
        }
    }
    keys[x] = NULL;
    vals[x] = NULL;
    return gdk_pixbuf_savev(pix, filename, "png", keys, vals, NULL);
}
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf;
  const char *software;
  const char *uri;
  GtkTreeIter iter;
  GtkListStore *store;

  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Failed to load image: %s", error->message);

      g_error_free (error);
      return;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);
  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  item = g_object_get_data (source_object, "item");
  uri = cc_background_item_get_uri (item);

  /* Ignore screenshots */
  software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
  if (software != NULL &&
      g_str_equal (software, "gnome-screenshot"))
    {
      g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot",
               cc_background_item_get_uri (item));
      g_object_unref (pixbuf);
      g_object_unref (item);
      return;
    }

  cc_background_item_load (item, NULL);

  /* insert the item into the liststore */
  gtk_list_store_insert_with_values (store, &iter, -1,
                                     0, pixbuf,
                                     1, item,
                                     -1);

  g_hash_table_insert (bg_source->priv->known_items,
                       bg_pictures_source_get_unique_filename (uri),
                       GINT_TO_POINTER (TRUE));


  g_object_unref (pixbuf);
}
Exemplo n.º 12
0
/* Check if we have an up-to-date thumbnail for this image.
 * If so, return it. Otherwise, returns NULL.
 */
static GdkPixbuf*
get_thumbnail_for(const char *pathname)
{
	GdkPixbuf *thumb = NULL;
	char *thumb_path, *uri;
	const char *ssize, *smtime;
	struct stat info;
	time_t ttime, now;

	char* path = pathdup(pathname);
	uri = g_filename_to_uri(path, NULL, NULL);
	if(!uri) uri = g_strconcat("file://", path, NULL);
	char* md5 = md5_hash(uri);
	g_free(uri);
	
	thumb_path = g_strdup_printf("%s/.thumbnails/normal/%s.png", g_get_home_dir(), md5);
	g_free(md5);

	thumb = gdk_pixbuf_new_from_file(thumb_path, NULL);
	if (!thumb) goto err;

	// Note that these don't need freeing... 
	ssize = gdk_pixbuf_get_option(thumb, "tEXt::Thumb::Size");
	if (!ssize) goto err;

	smtime = gdk_pixbuf_get_option(thumb, "tEXt::Thumb::MTime");
	if (!smtime) goto err;
	
	if (stat(path, &info) != 0) goto err;

	ttime=(time_t) atol(smtime);
	time(&now);
	if (info.st_mtime != ttime && now>ttime+PIXMAP_THUMB_TOO_OLD_TIME)
		goto err;

	if (info.st_size < atol(ssize)) goto err;

	goto out;
err:
	if (thumb) gdk_pixbuf_unref(thumb);
	thumb = NULL;
out:
	g_free(path);
	g_free(thumb_path);
	return thumb;
}
Exemplo n.º 13
0
Arquivo: gdkcursor.c Projeto: Vort/gtk
/**
 * gdk_cursor_new_from_pixbuf:
 * @display: the #GdkDisplay for which the cursor will be created
 * @pixbuf: the #GdkPixbuf containing the cursor image
 * @x: the horizontal offset of the “hotspot” of the cursor.
 * @y: the vertical offset of the “hotspot” of the cursor.
 *
 * Creates a new cursor from a pixbuf.
 *
 * Not all GDK backends support RGBA cursors. If they are not
 * supported, a monochrome approximation will be displayed.
 * The functions gdk_display_supports_cursor_alpha() and
 * gdk_display_supports_cursor_color() can be used to determine
 * whether RGBA cursors are supported;
 * gdk_display_get_default_cursor_size() and
 * gdk_display_get_maximal_cursor_size() give information about
 * cursor sizes.
 *
 * If @x or @y are `-1`, the pixbuf must have
 * options named “x_hot” and “y_hot”, resp., containing
 * integer values between `0` and the width resp. height of
 * the pixbuf. (Since: 3.0)
 *
 * On the X backend, support for RGBA cursors requires a
 * sufficently new version of the X Render extension.
 *
 * Returns: a new #GdkCursor.
 *
 * Since: 2.4
 */
GdkCursor *
gdk_cursor_new_from_pixbuf (GdkDisplay *display,
                            GdkPixbuf  *pixbuf,
                            gint        x,
                            gint        y)
{
  cairo_surface_t *surface;
  const char *option;
  char *end;
  gint64 value;
  GdkCursor *cursor;
 
  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);

  if (x == -1 && (option = gdk_pixbuf_get_option (pixbuf, "x_hot")))
    {
      errno = 0;
      end = NULL;
      value = g_ascii_strtoll (option, &end, 10);
      if (errno == 0 &&
          end != option &&
          value >= 0 && value < G_MAXINT)
        x = (gint) value;
    }
  
  if (y == -1 && (option = gdk_pixbuf_get_option (pixbuf, "y_hot")))
    {
      errno = 0;
      end = NULL;
      value = g_ascii_strtoll (option, &end, 10);
      if (errno == 0 &&
          end != option &&
          value >= 0 && value < G_MAXINT)
        y = (gint) value;
    }

  surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
  
  cursor = GDK_DISPLAY_GET_CLASS (display)->get_cursor_for_surface (display, surface, x, y);

  cairo_surface_destroy (surface);

  return cursor;
}
Exemplo n.º 14
0
inline static gboolean is_thumbnail_outdated(GdkPixbuf* thumb_pix, const char* path, time_t mtime)
{
    const char* thumb_mtime = gdk_pixbuf_get_option(thumb_pix, "tEXt::Thumb::MTime");
    /* out of date, delete it */
    if( !thumb_mtime || atol(thumb_mtime) != mtime )
    {
        unlink(path); /* delete the out-dated thumbnail. */
        g_object_unref(thumb_pix);
        return TRUE;
    }
    return FALSE;
}
Exemplo n.º 15
0
GList *
gimp_pattern_load_pixbuf (GimpContext   *context,
                          GFile         *file,
                          GInputStream  *input,
                          GError       **error)
{
  GimpPattern *pattern;
  GdkPixbuf   *pixbuf;
  gchar       *name;

  g_return_val_if_fail (G_IS_FILE (file), NULL);
  g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  pixbuf = gdk_pixbuf_new_from_stream (input, NULL, error);
  if (! pixbuf)
    return NULL;

  name = g_strdup (gdk_pixbuf_get_option (pixbuf, "tEXt::Title"));

  if (! name)
    name = g_strdup (gdk_pixbuf_get_option (pixbuf, "tEXt::Comment"));

  if (! name)
    name = g_path_get_basename (gimp_file_get_utf8_name (file));

  pattern = g_object_new (GIMP_TYPE_PATTERN,
                          "name",      name,
                          "mime-type", NULL, /* FIXME!! */
                          NULL);
  g_free (name);

  pattern->mask = gimp_temp_buf_new_from_pixbuf (pixbuf, NULL);

  g_object_unref (pixbuf);

  return g_list_prepend (NULL, pattern);
}
Exemplo n.º 16
0
static gboolean
append_option_value_pair (NemoImagePropertiesPage *page,
			  GdkPixbuf                   *pixbuf,
			  const char                  *key,
			  char                        *description)
{
	const char *value;

	value = gdk_pixbuf_get_option (pixbuf, key);
	if (value == NULL)
		return FALSE;

	append_item (page, description, value);
	return TRUE;
}
Exemplo n.º 17
0
static gint thumb_loader_std_fail_check(ThumbLoaderStd *tl)
{
	gchar *fail_path;
	gint result = FALSE;

	fail_path = thumb_loader_std_cache_path(tl, FALSE, NULL, TRUE);
	if (isfile(fail_path))
		{
		GdkPixbuf *pixbuf;

		if (tl->cache_retry)
			{
			pixbuf = NULL;
			}
		else
			{
			gchar *pathl;

			pathl = path_from_utf8(fail_path);
			pixbuf = gdk_pixbuf_new_from_file(pathl, NULL);
			g_free(pathl);
			}

		if (pixbuf)
			{
			const gchar *mtime_str;

			mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);
			if (mtime_str && strtol(mtime_str, NULL, 10) == tl->source_mtime)
				{
				result = TRUE;
				if (debug)
					{
					printf("thumb fail valid: %s\n", tl->source_path);
					printf("           thumb: %s\n", fail_path);
					}
				}

			g_object_unref(G_OBJECT(pixbuf));
			}

		if (!result) unlink_file(fail_path);
		}
	g_free(fail_path);

	return result;
}
Exemplo n.º 18
0
static gboolean
save_image_verify (const gchar *filename, GError **error)
{
	gboolean ret = FALSE;
	GdkPixbuf *pixbuf = NULL;
	const gchar *option;
	gchar *icc_profile = NULL;
	gsize len = 0;

	/* load */
	pixbuf = gdk_pixbuf_new_from_file (filename, error);
	if (pixbuf == NULL)
		goto out;

	/* check values */
	option = gdk_pixbuf_get_option (pixbuf, "icc-profile");
	if (option == NULL) {
		*error = g_error_new (1, 0, "no profile set");
		goto out;
	}

	/* decode base64 */
	icc_profile = (gchar *) g_base64_decode (option, &len);
	if (len != ICC_PROFILE_SIZE) {
		*error = g_error_new (1, 0,
		                      "profile length invalid, got %" G_GSIZE_FORMAT,
		                      len);
		g_file_set_contents ("error.icc", icc_profile, len, NULL);
		goto out;
	}

	/* success */
	ret = TRUE;
out:
	if (pixbuf != NULL)
		g_object_unref (pixbuf);
	g_free (icc_profile);
	return ret;
}
Exemplo n.º 19
0
static struct graphics_image_priv *
image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot, int rotation)
{
	GdkPixbuf *pixbuf;
	struct graphics_image_priv *ret;
	const char *option;
	
	if (!strcmp(name,"buffer:")) {
		struct graphics_image_buffer *buffer=(struct graphics_image_buffer *)name;
		GdkPixbufLoader *loader=gdk_pixbuf_loader_new();
		if (!loader)
			return NULL;
		if (*w != -1 || *h != -1)
			gdk_pixbuf_loader_set_size(loader, *w, *h);
		gdk_pixbuf_loader_write(loader, buffer->start, buffer->len, NULL);
		gdk_pixbuf_loader_close(loader, NULL);
		pixbuf=gdk_pixbuf_loader_get_pixbuf(loader);
		g_object_ref(pixbuf);
		g_object_unref(loader);
	} else {
		if (*w == -1 && *h == -1)
			pixbuf=gdk_pixbuf_new_from_file(name, NULL);
		else
			pixbuf=gdk_pixbuf_new_from_file_at_size(name, *w, *h, NULL);
	}

	if (!pixbuf)
		return NULL;

	if (rotation) {
		GdkPixbuf *tmp;
		switch (rotation) {
		case 90:
			rotation=270;
			break;
		case 180:
			break;
		case 270:
			rotation=90;
			break;
		default:
			return NULL;
		}

		tmp=gdk_pixbuf_rotate_simple(pixbuf, rotation);

		if (!tmp) {
			g_object_unref(pixbuf);
			return NULL;
		}

		g_object_unref(pixbuf);
		pixbuf=tmp;
	}

	ret=g_new0(struct graphics_image_priv, 1);
	ret->pixbuf=pixbuf;
	ret->w=gdk_pixbuf_get_width(pixbuf);
	ret->h=gdk_pixbuf_get_height(pixbuf);
	*w=ret->w;
	*h=ret->h;
	if (hot) {
		option=gdk_pixbuf_get_option(pixbuf, "x_hot");
		if (option)
			hot->x=atoi(option);
		else
			hot->x=ret->w/2-1;
		option=gdk_pixbuf_get_option(pixbuf, "y_hot");
		if (option)
			hot->y=atoi(option);
		else
			hot->y=ret->h/2-1;
	}
	return ret;
}
Exemplo n.º 20
0
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;

    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 <= 128 && h <= 128 )
    {
        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;
    }

    /* load existing thumbnail */
    thumbnail = gdk_pixbuf_new_from_file( thumbnail_file, NULL );
    if ( !thumbnail ||
            !( thumb_mtime = gdk_pixbuf_get_option( thumbnail, "tEXt::Thumb::MTime" ) ) ||
            atol( thumb_mtime ) != mtime )
    {
        if( thumbnail )
            g_object_unref( thumbnail );
        /* create new thumbnail */
        thumbnail = gdk_pixbuf_new_from_file_at_size( file_path, 128, 128, NULL );
        if ( thumbnail )
        {
            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. */
        }
    }

    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;
        }
        result = gdk_pixbuf_scale_simple(
                     thumbnail,
                     w, h, GDK_INTERP_BILINEAR );
        gdk_pixbuf_unref( thumbnail );
    }
    g_free( thumbnail_file );
    return result;
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
static gboolean
gwy_app_recent_file_try_load_thumbnail(GwyRecentFile *rf)
{
    GdkPixbuf *pixbuf;
    gint width, height;
    const gchar *option;
    GStatBuf st;
    gdouble scale;

    gwy_debug("<%s>", rf->thumb_sys);
    rf->thumb_state = FILE_STATE_FAILED;
    gwy_object_unref(rf->pixbuf);

    if (!rf->thumb_sys) {
        rf->pixbuf = gwy_app_recent_file_list_get_failed_pixbuf();
        g_object_ref(rf->pixbuf);
        return FALSE;
    }

    pixbuf = gdk_pixbuf_new_from_file(rf->thumb_sys, NULL);
    if (!pixbuf) {
        rf->pixbuf = gwy_app_recent_file_list_get_failed_pixbuf();
        g_object_ref(rf->pixbuf);
        return FALSE;
    }
    gwy_debug_objects_creation(G_OBJECT(pixbuf));

    width = gdk_pixbuf_get_width(pixbuf);
    height = gdk_pixbuf_get_height(pixbuf);
    scale = (gdouble)THUMB_SIZE/MAX(width, height);
    width = CLAMP((gint)(scale*width), 1, THUMB_SIZE);
    height = CLAMP((gint)(scale*height), 1, THUMB_SIZE);
    rf->pixbuf = gdk_pixbuf_scale_simple(pixbuf, width, height,
                                         GDK_INTERP_TILES);
    gwy_debug_objects_creation(G_OBJECT(rf->pixbuf));

    option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_URI);
    gwy_debug("uri = <%s>", rf->file_uri);
    if (!option || strcmp(option, rf->file_uri)) {
        g_warning("URI <%s> from thumb doesn't match <%s>. "
                  "If this isn't an MD5 collision, it's an implementation bug",
                  option, rf->file_uri);
    }

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_MTIME)))
        rf->thumb_mtime = atol(option);

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_FILESIZE)))
        rf->file_size = atol(option);

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_IMAGE_WIDTH)))
        rf->image_width = atoi(option);

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_IMAGE_HEIGHT)))
        rf->image_height = atoi(option);

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_GWY_REAL_SIZE)))
        rf->image_real_size = g_strdup(option);

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_GWY_IMAGES)))
        rf->image_images = atoi(option);

    if ((option = gdk_pixbuf_get_option(pixbuf, KEY_THUMB_GWY_GRAPHS)))
        rf->image_graphs = atoi(option);

    if (g_stat(rf->file_sys, &st) == 0) {
        rf->file_state = FILE_STATE_OK;
        rf->file_mtime = st.st_mtime;
        if (rf->thumb_mtime != rf->file_mtime)
            rf->thumb_state = FILE_STATE_OLD;
        else
            rf->thumb_state = FILE_STATE_OK;
    }
    else {
        rf->thumb_state = FILE_STATE_OLD;
        rf->file_state = FILE_STATE_FAILED;
    }

    g_object_unref(pixbuf);
    gwy_debug("<%s> thumbnail loaded OK", rf->file_utf8);

    return TRUE;
}
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf = NULL;
  const char *software;
  const char *uri;
  GtkTreeIter iter;
  GtkTreePath *path;
  GtkTreeRowReference *row_ref;
  GtkListStore *store;
  cairo_surface_t *surface = NULL;
  int scale_factor;

  item = g_object_get_data (source_object, "item");
  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_warning ("Failed to load image: %s", error->message);
          remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
        }

      g_error_free (error);
      goto out;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);
  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  uri = cc_background_item_get_uri (item);
  if (uri == NULL)
    uri = cc_background_item_get_source_url (item);

  /* Ignore screenshots */
  software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
  if (software != NULL &&
      g_str_equal (software, "gnome-screenshot"))
    {
      g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot", uri);
      remove_placeholder (BG_PICTURES_SOURCE (user_data), item);
      goto out;
    }

  scale_factor = bg_source_get_scale_factor (BG_SOURCE (bg_source));
  surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
  cc_background_item_load (item, NULL);

  row_ref = g_object_get_data (G_OBJECT (item), "row-ref");
  if (row_ref == NULL)
    {
      /* insert the item into the liststore if it did not exist */
      gtk_list_store_insert_with_values (store, NULL, -1,
                                         0, surface,
                                         1, item,
                                         -1);
    }
  else
    {
      path = gtk_tree_row_reference_get_path (row_ref);
      if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
        {
          /* otherwise update the thumbnail */
          gtk_list_store_set (store, &iter,
                              0, surface,
                              -1);
        }
    }

  g_hash_table_insert (bg_source->priv->known_items,
                       bg_pictures_source_get_unique_filename (uri),
                       GINT_TO_POINTER (TRUE));


 out:
  g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy);
  g_clear_object (&pixbuf);
}
Exemplo n.º 24
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);
}
Exemplo n.º 25
0
/**
 * gdk_pixbuf_apply_embedded_orientation:
 * @src: A #GdkPixbuf.
 *
 * Takes an existing pixbuf and checks for the presence of an
 * associated "orientation" option, which may be provided by the 
 * jpeg loader (which reads the exif orientation tag) or the 
 * tiff loader (which reads the tiff orientation tag, and
 * compensates it for the partial transforms performed by 
 * libtiff). If an orientation option/tag is present, the
 * appropriate transform will be performed so that the pixbuf
 * is oriented correctly.
 *
 * Return value: (transfer full): A newly-created pixbuf, or a reference to the
 * input pixbuf (with an increased reference count).
 *
 * Since: 2.12
 **/
GdkPixbuf *
gdk_pixbuf_apply_embedded_orientation (GdkPixbuf *src)
{
  	const gchar *orientation_string;
	int          transform = 0;
	GdkPixbuf   *temp;
	GdkPixbuf   *dest;

	g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL);

	/* Read the orientation option associated with the pixbuf */
	orientation_string = gdk_pixbuf_get_option (src, "orientation");	

	if (orientation_string) {
		/* If an orientation option was found, convert the 
		   orientation string into an integer. */
		transform = (int) g_ascii_strtoll (orientation_string, NULL, 10);
	}

	/* Apply the actual transforms, which involve rotations and flips. 
	   The meaning of orientation values 1-8 and the required transforms
	   are defined by the TIFF and EXIF (for JPEGs) standards. */
        switch (transform) {
        case 1:
                dest = src;
                g_object_ref (dest);
                break;
        case 2:
                dest = gdk_pixbuf_flip (src, TRUE);
                break;
        case 3:
                dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
                break;
        case 4:
                dest = gdk_pixbuf_flip (src, FALSE);
                break;
        case 5:
                temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
                dest = gdk_pixbuf_flip (temp, TRUE);
                g_object_unref (temp);
                break;
        case 6:
                dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
                break;
        case 7:
                temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE);
                dest = gdk_pixbuf_flip (temp, FALSE);
                g_object_unref (temp);
                break;
        case 8:
                dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
                break;
        default:
		/* if no orientation tag was present */
                dest = src;
                g_object_ref (dest);
                break;
        }

        return dest;
}
Exemplo n.º 26
0
static GdkPixbuf *
screenshot_fallback_get_pixbuf (GdkRectangle *rectangle)
{
  GdkWindow *root, *wm_window = NULL;
  GdkPixbuf *screenshot;
  GdkRectangle real_coords, screenshot_coords;
  Window wm;
  GtkBorder frame_offset = { 0, 0, 0, 0 };
  GdkWindow *window;

  window = screenshot_fallback_find_current_window ();

  screenshot_fallback_get_window_rect_coords (window, 
                                              screenshot_config->include_border,
                                              &real_coords,
                                              &screenshot_coords);

  wm = find_wm_window (window);
  if (wm != None)
    {
      GdkRectangle wm_real_coords;

      wm_window = gdk_x11_window_foreign_new_for_display 
        (gdk_window_get_display (window), wm);

      screenshot_fallback_get_window_rect_coords (wm_window,
                                                  FALSE,
                                                  &wm_real_coords,
                                                  NULL);

      frame_offset.left = (gdouble) (real_coords.x - wm_real_coords.x);
      frame_offset.top = (gdouble) (real_coords.y - wm_real_coords.y);
      frame_offset.right = (gdouble) (wm_real_coords.width - real_coords.width - frame_offset.left);
      frame_offset.bottom = (gdouble) (wm_real_coords.height - real_coords.height - frame_offset.top);
    }

  if (rectangle)
    {
      screenshot_coords.x = rectangle->x - screenshot_coords.x;
      screenshot_coords.y = rectangle->y - screenshot_coords.y;
      screenshot_coords.width  = rectangle->width;
      screenshot_coords.height = rectangle->height;
    }

  root = gdk_get_default_root_window ();
  screenshot = gdk_pixbuf_get_from_window (root,
                                           screenshot_coords.x, screenshot_coords.y,
                                           screenshot_coords.width, screenshot_coords.height);

  if (!screenshot_config->take_window_shot &&
      !screenshot_config->take_area_shot)
    mask_monitors (screenshot, root);

#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
  if (screenshot_config->include_border && (wm != None))
    {
      XRectangle *rectangles;
      GdkPixbuf *tmp;
      int rectangle_count, rectangle_order, i;

      /* we must use XShape to avoid showing what's under the rounder corners
       * of the WM decoration.
       */
      rectangles = XShapeGetRectangles (GDK_DISPLAY_XDISPLAY (gdk_display_get_default()),
                                        wm,
                                        ShapeBounding,
                                        &rectangle_count,
                                        &rectangle_order);
      if (rectangles && rectangle_count > 0)
        {
          gboolean has_alpha = gdk_pixbuf_get_has_alpha (screenshot);
          
          tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
                                screenshot_coords.width, screenshot_coords.height);
          gdk_pixbuf_fill (tmp, 0);
          
          for (i = 0; i < rectangle_count; i++)
            {
              gint rec_x, rec_y;
              gint rec_width, rec_height;
              gint y;

              /* If we're using invisible borders, the ShapeBounding might not
               * have the same size as the frame extents, as it would include the
               * areas for the invisible borders themselves.
               * In that case, trim every rectangle we get by the offset between the
               * WM window size and the frame extents.
               */
              rec_x = rectangles[i].x;
              rec_y = rectangles[i].y;
              rec_width = rectangles[i].width - (frame_offset.left + frame_offset.right);
              rec_height = rectangles[i].height - (frame_offset.top + frame_offset.bottom);

              if (real_coords.x < 0)
                {
                  rec_x += real_coords.x;
                  rec_x = MAX(rec_x, 0);
                  rec_width += real_coords.x;
                }

              if (real_coords.y < 0)
                {
                  rec_y += real_coords.y;
                  rec_y = MAX(rec_y, 0);
                  rec_height += real_coords.y;
                }

              if (screenshot_coords.x + rec_x + rec_width > gdk_screen_width ())
                rec_width = gdk_screen_width () - screenshot_coords.x - rec_x;

              if (screenshot_coords.y + rec_y + rec_height > gdk_screen_height ())
                rec_height = gdk_screen_height () - screenshot_coords.y - rec_y;

              for (y = rec_y; y < rec_y + rec_height; y++)
                {
                  guchar *src_pixels, *dest_pixels;
                  gint x;

                  src_pixels = gdk_pixbuf_get_pixels (screenshot)
                             + y * gdk_pixbuf_get_rowstride(screenshot)
                             + rec_x * (has_alpha ? 4 : 3);
                  dest_pixels = gdk_pixbuf_get_pixels (tmp)
                              + y * gdk_pixbuf_get_rowstride (tmp)
                              + rec_x * 4;

                  for (x = 0; x < rec_width; x++)
                    {
                      *dest_pixels++ = *src_pixels++;
                      *dest_pixels++ = *src_pixels++;
                      *dest_pixels++ = *src_pixels++;

                      if (has_alpha)
                        *dest_pixels++ = *src_pixels++;
                      else
                        *dest_pixels++ = 255;
                    }
                }
            }

          g_object_unref (screenshot);
          screenshot = tmp;

          XFree (rectangles);
        }
    }
#endif /* HAVE_X11_EXTENSIONS_SHAPE_H */

  /* if we have a selected area, there were by definition no cursor in the
   * screenshot */
  if (screenshot_config->include_pointer && !rectangle) 
    {
      GdkCursor *cursor;
      GdkPixbuf *cursor_pixbuf;

      cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_LEFT_PTR);
      cursor_pixbuf = gdk_cursor_get_image (cursor);

      if (cursor_pixbuf != NULL) 
        {
          GdkDeviceManager *manager;
          GdkDevice *device;
          GdkRectangle rect;
          gint cx, cy, xhot, yhot;

          manager = gdk_display_get_device_manager (gdk_display_get_default ());
          device = gdk_device_manager_get_client_pointer (manager);

          if (wm_window != NULL)
            gdk_window_get_device_position (wm_window, device,
                                            &cx, &cy, NULL);
          else
            gdk_window_get_device_position (window, device,
                                            &cx, &cy, NULL);

          sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "x_hot"), "%d", &xhot);
          sscanf (gdk_pixbuf_get_option (cursor_pixbuf, "y_hot"), "%d", &yhot);

          /* in rect we have the cursor window coordinates */
          rect.x = cx + real_coords.x;
          rect.y = cy + real_coords.y;
          rect.width = gdk_pixbuf_get_width (cursor_pixbuf);
          rect.height = gdk_pixbuf_get_height (cursor_pixbuf);

          /* see if the pointer is inside the window */
          if (gdk_rectangle_intersect (&real_coords, &rect, &rect)) 
            {
              gint cursor_x, cursor_y;

              cursor_x = cx - xhot - frame_offset.left;
              cursor_y = cy - yhot - frame_offset.top;
              gdk_pixbuf_composite (cursor_pixbuf, screenshot,
                                    cursor_x, cursor_y,
                                    rect.width, rect.height,
                                    cursor_x, cursor_y,
                                    1.0, 1.0, 
                                    GDK_INTERP_BILINEAR,
                                    255);
            }

          g_object_unref (cursor_pixbuf);
          g_object_unref (cursor);
        }
    }

  screenshot_fallback_fire_flash (window, rectangle);

  return screenshot;
}
Exemplo n.º 27
0
static char* get_image_text(GObject* image, const char* key)
{
    return g_strdup(gdk_pixbuf_get_option(GDK_PIXBUF(image), key));
}
Exemplo n.º 28
0
static void
picture_scaled (GObject *source_object,
                GAsyncResult *res,
                gpointer user_data)
{
  BgPicturesSource *bg_source;
  CcBackgroundItem *item;
  GError *error = NULL;
  GdkPixbuf *pixbuf;
  const char *source_url;
  const char *software;
  GtkTreeIter iter;
  GtkListStore *store;

  pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
  if (pixbuf == NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Failed to load image: %s", error->message);

      g_error_free (error);
      return;
    }

  /* since we were not cancelled, we can now cast user_data
   * back to BgPicturesSource.
   */
  bg_source = BG_PICTURES_SOURCE (user_data);
  store = bg_source_get_liststore (BG_SOURCE (bg_source));
  item = g_object_get_data (source_object, "item");

  gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (store),
                                   1,
                                   (GtkTreeIterCompareFunc)sort_func,
                                   bg_source,
                                   NULL);

  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
                                        1,
                                        GTK_SORT_ASCENDING);

  /* Ignore screenshots */
  software = gdk_pixbuf_get_option (pixbuf, "tEXt::Software");
  if (software != NULL &&
      g_str_equal (software, "gnome-screenshot"))
    {
      g_debug ("Ignored URL '%s' as it's a screenshot from gnome-screenshot",
               cc_background_item_get_uri (item));
      g_object_unref (pixbuf);
      g_object_unref (item);
      return;
    }

  cc_background_item_load (item, NULL);

  /* insert the item into the liststore */
  gtk_list_store_insert_with_values (store, &iter, 0,
                                     0, pixbuf,
                                     1, item,
                                     -1);
  source_url = cc_background_item_get_source_url (item);
  if (source_url != NULL)
    {
      g_hash_table_insert (bg_source->priv->known_items,
			   bg_pictures_source_get_unique_filename (source_url), GINT_TO_POINTER (TRUE));
    }
  else
    {
      char *cache_path;
      GFile *file, *parent, *dir;

      cache_path = bg_pictures_source_get_cache_path ();
      dir = g_file_new_for_path (cache_path);
      g_free (cache_path);

      file = g_file_new_for_uri (cc_background_item_get_uri (item));
      parent = g_file_get_parent (file);

      if (g_file_equal (parent, dir))
        {
          char *basename;
          basename = g_file_get_basename (file);
	  g_hash_table_insert (bg_source->priv->known_items,
			       basename, GINT_TO_POINTER (TRUE));
	}
      g_object_unref (file);
      g_object_unref (parent);
    }

  g_object_unref (pixbuf);
}
Exemplo n.º 29
0
/**
 * gd_create_collection_icon:
 * @base_size:
 * @pixbufs: (element-type GdkPixbuf):
 *
 * Returns: (transfer full):
 */
GIcon *
gd_create_collection_icon (gint base_size,
                           GList *pixbufs)
{
  cairo_surface_t *surface;
  GIcon *retval;
  cairo_t *cr;
  GtkStyleContext *context;
  GtkWidgetPath *path;
  GtkBorder tile_border;
  gint padding, tile_size;
  gint idx, cur_x, cur_y;
  GList *l;

  context = gtk_style_context_new ();
  gtk_style_context_add_class (context, "documents-collection-icon");

  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);
  gtk_style_context_set_path (context, path);
  gtk_widget_path_unref (path);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size);
  cr = cairo_create (surface);

  /* Render the thumbnail itself */
  gtk_render_background (context, cr,
                         0, 0, base_size, base_size);
  gtk_render_frame (context, cr,
                    0, 0, base_size, base_size);

  /* Now, render the tiles inside */
  gtk_style_context_remove_class (context, "documents-collection-icon");
  gtk_style_context_add_class (context, "documents-collection-icon-tile");

  /* TODO: do not hardcode 4, but scale to another layout if more
   * pixbufs are provided.
   */
  padding = MAX (floor (base_size / 10), 4);
  gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &tile_border);
  tile_size = (base_size - (3 * padding)) / 2 -
    MAX (tile_border.left + tile_border.right, tile_border.top + tile_border.bottom);

  l = pixbufs;
  idx = 0;
  cur_x = padding;
  cur_y = padding;

  while (l != NULL && idx < 4)
    {
      GdkPixbuf *pix;
      gboolean is_thumbnail;
      gint pix_width, pix_height, scale_size;

      pix = l->data;
      is_thumbnail = (gdk_pixbuf_get_option (pix, "-documents-has-thumb") != NULL);

      /* Only draw a box for thumbnails */
      if (is_thumbnail)
        {
          gtk_render_background (context, cr,
                                 cur_x, cur_y,
                                 tile_size + tile_border.left + tile_border.right,
                                 tile_size + tile_border.top + tile_border.bottom);
          gtk_render_frame (context, cr,
                            cur_x, cur_y,
                            tile_size + tile_border.left + tile_border.right,
                            tile_size + tile_border.top + tile_border.bottom);
        }

      pix_width = gdk_pixbuf_get_width (pix);
      pix_height = gdk_pixbuf_get_height (pix);
      scale_size = MIN (pix_width, pix_height);

      cairo_save (cr);

      cairo_translate (cr, cur_x + tile_border.left, cur_y + tile_border.top);
      cairo_rectangle (cr, 0, 0, tile_size, tile_size);
      cairo_clip (cr);

      cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size);
      gdk_cairo_set_source_pixbuf (cr, pix, 0, 0);
      cairo_paint (cr);

      cairo_restore (cr);

      if ((idx % 2) == 0)
        {
          cur_x += tile_size + padding + tile_border.left + tile_border.right;
        }
      else
        {
          cur_x = padding;
          cur_y += tile_size + padding + tile_border.top + tile_border.bottom;
        }

      idx++;
      l = l->next;
    }

  retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size));

  cairo_surface_destroy (surface);
  cairo_destroy (cr);
  g_object_unref (context);

  return retval;
}
Exemplo n.º 30
0
/**
 * gimp_thumbnail_load_thumb:
 * @thumbnail: a #GimpThumbnail object
 * @size: the preferred #GimpThumbSize for the preview
 * @error: return location for possible errors
 *
 * Attempts to load a thumbnail preview for the image associated with
 * @thumbnail. Before you use this function you need need to set an
 * image location using gimp_thumbnail_set_uri() or
 * gimp_thumbnail_set_filename(). You can also peek at the thumb
 * before loading it using gimp_thumbnail_peek_thumb.
 *
 * This function will return the best matching pixbuf for the
 * specified @size. It returns the pixbuf as loaded from disk. It is
 * left to the caller to scale it to the desired size. The returned
 * pixbuf may also represent an outdated preview of the image file.
 * In order to verify if the preview is uptodate, you should check the
 * "thumb_state" property after calling this function.
 *
 * Return value: a preview pixbuf or %NULL if no thumbnail was found
 **/
GdkPixbuf *
gimp_thumbnail_load_thumb (GimpThumbnail  *thumbnail,
                           GimpThumbSize   size,
                           GError        **error)
{
  GimpThumbState  state;
  GdkPixbuf      *pixbuf;
  const gchar    *option;
  gint64          image_mtime;
  gint64          image_size;

  g_return_val_if_fail (GIMP_IS_THUMBNAIL (thumbnail), NULL);

  GIMP_THUMB_DEBUG_CALL (thumbnail);

  if (! thumbnail->image_uri)
    return NULL;

  state = gimp_thumbnail_peek_thumb (thumbnail, size);

  if (state < GIMP_THUMB_STATE_EXISTS || state == GIMP_THUMB_STATE_FAILED)
    return NULL;

  pixbuf = gdk_pixbuf_new_from_file (thumbnail->thumb_filename, NULL);
  if (! pixbuf)
    return NULL;

#ifdef GIMP_THUMB_DEBUG
  g_printerr ("thumbnail loaded from %s\n", thumbnail->thumb_filename);
#endif

  g_object_freeze_notify (G_OBJECT (thumbnail));

  /* URI and mtime from the thumbnail need to match our file */
  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_URI);
  if (!option)
    goto finish;

  if (strcmp (option, thumbnail->image_uri))
    {
      /*  might be a local thumbnail, try if the local part matches  */
      const gchar *baseuri = strrchr (thumbnail->image_uri, '/');

      if (!baseuri || strcmp (option, baseuri))
        goto finish;
    }

  state = GIMP_THUMB_STATE_OLD;

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_MTIME);
  if (!option || sscanf (option, "%" G_GINT64_FORMAT, &image_mtime) != 1)
    goto finish;

  option = gdk_pixbuf_get_option (pixbuf, TAG_THUMB_FILESIZE);
  if (option && sscanf (option, "%" G_GINT64_FORMAT, &image_size) != 1)
    goto finish;

  /* TAG_THUMB_FILESIZE is optional but must match if present */
  if (image_mtime == thumbnail->image_mtime &&
      (option == NULL || image_size == thumbnail->image_filesize))
    {
      if (thumbnail->thumb_size == GIMP_THUMB_SIZE_FAIL)
        state = GIMP_THUMB_STATE_FAILED;
      else
        state = GIMP_THUMB_STATE_OK;
    }

  if (state == GIMP_THUMB_STATE_FAILED)
    gimp_thumbnail_reset_info (thumbnail);
  else
    gimp_thumbnail_set_info_from_pixbuf (thumbnail, pixbuf);

 finish:
  if (thumbnail->thumb_size == GIMP_THUMB_SIZE_FAIL ||
      (state != GIMP_THUMB_STATE_OLD && state != GIMP_THUMB_STATE_OK))
    {
      g_object_unref (pixbuf);
      pixbuf = NULL;
    }

  g_object_set (thumbnail,
                "thumb-state", state,
                NULL);

  g_object_thaw_notify (G_OBJECT (thumbnail));

  return pixbuf;
}