Beispiel #1
0
int
nsp_feed_update_icon(NspFeed *feed)
{
	NspNetData *data;
	char *icon_url = NULL;
	char *icon_path = NULL;
	GRegex *regex;
	GMatchInfo *match_info;
	CURL *curl;
	CURLcode result;
	GdkPixbufLoader *loader = NULL;
	GError *error = NULL;
	char *feed_id_string = NULL;
	
	/* Download web page */
	data = nsp_net_new();
	if ( nsp_net_load_url(feed->site_url, data) ) {
		g_warning("ERROR: %s\n", data->error);
		nsp_net_free(data);
		return 1;
	}
	
	/* Find <link> tag reffering to the icon */
	regex = g_regex_new ("<link[^>]*?rel=[\"'](icon|shortcut icon)[\"'][^>]*?href=[\"'](?<href>.*?)[\"'][^>]*?>", 0, 0, NULL);
	g_regex_match (regex, data->content, 0, &match_info);
	
	while (g_match_info_matches (match_info)) {
		gchar *word = g_match_info_fetch_named (match_info, "href");
		if ( !g_str_has_prefix(word, "http") ) {
			icon_url = g_strdup_printf("%s/%s", feed->site_url, word);
			g_free(word);
			break;
		}
		g_free (word);
		g_match_info_next (match_info, NULL);
	}
	g_match_info_free (match_info);
	g_regex_unref (regex);
	nsp_net_free(data);
	
	/* If no image is found - use home url + /favicon.ico */
	if ( icon_url == NULL ) {
		regex = g_regex_new ("^(?<hostname>https?://[^/]*)", 0, 0, NULL);
		g_regex_match (regex, feed->site_url, 0, &match_info);
		
		if (g_match_info_matches (match_info)) {
			gchar *word = g_match_info_fetch_named (match_info, "hostname");
			icon_url = g_strdup_printf("%s/favicon.ico", word);
			g_free (word);
		}
		
		g_match_info_free (match_info);
		g_regex_unref (regex);
	}
	
	/* Store the image to a GtkPixbufLoader */
	loader = gdk_pixbuf_loader_new();
	curl = curl_easy_init();
	curl_easy_setopt (curl, CURLOPT_URL, icon_url);
	curl_easy_setopt (curl, CURLOPT_HEADER, 0);
	curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, nsp_feed_download_icon_cb );
	curl_easy_setopt (curl, CURLOPT_WRITEDATA, loader);
	curl_easy_setopt (curl, CURLOPT_TIMEOUT, 60);
	curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1);
	
	result = curl_easy_perform (curl);
	curl_easy_cleanup(curl);
	g_free(icon_url);
	
	if ( result != 0) {
		return 1;
	}
	
	gdk_pixbuf_loader_close (loader, NULL);
	feed->icon = gdk_pixbuf_loader_get_pixbuf (loader);
	
	if ( !GDK_IS_PIXBUF(feed->icon) ) {
		feed->icon = NULL;
		return 1;
	}
	
	/* Resize and save the image */
	if (gdk_pixbuf_get_width (feed->icon) != 16 || gdk_pixbuf_get_height (feed->icon) != 16) {
		GdkPixbuf *old = feed->icon;
		feed->icon = gdk_pixbuf_scale_simple (old, 16, 16, GDK_INTERP_BILINEAR);
		g_object_unref (G_OBJECT (old));
	}
	
	feed_id_string = malloc(sizeof(char)*9);
	g_snprintf (feed_id_string, 9, "%i", feed->id);
	
	icon_path = g_build_filename( g_get_user_data_dir(), PACKAGE, "/icons", NULL);
	g_mkdir_with_parents(icon_path, 0700);
	
	icon_path = g_build_filename( icon_path, "/", feed_id_string, NULL);
	gdk_pixbuf_save(feed->icon, icon_path, "png", &error, NULL);
	
	if ( error != NULL ) {
		g_warning("ERROR: %s\n", error->message);
		g_error_free(error);
	}
	g_free(icon_path);
	free(feed_id_string);
	
	return 0;
}
Beispiel #2
0
/**
 * as_image_save_pixbuf:
 * @image: a #AsImage instance.
 * @width: target width, or 0 for default
 * @height: target height, or 0 for default
 * @flags: some #AsImageSaveFlags values, e.g. %AS_IMAGE_SAVE_FLAG_PAD_16_9
 *
 * Resamples a pixbuf to a specific size.
 *
 * Returns: (transfer full): A #GdkPixbuf of the specified size
 *
 * Since: 0.1.6
 **/
GdkPixbuf *
as_image_save_pixbuf (AsImage *image,
		      guint width,
		      guint height,
		      AsImageSaveFlags flags)
{
	AsImagePrivate *priv = GET_PRIVATE (image);
	GdkPixbuf *pixbuf = NULL;
	guint tmp_height;
	guint tmp_width;
	guint pixbuf_height;
	guint pixbuf_width;
	g_autoptr(GdkPixbuf) pixbuf_tmp = NULL;

	/* never set */
	if (priv->pixbuf == NULL)
		return NULL;

	/* 0 means 'default' */
	if (width == 0)
		width = (guint) gdk_pixbuf_get_width (priv->pixbuf);
	if (height == 0)
		height = (guint) gdk_pixbuf_get_height (priv->pixbuf);

	/* don't do anything to an image with the correct size */
	pixbuf_width = (guint) gdk_pixbuf_get_width (priv->pixbuf);
	pixbuf_height = (guint) gdk_pixbuf_get_height (priv->pixbuf);
	if (width == pixbuf_width && height == pixbuf_height)
		return g_object_ref (priv->pixbuf);

	/* is the aspect ratio of the source perfectly 16:9 */
	if (flags == AS_IMAGE_SAVE_FLAG_NONE ||
	    (pixbuf_width / 16) * 9 == pixbuf_height) {
		pixbuf = gdk_pixbuf_scale_simple (priv->pixbuf,
						  (gint) width, (gint) height,
						  GDK_INTERP_HYPER);
		if ((flags & AS_IMAGE_SAVE_FLAG_SHARPEN) > 0)
			as_pixbuf_sharpen (pixbuf, 1, -0.5);
		if ((flags & AS_IMAGE_SAVE_FLAG_BLUR) > 0)
			as_pixbuf_blur (pixbuf, 5, 3);
		return pixbuf;
	}

	/* create new 16:9 pixbuf with alpha padding */
	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
				 TRUE, 8,
				 (gint) width,
				 (gint) height);
	gdk_pixbuf_fill (pixbuf, 0x00000000);
	if ((pixbuf_width / 16) * 9 > pixbuf_height) {
		tmp_width = width;
		tmp_height = width * pixbuf_height / pixbuf_width;
	} else {
		tmp_width = height * pixbuf_width / pixbuf_height;
		tmp_height = height;
	}
	pixbuf_tmp = gdk_pixbuf_scale_simple (priv->pixbuf,
					      (gint) tmp_width,
					      (gint) tmp_height,
					      GDK_INTERP_HYPER);
	if ((flags & AS_IMAGE_SAVE_FLAG_SHARPEN) > 0)
		as_pixbuf_sharpen (pixbuf_tmp, 1, -0.5);
	if ((flags & AS_IMAGE_SAVE_FLAG_BLUR) > 0)
		as_pixbuf_blur (pixbuf_tmp, 5, 3);
	gdk_pixbuf_copy_area (pixbuf_tmp,
			      0, 0, /* of src */
			      (gint) tmp_width,
			      (gint) tmp_height,
			      pixbuf,
			      (gint) (width - tmp_width) / 2,
			      (gint) (height - tmp_height) / 2);
	return pixbuf;
}
Beispiel #3
0
// Updates the images according to preferences and the window situation
// Warning! This function is called very often, so it should only do the most necessary things!
void updateTitle(WTApplet *wtapplet) {
	WnckWindow *controlledwindow;
	gchar *title_text, *title_color, *title_font;
	GdkPixbuf *icon_pixbuf;

	if (wtapplet->prefs->only_maximized) {
		controlledwindow = wtapplet->umaxedwindow;
	} else {
		controlledwindow = wtapplet->activewindow;
	}

	if (controlledwindow == NULL)
		return;

	if (controlledwindow == wtapplet->rootwindow) {
		// we're on desktop
		if (wtapplet->prefs->hide_on_unmaximized) {
			// hide everything
			icon_pixbuf = NULL;
			title_text = "";
		} else {
			// display "custom" icon/title (TODO: customization via preferences?)
			icon_pixbuf = gtk_widget_render_icon(GTK_WIDGET(wtapplet),GTK_STOCK_HOME,GTK_ICON_SIZE_MENU,NULL); // This has to be unrefed!
			title_text = ("Desktop");
		}
	} else {
		icon_pixbuf = wnck_window_get_icon(controlledwindow); // This only returns a pointer - it SHOULDN'T be unrefed!
		title_text = (gchar*)wnck_window_get_name(controlledwindow);
	}

	// TODO: we need the default font to somehow be the same in both modes
	if (wtapplet->prefs->custom_style) {
		// custom style
		if (controlledwindow == wtapplet->activewindow) {
			// window focused
			title_color = wtapplet->prefs->title_active_color;
			title_font = wtapplet->prefs->title_active_font;
		} else {
			// window unfocused
			title_color = wtapplet->prefs->title_inactive_color;
			title_font = wtapplet->prefs->title_inactive_font;
		}
	} else {
		// automatic (non-custom) style
		if (controlledwindow == wtapplet->activewindow) {
			// window focused
			title_color = wtapplet->panel_color_fg;
			title_font = "";
		} else {
			// window unfocused
			title_color = "#808080"; // inactive title color. best fits for any panel regardless of color
			title_font = "";
		}
	}

	// Set tooltips
	if (wtapplet->prefs->show_tooltips) {
		gtk_widget_set_tooltip_text (GTK_WIDGET(wtapplet->icon), title_text);
		gtk_widget_set_tooltip_text (GTK_WIDGET(wtapplet->title), title_text);
	}

	title_text = g_markup_printf_escaped("<span font=\"%s\" color=\"%s\">%s</span>", title_font, title_color, title_text);
	// Apply markup to label widget
	gtk_label_set_markup(GTK_LABEL(wtapplet->title), title_text);
	g_free(title_text);

	if (icon_pixbuf == NULL) {
		gtk_image_clear(wtapplet->icon);
	} else {
		// We're updating window info (Careful! We've had pixbuf memory leaks here)
		GdkPixbuf *ipb1 = gdk_pixbuf_scale_simple(icon_pixbuf, ICON_WIDTH, ICON_HEIGHT, GDK_INTERP_BILINEAR);
		if (controlledwindow == wtapplet->rootwindow) g_object_unref(icon_pixbuf); //this is stupid beyond belief, thanks to the retarded GTK framework
		GdkPixbuf *ipb2 = gdk_pixbuf_rotate_simple(ipb1, wtapplet->angle);
		g_object_unref(ipb1);	// Unref ipb1 to get it cleared from memory (we still need ipb2)

		// Saturate icon when window is not focused
		if (controlledwindow != wtapplet->activewindow)
			gdk_pixbuf_saturate_and_pixelate(ipb2, ipb2, 0, FALSE);

		// Apply pixbuf to icon widget
		gtk_image_set_from_pixbuf(wtapplet->icon, ipb2);
		g_object_unref(ipb2);   // Unref ipb2 to get it cleared from memory
	}
}
Beispiel #4
0
nsresult
nsIconChannel::InitWithGnome(nsIMozIconURI *aIconURI)
{
  nsresult rv;
  
  if (!gnome_program_get()) {
    // Get the brandShortName from the string bundle to pass to GNOME
    // as the application name.  This may be used for things such as
    // the title of grouped windows in the panel.
    nsCOMPtr<nsIStringBundleService> bundleService = 
      do_GetService(NS_STRINGBUNDLE_CONTRACTID);

    NS_ASSERTION(bundleService, "String bundle service must be present!");

    nsCOMPtr<nsIStringBundle> bundle;
    bundleService->CreateBundle("chrome://branding/locale/brand.properties",
                                getter_AddRefs(bundle));
    nsXPIDLString appName;

    if (bundle) {
      bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
                                getter_Copies(appName));
    } else {
      NS_WARNING("brand.properties not present, using default application name");
      appName.AssignLiteral("Gecko");
    }

    char* empty[] = { "" };
    gnome_init(NS_ConvertUTF16toUTF8(appName).get(), "1.0", 1, empty);
  }

  nsCAutoString iconSizeString;
  aIconURI->GetIconSize(iconSizeString);

  PRUint32 iconSize;

  if (iconSizeString.IsEmpty()) {
    rv = aIconURI->GetImageSize(&iconSize);
    NS_ASSERTION(NS_SUCCEEDED(rv), "GetImageSize failed");
  } else {
    int size;
    
    GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get());
    gtk_icon_size_lookup(icon_size, &size, NULL);
    iconSize = size;
  }

  nsCAutoString type;
  aIconURI->GetContentType(type);

  GnomeVFSFileInfo fileInfo = {0};
  fileInfo.refcount = 1; // In case some GnomeVFS function addrefs and releases it

  nsCAutoString spec;
  nsCOMPtr<nsIURI> fileURI;
  rv = aIconURI->GetIconFile(getter_AddRefs(fileURI));
  if (fileURI) {
    fileURI->GetAsciiSpec(spec);
    // Only ask gnome-vfs for a GnomeVFSFileInfo for file: uris, to avoid a
    // network request
    PRBool isFile;
    if (NS_SUCCEEDED(fileURI->SchemeIs("file", &isFile)) && isFile) {
      gnome_vfs_get_file_info(spec.get(), &fileInfo, GNOME_VFS_FILE_INFO_DEFAULT);
    }
    else {
      // We have to get a leaf name from our uri...
      nsCOMPtr<nsIURL> url(do_QueryInterface(fileURI));
      if (url) {
        nsCAutoString name;
        // The filename we get is UTF-8-compatible, which matches gnome expectations.
        // See also: http://lists.gnome.org/archives/gnome-vfs-list/2004-March/msg00049.html
        // "Whenever we can detect the charset used for the URI type we try to
        //  convert it to/from utf8 automatically inside gnome-vfs."
        // I'll interpret that as "otherwise, this field is random junk".
        url->GetFileName(name);
        fileInfo.name = g_strdup(name.get());
      }
      // If this is no nsIURL, nothing we can do really.

      if (!type.IsEmpty()) {
        fileInfo.valid_fields = GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
        fileInfo.mime_type = g_strdup(type.get());
      }
    }
  }


  if (type.IsEmpty()) {
    nsCOMPtr<nsIMIMEService> ms(do_GetService("@mozilla.org/mime;1"));
    if (ms) {
      nsCAutoString fileExt;
      aIconURI->GetFileExtension(fileExt);
      ms->GetTypeFromExtension(fileExt, type);
    }
  }

  // Get the icon theme
  if (!gIconTheme) {
    gIconTheme = gnome_icon_theme_new();
    if (!gIconTheme) {
      gnome_vfs_file_info_clear(&fileInfo);
      return NS_ERROR_NOT_AVAILABLE;
    }
  }

  char* name = gnome_icon_lookup(gIconTheme, NULL, spec.get(), NULL, &fileInfo,
                                 type.get(), GNOME_ICON_LOOKUP_FLAGS_NONE,
                                 NULL);
  gnome_vfs_file_info_clear(&fileInfo);
  if (!name) {
    return NS_ERROR_NOT_AVAILABLE;
  }
 
  char* file = gnome_icon_theme_lookup_icon(gIconTheme, name, iconSize,
                                            NULL, NULL);
  g_free(name);
  if (!file)
    return NS_ERROR_NOT_AVAILABLE;

  // Create a GdkPixbuf buffer and scale it
  GError *err = nsnull;
  GdkPixbuf* buf = gdk_pixbuf_new_from_file(file, &err);
  g_free(file);
  if (!buf) {
    if (err)
      g_error_free(err);
    return NS_ERROR_UNEXPECTED;
  }

  GdkPixbuf* scaled = buf;
  if (gdk_pixbuf_get_width(buf)  != iconSize &&
      gdk_pixbuf_get_height(buf) != iconSize) {
    // scale...
    scaled = gdk_pixbuf_scale_simple(buf, iconSize, iconSize,
                                     GDK_INTERP_BILINEAR);
    gdk_pixbuf_unref(buf);
    if (!scaled)
      return NS_ERROR_OUT_OF_MEMORY;
  }

  // XXX Respect icon state
  
  rv = moz_gdk_pixbuf_to_channel(scaled, aIconURI,
                                 getter_AddRefs(mRealChannel));
  gdk_pixbuf_unref(scaled);
  return rv;
}
Beispiel #5
0
/**
 * as_image_load_filename_full:
 * @image: a #AsImage instance.
 * @filename: filename to read from
 * @dest_size: The size of the constructed pixbuf, or 0 for the native size
 * @src_size_min: The smallest source size allowed, or 0 for none
 * @flags: a #AsImageLoadFlags, e.g. %AS_IMAGE_LOAD_FLAG_NONE
 * @error: A #GError or %NULL.
 *
 * Reads an image from a file.
 *
 * Returns: %TRUE for success
 *
 * Since: 0.5.6
 **/
gboolean
as_image_load_filename_full (AsImage *image,
			     const gchar *filename,
			     guint dest_size,
			     guint src_size_min,
			     AsImageLoadFlags flags,
			     GError **error)
{
	AsImagePrivate *priv = GET_PRIVATE (image);
	guint pixbuf_height;
	guint pixbuf_width;
	guint tmp_height;
	guint tmp_width;
	g_autoptr(GdkPixbuf) pixbuf = NULL;
	g_autoptr(GdkPixbuf) pixbuf_src = NULL;
	g_autoptr(GdkPixbuf) pixbuf_tmp = NULL;

	/* only support non-deprecated types */
	if (flags & AS_IMAGE_LOAD_FLAG_ONLY_SUPPORTED) {
		GdkPixbufFormat *fmt;
		fmt = gdk_pixbuf_get_file_info (filename, NULL, NULL);
		if (fmt == NULL) {
			g_set_error_literal (error,
					     AS_UTILS_ERROR,
					     AS_UTILS_ERROR_FAILED,
					     "image format was not recognized");
			return FALSE;
		}
		if (g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "png") != 0 &&
		    g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "jpeg") != 0 &&
		    g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "xpm") != 0 &&
		    g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "svg") != 0) {
			g_set_error (error,
				     AS_UTILS_ERROR,
				     AS_UTILS_ERROR_FAILED,
				     "image format %s is not supported",
				     gdk_pixbuf_format_get_name (fmt));
			return FALSE;
		}
	}

	/* update basename */
	if (flags & AS_IMAGE_LOAD_FLAG_SET_BASENAME) {
		g_autofree gchar *basename = NULL;
		basename = g_path_get_basename (filename);
		as_image_set_basename (image, basename);
	}

	/* update checksum */
	if (flags & AS_IMAGE_LOAD_FLAG_SET_CHECKSUM) {
		gsize len;
		g_autofree gchar *data = NULL;
		g_autofree gchar *md5_tmp = NULL;

		/* get the contents so we can hash the predictable file data,
		 * rather than the unpredicatable (for JPEG) pixel data */
		if (!g_file_get_contents (filename, &data, &len, error))
			return FALSE;
		md5_tmp = g_compute_checksum_for_data (G_CHECKSUM_MD5,
						       (guchar * )data, len);
		as_ref_string_assign_safe (&priv->md5, md5_tmp);
	}

	/* load the image of the native size */
	if (dest_size == 0) {
		pixbuf = gdk_pixbuf_new_from_file (filename, error);
		if (pixbuf == NULL)
			return FALSE;
		as_image_set_pixbuf (image, pixbuf);
		return TRUE;
	}

	/* open file in native size */
	if (g_str_has_suffix (filename, ".svg")) {
		pixbuf_src = gdk_pixbuf_new_from_file_at_scale (filename,
								(gint) dest_size,
								(gint) dest_size,
								TRUE, error);
	} else {
		pixbuf_src = gdk_pixbuf_new_from_file (filename, error);
	}
	if (pixbuf_src == NULL)
		return FALSE;

	/* check size */
	if (gdk_pixbuf_get_width (pixbuf_src) < (gint) src_size_min &&
	    gdk_pixbuf_get_height (pixbuf_src) < (gint) src_size_min) {
		g_set_error (error,
			     AS_UTILS_ERROR,
			     AS_UTILS_ERROR_FAILED,
			     "icon was too small %ix%i",
			     gdk_pixbuf_get_width (pixbuf_src),
			     gdk_pixbuf_get_height (pixbuf_src));
		return FALSE;
	}

	/* don't do anything to an icon with the perfect size */
	pixbuf_width = (guint) gdk_pixbuf_get_width (pixbuf_src);
	pixbuf_height = (guint) gdk_pixbuf_get_height (pixbuf_src);
	if (pixbuf_width == dest_size && pixbuf_height == dest_size) {
		as_image_set_pixbuf (image, pixbuf_src);
		return TRUE;
	}

	/* never scale up, just pad */
	if (pixbuf_width < dest_size && pixbuf_height < dest_size) {
		g_debug ("icon padded to %ux%u as size %ux%u",
			 dest_size, dest_size,
			 pixbuf_width, pixbuf_height);
		pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
					 (gint) dest_size, (gint) dest_size);
		gdk_pixbuf_fill (pixbuf, 0x00000000);
		gdk_pixbuf_copy_area (pixbuf_src,
				      0, 0, /* of src */
				      (gint) pixbuf_width,
				      (gint) pixbuf_height,
				      pixbuf,
				      (gint) (dest_size - pixbuf_width) / 2,
				      (gint) (dest_size - pixbuf_height) / 2);
		as_image_set_pixbuf (image, pixbuf);
		return TRUE;
	}

	/* is the aspect ratio perfectly square */
	if (pixbuf_width == pixbuf_height) {
		pixbuf = gdk_pixbuf_scale_simple (pixbuf_src,
						  (gint) dest_size,
						  (gint) dest_size,
						  GDK_INTERP_HYPER);
		as_image_set_pixbuf (image, pixbuf);
		return TRUE;
	}

	/* create new square pixbuf with alpha padding */
	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
				 (gint) dest_size, (gint) dest_size);
	gdk_pixbuf_fill (pixbuf, 0x00000000);
	if (pixbuf_width > pixbuf_height) {
		tmp_width = dest_size;
		tmp_height = dest_size * pixbuf_height / pixbuf_width;
	} else {
		tmp_width = dest_size * pixbuf_width / pixbuf_height;
		tmp_height = dest_size;
	}
	pixbuf_tmp = gdk_pixbuf_scale_simple (pixbuf_src,
					      (gint) tmp_width,
					      (gint) tmp_height,
					      GDK_INTERP_HYPER);
	if (flags & AS_IMAGE_LOAD_FLAG_SHARPEN)
		as_pixbuf_sharpen (pixbuf_tmp, 1, -0.5);
	gdk_pixbuf_copy_area (pixbuf_tmp,
			      0, 0, /* of src */
			      (gint) tmp_width, (gint) tmp_height,
			      pixbuf,
			      (gint) (dest_size - tmp_width) / 2,
			      (gint) (dest_size - tmp_height) / 2);
	as_image_set_pixbuf (image, pixbuf);
	return TRUE;
}
Beispiel #6
0
int compositor_process(weed_plant_t *inst, weed_timecode_t timecode) {
  int error;
  weed_plant_t **in_channels=NULL;
  int num_in_channels=0;
  weed_plant_t *out_channel=weed_get_plantptr_value(inst,"out_channels",&error);

  unsigned char *src;
  unsigned char *dst=weed_get_voidptr_value(out_channel,"pixel_data",&error),*dst2;

  int owidth=weed_get_int_value(out_channel,"width",&error),owidth3=owidth*3;
  int oheight=weed_get_int_value(out_channel,"height",&error);

  int in_width,in_height,out_width,out_height;

  int irowstride;
  int orowstride=weed_get_int_value(out_channel,"rowstrides",&error);
  //int palette=weed_get_int_value(out_channel,"current_palette",&error);

  weed_plant_t **in_params;

  int numscalex,numscaley,numoffsx,numoffsy,numalpha;
  int *bgcol;
  double *offsx,*offsy,*scalex,*scaley,*alpha;

  double myoffsx,myoffsy,myscalex,myscaley,myalpha;

  unsigned char *end;

  register int x,y,z;

  GdkPixbuf *in_pixbuf,*out_pixbuf;

  int up_interp=GDK_INTERP_HYPER;
  int down_interp=GDK_INTERP_BILINEAR;



  if (weed_plant_has_leaf(inst,"in_channels")) {
    num_in_channels=weed_leaf_num_elements(inst,"in_channels");
    in_channels=weed_get_plantptr_array(inst,"in_channels",&error);
  }

  in_params=weed_get_plantptr_array(inst,"in_parameters",&error);

  numoffsx=weed_leaf_num_elements(in_params[0],"value");
  offsx=weed_get_double_array(in_params[0],"value",&error);

  numoffsy=weed_leaf_num_elements(in_params[1],"value");
  offsy=weed_get_double_array(in_params[1],"value",&error);

  numscalex=weed_leaf_num_elements(in_params[2],"value");
  scalex=weed_get_double_array(in_params[2],"value",&error);

  numscaley=weed_leaf_num_elements(in_params[3],"value");
  scaley=weed_get_double_array(in_params[3],"value",&error);

  numalpha=weed_leaf_num_elements(in_params[4],"value");
  alpha=weed_get_double_array(in_params[4],"value",&error);

  bgcol=weed_get_int_array(in_params[5],"value",&error);

  // set out frame to bgcol

  end=dst+oheight*orowstride;
  for (dst2=dst; dst2<end; dst2+=orowstride) {
    for (x=0; x<owidth3; x+=3) {
      dst2[x]=bgcol[0];
      dst2[x+1]=bgcol[1];
      dst2[x+2]=bgcol[2];
    }
  }

  weed_free(bgcol);

  // add overlays in reverse order

  for (z=num_in_channels-1; z>=0; z--) {
    // check if host disabled this channel : this is allowed as we have set "max_repeats"
    if (weed_plant_has_leaf(in_channels[z],"disabled")&&weed_get_boolean_value(in_channels[z],"disabled",&error)==WEED_TRUE) continue;

    if (z<numoffsx) myoffsx=(int)(offsx[z]*(double)owidth);
    else myoffsx=0;
    if (z<numoffsy) myoffsy=(int)(offsy[z]*(double)oheight);
    else myoffsy=0;
    if (z<numscalex) myscalex=scalex[z];
    else myscalex=1.;
    if (z<numscaley) myscaley=scaley[z];
    else myscaley=1.;
    if (z<numalpha) myalpha=alpha[z];
    else myalpha=1.;

    out_width=(owidth*myscalex+.5);
    out_height=(oheight*myscaley+.5);

    if (out_width*out_height>0) {
      in_width=weed_get_int_value(in_channels[z],"width",&error);
      in_height=weed_get_int_value(in_channels[z],"height",&error);

      src=weed_get_voidptr_value(in_channels[z],"pixel_data",&error);
      irowstride=weed_get_int_value(in_channels[z],"rowstrides",&error);

      // scale image to new size

      in_pixbuf=pl_data_to_pixbuf(WEED_PALETTE_RGB24, in_width, in_height, irowstride, (guchar *)src);

      if (out_width>in_width||out_height>in_height) {
        out_pixbuf=gdk_pixbuf_scale_simple(in_pixbuf,out_width,out_height,up_interp);
      } else {
        out_pixbuf=gdk_pixbuf_scale_simple(in_pixbuf,out_width,out_height,down_interp);
      }

      g_object_unref(in_pixbuf);

      src=gdk_pixbuf_get_pixels(out_pixbuf);

      out_width=gdk_pixbuf_get_width(out_pixbuf);
      out_height=gdk_pixbuf_get_height(out_pixbuf);
      irowstride=gdk_pixbuf_get_rowstride(out_pixbuf);


      for (y=myoffsy; y<oheight&&y<myoffsy+out_height; y++) {
        for (x=myoffsx; x<owidth&&x<myoffsx+out_width; x++) {
          paint_pixel(dst,y*orowstride+x*3,src,(y-myoffsy)*irowstride+(x-myoffsx)*3,myalpha);
        }
      }
      g_object_unref(out_pixbuf);
    }
  }

  weed_free(offsx);
  weed_free(offsy);
  weed_free(scalex);
  weed_free(scaley);
  weed_free(alpha);

  if (num_in_channels>0) weed_free(in_channels);
  return WEED_NO_ERROR;
}
Beispiel #7
0
static void
insert_text (GtkTextBuffer *buffer)
{
  GtkTextIter iter;
  GtkTextIter start, end;
  GdkPixbuf *pixbuf;
  GdkPixbuf *scaled;
  char *filename;

  /* demo_find_file() looks in the current directory first,
   * so you can run gtk-demo without installing GTK, then looks
   * in the location where the file is installed.
   */
  pixbuf = NULL;
  filename = demo_find_file ("gtk-logo-rgb.gif", NULL);
  if (filename)
    {
      pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
      g_free (filename);
    }

  if (pixbuf == NULL)
    {
      g_printerr ("Failed to load image file gtk-logo-rgb.gif\n");
      exit (1);
    }

  scaled = gdk_pixbuf_scale_simple (pixbuf, 32, 32, GDK_INTERP_BILINEAR);
  g_object_unref (pixbuf);
  pixbuf = scaled;

  /* get start of buffer; each insertion will revalidate the
   * iterator to point to just after the inserted text.
   */
  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);

  gtk_text_buffer_insert (buffer, &iter,
      "The text widget can display text with all kinds of nifty attributes. "
      "It also supports multiple views of the same buffer; this demo is "
      "showing the same buffer in two places.\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Font styles. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert (buffer, &iter, "For example, you can have ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "italic", -1,
                                            "italic", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "bold", -1,
                                            "bold", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", or ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "monospace (typewriter)", -1,
                                            "monospace", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", or ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "big", -1,
                                            "big", NULL);
  gtk_text_buffer_insert (buffer, &iter, " text. ", -1);
  gtk_text_buffer_insert (buffer, &iter,
      "It's best not to hardcode specific text sizes; you can use relative "
      "sizes as with CSS, such as ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "xx-small", -1,
                                            "xx-small", NULL);
  gtk_text_buffer_insert (buffer, &iter, " or ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "x-large", -1,
                                            "x-large", NULL);
  gtk_text_buffer_insert (buffer, &iter,
      " to ensure that your program properly adapts if the user changes the "
      "default font size.\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Colors. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert (buffer, &iter, "Colors such as ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "a blue foreground", -1,
                                            "blue_foreground", NULL);
  gtk_text_buffer_insert (buffer, &iter, " or ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "a red background", -1,
                                            "red_background", NULL);
  gtk_text_buffer_insert (buffer, &iter, " or even ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "a blue foreground on red background", -1,
                                            "blue_foreground",
                                            "red_background",
                                            NULL);
  gtk_text_buffer_insert (buffer, &iter, " (select that to read it) can be used.\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Underline, strikethrough, and rise. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Strikethrough", -1,
                                            "strikethrough", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "underline", -1,
                                            "underline", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "double underline", -1,
                                            "double_underline", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "superscript", -1,
                                            "superscript", NULL);
  gtk_text_buffer_insert (buffer, &iter, ", and ", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "subscript", -1,
                                            "subscript", NULL);
  gtk_text_buffer_insert (buffer, &iter, " are all supported.\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Images. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
  gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
  gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
  gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
  gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Spacing. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert (buffer, &iter,
      "You can adjust the amount of space before each line.\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "This line has a whole lot of space before it.\n", -1,
      "big_gap_before_line", "wide_margins", NULL);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "You can also adjust the amount of space after each line; "
      "this line has a whole lot of space after it.\n", -1,
      "big_gap_after_line", "wide_margins", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "You can also adjust the amount of space between wrapped lines; "
      "this line has extra space between each wrapped line in the same "
      "paragraph. To show off wrapping, some filler text: the quick "
      "brown fox jumped over the lazy dog. Blah blah blah blah blah "
      "blah blah blah blah.\n", -1,
      "double_spaced_line", "wide_margins", NULL);

  gtk_text_buffer_insert (buffer, &iter,
      "Also note that those lines have extra-wide margins.\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Editability. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "This line is 'locked down' and can't be edited by the user - just "
      "try it! You can't delete this line.\n\n", -1,
      "not_editable", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Wrapping. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert (buffer, &iter,
      "This line (and most of the others in this buffer) is word-wrapped, "
      "using the proper Unicode algorithm. Word wrap should work in all "
      "scripts and languages that GTK+ supports. Let's make this a long "
      "paragraph to demonstrate: blah blah blah blah blah blah blah blah "
      "blah blah blah blah blah blah blah blah blah blah blah\n\n", -1);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "This line has character-based wrapping, and can wrap between any two "
      "character glyphs. Let's make this a long paragraph to demonstrate: "
      "blah blah blah blah blah blah blah blah blah blah blah blah blah blah "
      "blah blah blah blah blah\n\n", -1, "char_wrap", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "This line has all wrapping turned off, so it makes the horizontal "
      "scrollbar appear.\n\n\n", -1, "no_wrap", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Justification. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "\nThis line has center justification.\n", -1,
                                            "center", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "This line has right justification.\n", -1,
                                            "right_justify", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "\nThis line has big wide margins. Text text text text text text text "
      "text text text text text text text text text text text text text text "
      "text text text text text text text text text text text text text text "
      "text.\n", -1, "wide_margins", NULL);

  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
                                            "Internationalization. ", -1,
                                            "heading", NULL);

  gtk_text_buffer_insert (buffer, &iter,
      "You can put all sorts of Unicode text in the buffer.\n\nGerman "
      "(Deutsch S\303\274d) Gr\303\274\303\237 Gott\nGreek "
      "(\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) "
      "\316\223\316\265\316\271\316\254 \317\203\316\261\317\202\nHebrew      "
      "\327\251\327\234\327\225\327\235\nJapanese "
      "(\346\227\245\346\234\254\350\252\236)\n\nThe widget properly handles "
      "bidirectional text, word wrapping, DOS/UNIX/Unicode paragraph separators, "
      "grapheme boundaries, and so on using the Pango internationalization "
      "framework.\n", -1);

  gtk_text_buffer_insert (buffer, &iter,
      "Here's a word-wrapped quote in a right-to-left language:\n", -1);
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
      "\331\210\331\202\330\257 \330\250\330\257\330\243 "
      "\330\253\331\204\330\247\330\253 \331\205\331\206 "
      "\330\243\331\203\330\253\330\261 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 "
      "\330\252\331\202\330\257\331\205\330\247 \331\201\331\212 "
      "\330\264\330\250\331\203\330\251 \330\247\331\203\330\263\331\212\331\210\331\206 "
      "\330\250\330\261\330\247\331\205\330\254\331\207\330\247 "
      "\331\203\331\205\331\206\330\270\331\205\330\247\330\252 "
      "\331\204\330\247 \330\252\330\263\330\271\331\211 \331\204\331\204\330\261\330\250\330\255\330\214 "
      "\330\253\331\205 \330\252\330\255\331\210\331\204\330\252 "
      "\331\201\331\212 \330\247\331\204\330\263\331\206\331\210\330\247\330\252 "
      "\330\247\331\204\330\256\331\205\330\263 \330\247\331\204\331\205\330\247\330\266\331\212\330\251 "
      "\330\245\331\204\331\211 \331\205\330\244\330\263\330\263\330\247\330\252 "
      "\331\205\330\247\331\204\331\212\330\251 \331\205\331\206\330\270\331\205\330\251\330\214 "
      "\331\210\330\250\330\247\330\252\330\252 \330\254\330\262\330\241\330\247 "
      "\331\205\331\206 \330\247\331\204\331\206\330\270\330\247\331\205 "
      "\330\247\331\204\331\205\330\247\331\204\331\212 \331\201\331\212 "
      "\330\250\331\204\330\257\330\247\331\206\331\207\330\247\330\214 "
      "\331\210\331\204\331\203\331\206\331\207\330\247 \330\252\330\252\330\256\330\265\330\265 "
      "\331\201\331\212 \330\256\330\257\331\205\330\251 \331\202\330\267\330\247\330\271 "
      "\330\247\331\204\331\205\330\264\330\261\331\210\330\271\330\247\330\252 "
      "\330\247\331\204\330\265\330\272\331\212\330\261\330\251. \331\210\330\243\330\255\330\257 "
      "\330\243\331\203\330\253\330\261 \331\207\330\260\331\207 "
      "\330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 "
      "\331\206\330\254\330\247\330\255\330\247 \331\207\331\210 "
      "\302\273\330\250\330\247\331\206\331\203\331\210\330\263\331\210\331\204\302\253 "
      "\331\201\331\212 \330\250\331\210\331\204\331\212\331\201\331\212\330\247.\n\n", -1,
                                                "rtl_quote", NULL);

  gtk_text_buffer_insert (buffer, &iter,
                          "You can put widgets in the buffer: Here's a button: ", -1);
  gtk_text_buffer_create_child_anchor (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, " and a menu: ", -1);
  gtk_text_buffer_create_child_anchor (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, " and a scale: ", -1);
  gtk_text_buffer_create_child_anchor (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, " and an animation: ", -1);
  gtk_text_buffer_create_child_anchor (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, " finally a text entry: ", -1);
  gtk_text_buffer_create_child_anchor (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, ".\n", -1);

  gtk_text_buffer_insert (buffer, &iter,
      "\n\nThis demo doesn't demonstrate all the GtkTextBuffer features; "
      "it leaves out, for example: invisible/hidden text, tab stops, "
      "application-drawn areas on the sides of the widget for displaying "
      "breakpoints and such...", -1);

  /* Apply word_wrap tag to whole buffer */
  gtk_text_buffer_get_bounds (buffer, &start, &end);
  gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);

  g_object_unref (pixbuf);
}
int _camera_storage_image_filename(const dt_camera_t *camera,const char *filename,CameraFile *preview,CameraFile *exif,void *user_data)
{
  _camera_import_dialog_t *data=(_camera_import_dialog_t*)user_data;
  GtkTreeIter iter;
  const char *img;
  unsigned long size;
  GdkPixbuf *pixbuf=NULL;
  GdkPixbuf *thumb=NULL;

  /* stop fetching previews if job is cancelled */
  if (data->preview_job && dt_control_job_get_state(data->preview_job) == DT_JOB_STATE_CANCELLED )
    return 0;


  gboolean i_own_lock = dt_control_gdk_lock();
  char exif_info[1024]= {0};
  char file_info[4096]= {0};

  if( preview )
  {
    gp_file_get_data_and_size(preview, &img, &size);
    if( size > 0 )
    {
      // we got preview image data lets create a pixbuf from image blob
      GError *err=NULL;
      GInputStream *stream;
      if( (stream = g_memory_input_stream_new_from_data(img, size,NULL)) !=NULL)
        pixbuf = gdk_pixbuf_new_from_stream( stream, NULL, &err );
    }

    if(pixbuf)
    {
      // Scale pixbuf to a thumbnail
      double sw=gdk_pixbuf_get_width( pixbuf );
      double scale=75.0/gdk_pixbuf_get_height( pixbuf );
      thumb = gdk_pixbuf_scale_simple( pixbuf, sw*scale,75 , GDK_INTERP_BILINEAR );
    }
  }

#if 0
  // libgphoto only supports fetching exif in jpegs, not raw
  char buffer[1024]= {0};
  if ( exif )
  {
    const char *exif_data;
    char *value=NULL;
    gp_file_get_data_and_size(exif, &exif_data, &size);
    if( size > 0 )
    {
      void *exif=dt_exif_data_new((uint8_t *)exif_data,size);
      if( (value=g_strdup( dt_exif_data_get_value(exif,"Exif.Photo.ExposureTime",buffer,1024) ) ) != NULL);
      snprintf(exif_info, sizeof(exif_info), "exposure: %s\n", value);
    }
    else fprintf(stderr,"No exifdata read\n");
  }
#endif

  // filename\n 1/60 f/2.8 24mm iso 160
  snprintf(file_info, sizeof(file_info), "%s%c%s",filename,strlen(exif_info)?'\n':'\0',strlen(exif_info)?exif_info:"");
  gtk_list_store_append(data->store,&iter);
  gtk_list_store_set(data->store,&iter,0,thumb,1,file_info,-1);
  if(pixbuf) g_object_unref(pixbuf);
  if(thumb) g_object_ref(thumb);

  if (i_own_lock) dt_control_gdk_unlock();

  return 1;
}
Beispiel #9
0
void PictureEntry_Update (Picture *pic, gboolean select_it)
{
    GdkPixbufLoader *loader = 0;
    GError *error = NULL;
    
    g_return_if_fail (pic != NULL || PictureEntryView != NULL);

    if (!pic->data)
    {
        PictureEntry_Clear();
        return;
    }

    loader = gdk_pixbuf_loader_new();
    if (loader)
    {
        if (gdk_pixbuf_loader_write(loader, pic->data, pic->size, &error))
        {
            GtkTreeSelection *selection;
            GdkPixbuf *pixbuf;

            if (!gdk_pixbuf_loader_close(loader, &error))
            {
                Log_Print(LOG_ERROR,_("Error with 'loader_close': %s"), error->message);
                g_error_free(error);
            }

            selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(PictureEntryView));

            pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
            if (pixbuf)
            {
                GtkListStore *picture_store;
                GtkTreeIter iter1;
                GdkPixbuf *scaled_pixbuf;
                gint scaled_pixbuf_width;
                gint scaled_pixbuf_height;
                gchar *pic_info;

                g_object_ref(pixbuf);
                g_object_unref(loader);
                
                // Keep aspect ratio of the picture
                pic->width  = gdk_pixbuf_get_width(pixbuf);
                pic->height = gdk_pixbuf_get_height(pixbuf);
                if (pic->width > pic->height)
                {
                    scaled_pixbuf_width  = 96;
                    scaled_pixbuf_height = 96 * pic->height / pic->width;
                }else
                {
                    scaled_pixbuf_width = 96 * pic->width / pic->height;
                    scaled_pixbuf_height = 96;
                }

                scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
                                    scaled_pixbuf_width, scaled_pixbuf_height,
                                    //GDK_INTERP_NEAREST); // Lower quality but better speed
                                    GDK_INTERP_BILINEAR);
                g_object_unref(pixbuf);

                picture_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(PictureEntryView)));
                pic_info = Picture_Info(pic);
                gtk_list_store_insert_with_values (picture_store, &iter1,
                                                   G_MAXINT,
                                                   PICTURE_COLUMN_PIC,
                                                   scaled_pixbuf,
                                                   PICTURE_COLUMN_TEXT,
                                                   pic_info,
                                                   PICTURE_COLUMN_DATA,
                                                   Picture_Copy_One (pic), -1);
                g_free(pic_info);

                if (select_it)
                    gtk_tree_selection_select_iter(selection, &iter1);
                g_object_unref(scaled_pixbuf);
            }else
            {
                GtkWidget *msgdialog;
                
                g_object_unref(loader);
                
                Log_Print (LOG_ERROR, "%s",
                           _("Cannot display the image because not enough data has been read to determine how to create the image buffer."));

                msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
                                                   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
                                                   "%s",
                                                   _("Cannot display the image"));
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (msgdialog),
                                                          _("Not enough data has been read to determine how to create the image buffer."));
                gtk_window_set_title (GTK_WINDOW (msgdialog),
                                      _("Load Image File"));
                gtk_dialog_run(GTK_DIALOG(msgdialog));
                gtk_widget_destroy(msgdialog);
            }
        }else
        {
            Log_Print(LOG_ERROR,_("Error with 'loader_write': %s"), error->message);
            g_error_free(error);
        }
    }

    // Do also for next picture
    if (pic->next)
        PictureEntry_Update(pic->next, select_it);

    return;
}
Beispiel #10
0
static int
image_constructor(Plugin *p, char **fp)
{
    gchar *tooltip, *fname;
    image *img;
    GdkPixbuf *gp, *gps;
    GtkWidget *wid;
    GError *err = NULL;
    char *config_start, *config_end;

    line s;

    s.len = 256;
    ENTER;
    img = g_new0(image, 1);
    g_return_val_if_fail(img != NULL, 0);
    p->priv = img;
    tooltip = fname = 0;
    if( fp ) {
        config_start = *fp;
        while (lxpanel_get_line(fp, &s) != LINE_BLOCK_END) {
            if (s.type == LINE_NONE) {
                ERR( "image: illegal token %s\n", s.str);
                goto error;
            }
            if (s.type == LINE_VAR) {
                if (!g_ascii_strcasecmp(s.t[0], "image"))
                    fname = expand_tilda(s.t[1]);
                else if (!g_ascii_strcasecmp(s.t[0], "tooltip"))
                    tooltip = g_strdup(s.t[1]);
                else {
                    ERR( "image: unknown var %s\n", s.t[0]);
                    goto error;
                }
            } else {
                ERR( "image: illegal in this context %s\n", s.str);
                goto error;
            }
        }
        config_end = *fp - 1;
        while( *config_end != '}' && config_end > config_start ) {
            --config_end;
        }
        if( *config_end == '}' )
            --config_end;
        img->config_data = g_strndup( config_start,
                                      (config_end-config_start) );
    }
    else {
        config_start = config_end = NULL;
    }
    img->mainw = gtk_event_box_new();
    gtk_widget_show(img->mainw);
    //g_signal_connect(G_OBJECT(img->mainw), "expose_event",
    //      G_CALLBACK(gtk_widget_queue_draw), NULL);
    gp = gdk_pixbuf_new_from_file(fname, &err);
    if (!gp) {
        g_warning("image: can't read image %s\n", fname);
        wid = gtk_label_new("?");
    } else {
        float ratio;
        ratio = (p->panel->orientation == ORIENT_HORIZ) ?
            (float) (p->panel->ah - 2) / (float) gdk_pixbuf_get_height(gp)
            : (float) (p->panel->aw - 2) / (float) gdk_pixbuf_get_width(gp);
        gps =  gdk_pixbuf_scale_simple (gp,
              ratio * ((float) gdk_pixbuf_get_width(gp)),
              ratio * ((float) gdk_pixbuf_get_height(gp)),
              GDK_INTERP_HYPER);
        wid = gtk_image_new_from_pixbuf(gps);
        g_object_unref(gp);
        g_object_unref(gps);

    }
    gtk_widget_show(wid);
    gtk_container_add(GTK_CONTAINER(img->mainw), wid);
    gtk_container_set_border_width(GTK_CONTAINER(img->mainw), 0);
    g_free(fname);

    if (tooltip) {
        gtk_widget_set_tooltip_text(img->mainw, tooltip);
        g_free(tooltip);
    }
    RET(1);

 error:
    g_free(fname);
    g_free(tooltip);
    image_destructor(p);
    RET(0);
}
Beispiel #11
0
G_MODULE_EXPORT gboolean
display_show(NOTIFICATION_INFO* ni) {
  GdkColor color;
  GtkWidget* vbox;
  GtkWidget* hbox;
  GtkWidget* label;
  GtkWidget* image;
  GdkScreen* screen;
  gint n, pos, len;
  gint x, y;
  gint monitor_num;
  GdkRectangle rect;

  DISPLAY_INFO* di = g_new0(DISPLAY_INFO, 1);
  if (!di) {
    perror("g_new0");
    return FALSE;
  }
  di->ni = ni;

  len = g_list_length(notifications);
  for (pos = 0; pos < len; pos++) {
    DISPLAY_INFO* p = g_list_nth_data(notifications, pos);
    if (pos != p->pos) break;
  }

  screen = gdk_screen_get_default();
  monitor_num = gdk_screen_get_primary_monitor(screen);
  gdk_screen_get_monitor_geometry(screen, monitor_num, &rect);

  x = rect.x + rect.width - 250;
  y = rect.y + rect.height - 110;
  for (n = 0; n < pos; n++) {
    y -= 110;
    if (y < 0) {
      x -= 250;
      if (x < 0) {
        return FALSE;
      }
      y = rect.y + rect.height - 110;
    }
  }

  di->pos = pos;
  notifications = g_list_insert_sorted(notifications, di, notifications_compare);
  di->x = x;
  di->y = y;

  di->popup = gtk_window_new(GTK_WINDOW_POPUP);
  gtk_window_set_title(GTK_WINDOW(di->popup), "growl-for-linux");
  gtk_window_set_resizable(GTK_WINDOW(di->popup), FALSE);
  gtk_window_set_decorated(GTK_WINDOW(di->popup), FALSE);
  gtk_window_set_keep_above(GTK_WINDOW(di->popup), TRUE);

  gtk_window_stick(GTK_WINDOW(di->popup));

  vbox = gtk_vbox_new(FALSE, 5);
  gtk_container_set_border_width(GTK_CONTAINER(vbox), 18);
  gtk_container_add(GTK_CONTAINER(di->popup), vbox);

  hbox = gtk_hbox_new(FALSE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);

  if (di->ni->icon && *di->ni->icon) {
    GdkPixbuf* pixbuf;
    if (di->ni->local) {
      gchar* newurl = g_filename_from_uri(di->ni->icon, NULL, NULL);
      GError* error = NULL;
      pixbuf = gdk_pixbuf_new_from_file(newurl ? newurl : di->ni->icon, &error);
      if (newurl) g_free(newurl);
    } else
      pixbuf = url2pixbuf(di->ni->icon, NULL);
    if (pixbuf) {
      GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_TILES);
      if (tmp) {
        g_object_unref(pixbuf);
        pixbuf = tmp;
      }
      image = gtk_image_new_from_pixbuf(pixbuf);
      gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
      g_object_unref(pixbuf);
    }
  }

  PangoFontDescription* font_desc;
  
  font_desc = pango_font_description_new();
  pango_font_description_set_family(font_desc, "Sans");
  pango_font_description_set_size(font_desc, 12 * PANGO_SCALE);

  label = gtk_label_new(di->ni->title);
  gdk_color_parse("white", &color);
  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color);
  gtk_widget_modify_font(label, font_desc);
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  pango_font_description_free(font_desc);

  font_desc = pango_font_description_new();
  pango_font_description_set_family(font_desc, "Sans");
  pango_font_description_set_size(font_desc, 8 * PANGO_SCALE);

  label = gtk_label_new(di->ni->text);
  gdk_color_parse("white", &color);
  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color);
  gtk_widget_modify_font(label, font_desc);
  g_signal_connect(G_OBJECT(label), "size-allocate", G_CALLBACK(label_size_allocate), NULL);
  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
  gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
  gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_CHAR);
  gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0);

  pango_font_description_free(font_desc);

  gtk_widget_set_events(di->popup, GDK_BUTTON_PRESS_MASK);
  g_signal_connect(G_OBJECT(di->popup), "button-press-event", G_CALLBACK(display_clicked), di);

  di->offset = 0;
  di->timeout = 500;

  gtk_window_move(GTK_WINDOW(di->popup), di->x, di->y);
  gtk_window_set_opacity(GTK_WINDOW(di->popup), 0);
  gtk_widget_set_app_paintable(di->popup, TRUE);
  gtk_widget_show_all(di->popup);

  if (pixmap == NULL) {
     pixmap = gdk_pixmap_create_from_xpm_d(di->popup->window, &bitmap, NULL, balloon);
  }
  gdk_drawable_get_size(pixmap, &pixmap_width, &pixmap_height);
  gtk_widget_set_size_request(di->popup, pixmap_width, pixmap_height);
  gdk_window_shape_combine_mask(di->popup->window, bitmap, 0, 0);
  g_signal_connect(G_OBJECT(di->popup), "expose-event", G_CALLBACK(display_expose), di);

  g_timeout_add(10, display_animation_func, di);

  return FALSE;
}
Beispiel #12
0
static gboolean
gdict_applet_draw (GdictApplet *applet)
{
  GdictAppletPrivate *priv = applet->priv;
  GtkWidget *box;
  GtkWidget *hbox;
  gchar *text = NULL;

  if (priv->entry)
    text = gtk_editable_get_chars (GTK_EDITABLE (priv->entry), 0, -1);
  
  if (priv->box)
    gtk_widget_destroy (priv->box);

  switch (priv->orient)
    {
    case GTK_ORIENTATION_VERTICAL:
      box = gtk_vbox_new (FALSE, 0);
      break;
    case GTK_ORIENTATION_HORIZONTAL:
      box = gtk_hbox_new (FALSE, 0);
      break;
    default:
      g_assert_not_reached ();
      break;
    }
  
  gtk_container_add (GTK_CONTAINER (applet), box);
  gtk_widget_show (box);

  /* toggle button */
  priv->toggle = gtk_toggle_button_new ();
  gtk_widget_set_tooltip_text (priv->toggle, _("Click to view the dictionary window"));
  set_atk_name_description (priv->toggle,
			    _("Toggle dictionary window"),
		  	    _("Show or hide the definition window"));
  
  gtk_button_set_relief (GTK_BUTTON (priv->toggle),
		  	 GTK_RELIEF_NONE);
  g_signal_connect (priv->toggle, "toggled",
		    G_CALLBACK (gdict_applet_icon_toggled_cb),
		    applet);
  g_signal_connect (priv->toggle, "button-press-event",
		    G_CALLBACK (gdict_applet_icon_button_press_event_cb),
		    applet);
  gtk_box_pack_start (GTK_BOX (box), priv->toggle, FALSE, FALSE, 0);
  gtk_widget_show (priv->toggle);

  hbox = gtk_hbox_new (FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
  gtk_container_add (GTK_CONTAINER (priv->toggle), hbox);
  gtk_widget_show (hbox);

  if (priv->icon)
    {
      GdkPixbuf *scaled;
      
      priv->image = gtk_image_new ();
      gtk_image_set_pixel_size (GTK_IMAGE (priv->image), priv->size - 10);

      scaled = gdk_pixbuf_scale_simple (priv->icon,
		      			priv->size - 5,
					priv->size - 5,
					GDK_INTERP_BILINEAR);
      
      gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), scaled);
      g_object_unref (scaled);
      
      gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0);
      
      gtk_widget_show (priv->image);
    }
  else
    {
      priv->image = gtk_image_new ();

      gtk_image_set_pixel_size (GTK_IMAGE (priv->image), priv->size - 10);
      gtk_image_set_from_stock (GTK_IMAGE (priv->image),
				GTK_STOCK_MISSING_IMAGE,
				-1);
      
      gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0);
      gtk_widget_show (priv->image);
    }

  /* entry */
  priv->entry = gtk_entry_new ();
  gtk_widget_set_tooltip_text (priv->entry, _("Type the word you want to look up"));
  set_atk_name_description (priv->entry,
		  	    _("Dictionary entry"),
			    _("Look up words in dictionaries"));
  
  gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
  gtk_entry_set_width_chars (GTK_ENTRY (priv->entry), 12);
  g_signal_connect (priv->entry, "activate",
  		    G_CALLBACK (gdict_applet_entry_activate_cb),
  		    applet);
  g_signal_connect (priv->entry, "button-press-event",
		    G_CALLBACK (gdict_applet_entry_button_press_event_cb),
		    applet);
  g_signal_connect (priv->entry, "key-press-event",
		    G_CALLBACK (gdict_applet_entry_key_press_cb),
		    applet);
  gtk_box_pack_end (GTK_BOX (box), priv->entry, FALSE, FALSE, 0);
  gtk_widget_show (priv->entry);

  if (text)
    {
      gtk_entry_set_text (GTK_ENTRY (priv->entry), text);

      g_free (text);
    }
  
  priv->box = box;

#if 0
  gtk_widget_grab_focus (priv->entry);
#endif
  
  gtk_widget_show_all (GTK_WIDGET (applet));

  return FALSE;
}
Beispiel #13
0
// TODO: use orientation to correctly rotate the image.
// maybe this should be (partly) in common/imageio.[c|h]?
static void _lib_import_update_preview(GtkFileChooser *file_chooser, gpointer data)
{
  GtkWidget *preview;
  char *filename;
  GdkPixbuf *pixbuf = NULL;
  gboolean have_preview = FALSE;

  preview = GTK_WIDGET(data);
  filename = gtk_file_chooser_get_preview_filename(file_chooser);

  if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) goto no_preview_fallback;
  // don't create dng thumbnails to avoid crashes in libtiff when these are hdr:
  char *c = filename + strlen(filename);
  while(c > filename && *c != '.') c--;
  if(!strcasecmp(c, ".dng")) goto no_preview_fallback;

  pixbuf = gdk_pixbuf_new_from_file_at_size(filename, 128, 128, NULL);
  have_preview = (pixbuf != NULL);
  if(!have_preview)
  {
    // raw image thumbnail
    int ret;
    libraw_data_t *raw = libraw_init(0);
    libraw_processed_image_t *image = NULL;
    ret = libraw_open_file(raw, filename);
    if(ret) goto libraw_fail;
    ret = libraw_unpack_thumb(raw);
    if(ret) goto libraw_fail;
    ret = libraw_adjust_sizes_info_only(raw);
    if(ret) goto libraw_fail;

    image = libraw_dcraw_make_mem_thumb(raw, &ret);
    if(!image || ret) goto libraw_fail;
//     const int orientation = raw->sizes.flip;

    GdkPixbuf *tmp;
    GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
    have_preview = gdk_pixbuf_loader_write(loader, image->data, image->data_size, NULL);
    tmp = gdk_pixbuf_loader_get_pixbuf(loader);
    gdk_pixbuf_loader_close(loader, NULL);
    float ratio;
    if(image->type == LIBRAW_IMAGE_JPEG)
    {
      // jpeg
      dt_imageio_jpeg_t jpg;
      if(dt_imageio_jpeg_decompress_header(image->data, image->data_size, &jpg)) goto libraw_fail;
      ratio = 1.0*jpg.height/jpg.width;
    }
    else
    {
      // bmp -- totally untested
      ratio = 1.0*image->height/image->width;
    }
    int width = 128, height = 128*ratio;
    pixbuf = gdk_pixbuf_scale_simple(tmp, width, height, GDK_INTERP_BILINEAR);

    if(loader)
      g_object_unref(loader);

    // clean up raw stuff.
    libraw_recycle(raw);
    libraw_close(raw);
    free(image);
    if(0)
    {
libraw_fail:
      // fprintf(stderr,"[imageio] %s: %s\n", filename, libraw_strerror(ret));
      libraw_close(raw);
      have_preview = FALSE;
    }
  }
  if(!have_preview)
  {
no_preview_fallback:
    pixbuf = gdk_pixbuf_new_from_inline(-1, dt_logo_128x128, FALSE, NULL);
    have_preview = TRUE;
  }
  if(have_preview)
    gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf);
  if(pixbuf)
    g_object_unref(pixbuf);
  g_free(filename);

  gtk_file_chooser_set_preview_widget_active(file_chooser, have_preview);
}
static int renderer_overlay_wallpaper( GdkPixbuf *background,
                                       const char *wallpaper,
                                       MMB_Screen *screen,
                                       int clip )
{
    GError *error = NULL;
    GdkPixbuf *image = gdk_pixbuf_new_from_file( wallpaper, &error );

    if ( error != NULL ) {
        fprintf( stderr, "Failed to parse image: %s\n" , error->message );
        return 0;
    }

    double wp_width  = gdk_pixbuf_get_width( image );
    double wp_height = gdk_pixbuf_get_height( image );

    for ( int monitor = 0; monitor < screen->num_monitors; monitor++ ) {

        MMB_Rectangle rectangle = screen->monitors[monitor];
        double w_scale = wp_width/( double )( rectangle.w );
        double h_scale = wp_height/( double )( rectangle.h );

        // Picture is small then screen, center it.
        if ( w_scale < 1 && h_scale < 1 ) {
            gdk_pixbuf_copy_area( image, 0,0,
                                  wp_width, wp_height,
                                  background,
                                  rectangle.x + ( rectangle.w-wp_width )/2,
                                  rectangle.y + ( rectangle.h-wp_height )/2
                                );
        }
        // Picture is smaller on one of the sides and we want to clip.
        else if ( clip && ( w_scale < 1 || h_scale < 1 ) ) {
            double x_off = ( ( float )rectangle.w-wp_width )/2.0;
            double y_off = ( ( float )rectangle.h-wp_height )/2.0;
            gdk_pixbuf_copy_area( image,
                                  -( x_off < 0 )*x_off,-( y_off < 0 )*y_off,
                                  wp_width+( x_off < 0 )*2*x_off,
                                  wp_height+( y_off < 0 )*2*y_off,
                                  background,
                                  rectangle.x + ( ( x_off> 0 )?x_off:0 ),
                                  rectangle.y + ( ( y_off> 0 )?y_off:0 ) );

        }
        // Picture is bigger/equal then screen.
        // Scale to fit.
        else {
            int new_w= 0;
            int new_h = 0;
            double x_off = 0;
            double y_off = 0;

            if ( clip ) {
                if ( w_scale < h_scale ) {
                    new_w = wp_width/w_scale;
                    new_h = wp_height/w_scale;
                } else {
                    new_w = wp_width/h_scale;
                    new_h = wp_height/h_scale;
                }

                x_off = ( ( new_w-rectangle.w )/2.0 );
                y_off = ( ( new_h-rectangle.h )/2.0 );
            } else {
                if ( w_scale > h_scale ) {
                    new_w = wp_width/w_scale;
                    new_h = wp_height/w_scale;
                } else {
                    new_w = wp_width/h_scale;
                    new_h = wp_height/h_scale;
                }
            }

            GdkPixbuf *scaled_wp = gdk_pixbuf_scale_simple( image, new_w, new_h, GDK_INTERP_HYPER );
            gdk_pixbuf_copy_area(
                scaled_wp,
                ( int )ceil( x_off ),( int )ceil( y_off ),
                new_w-ceil(x_off)*2,
                new_h-ceil(y_off)*2,
                background,
                rectangle.x + ( ( double )rectangle.w-new_w+x_off*2 )/2,
                rectangle.y + ( ( double )rectangle.h-new_h+y_off*2 )/2 );

            g_object_unref( scaled_wp );
        }
    }

    g_object_unref( image );
    return 1;
}
Beispiel #15
0
static void
_lib_filmstrip_dnd_begin_callback(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
  const int ts = 64;

  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data;

  int imgid = strip->mouse_over_id;

  // imgid part of selection -> do nothing
  // otherwise               -> select the current image
  strip->select = DT_LIB_FILMSTRIP_SELECT_NONE;
  sqlite3_stmt *stmt;
  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images where imgid=?1", -1, &stmt, NULL);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);
  if(sqlite3_step(stmt) != SQLITE_ROW)
  {
    dt_selection_select_single(darktable.selection, imgid);
    /* redraw filmstrip */
    if(darktable.view_manager->proxy.filmstrip.module)
      gtk_widget_queue_draw(darktable.view_manager->proxy.filmstrip.module->widget);
  }
  sqlite3_finalize(stmt);

  // if we are dragging a single image -> use the thumbnail of that image
  // otherwise use the generic d&d icon
  // TODO: have something pretty in the 2nd case, too.
  if(dt_collection_get_selected_count(NULL) == 1)
  {
    dt_mipmap_buffer_t buf;
    dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size(darktable.mipmap_cache, ts, ts);
    dt_mipmap_cache_read_get(darktable.mipmap_cache, &buf, imgid, mip, DT_MIPMAP_BLOCKING);

    if(buf.buf)
    {
      uint8_t *scratchmem = dt_mipmap_cache_alloc_scratchmem(darktable.mipmap_cache);
      uint8_t *buf_decompressed = dt_mipmap_cache_decompress(&buf, scratchmem);

      uint8_t *rgbbuf = g_malloc((buf.width+2)*(buf.height+2)*3);
      memset(rgbbuf, 64, (buf.width+2)*(buf.height+2)*3);
      for(int i=1; i<=buf.height; i++)
        for(int j=1; j<=buf.width; j++)
          for(int k=0; k<3; k++)
            rgbbuf[(i*(buf.width+2)+j)*3+k] = buf_decompressed[((i-1)*buf.width+j-1)*4+2-k];

      int w=ts, h=ts;
      if(buf.width < buf.height) w = (buf.width*ts)/buf.height; // portrait
      else                       h = (buf.height*ts)/buf.width; // landscape

      GdkPixbuf *source = gdk_pixbuf_new_from_data(rgbbuf, GDK_COLORSPACE_RGB, FALSE, 8, (buf.width+2), (buf.height+2), (buf.width+2)*3, NULL, NULL);
      GdkPixbuf *scaled = gdk_pixbuf_scale_simple(source, w, h, GDK_INTERP_HYPER);
      gtk_drag_set_icon_pixbuf(context, scaled, 0, 0);

      if(source)
        g_object_unref(source);
      if(scaled)
        g_object_unref(scaled);
      g_free(rgbbuf);
    }

    dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf);
  }
}
static gboolean
update_icon_idle (ButtonData *button_data)
{
        int width, height;
        GdkPixbuf *icon;
        GdkPixbuf *scaled;
        int        icon_size;
        GError    *error;
        int        xrequest, yrequest;
        GtkRequisition empty_button_request;

        /* FIXME this function could do a lot more short-circuiting and maybe
         * save some effort
         */
        g_debug("Updating icon, allocated size=%d", button_data->size);
        
        if (!button_data->icon_theme)
                goto done;

        gtk_image_clear (GTK_IMAGE (button_data->image));
        
        gtk_widget_set_size_request (button_data->image, 10, 10); /* we undo this later, it's just in case the button special-cases 0x0 contents */
        gtk_widget_size_request (GTK_WIDGET(button_data->button), &empty_button_request);
        empty_button_request.width -= 10;
        empty_button_request.height -= 10;
        
        icon_size = 0;
        xrequest = -1;
        yrequest = -1;
        switch (button_data->orient) {
        case GTK_ORIENTATION_HORIZONTAL:
                xrequest = button_data->size - empty_button_request.width;
                if (xrequest < 0)
                        xrequest = 0;
                yrequest = 12;
                icon_size = xrequest;
                break;
        case GTK_ORIENTATION_VERTICAL:
                xrequest = 12;
                yrequest = button_data->size - empty_button_request.height;
                if (yrequest < 0)
                        yrequest = 0;
                icon_size = yrequest;
                break;
        }

        /* clamp icon size to a max of 60 which is the native server-side size
         */
        if (icon_size < 22)
                icon_size = 16;
        else if (icon_size < 32)
                icon_size = 22;
        else if (icon_size < 48)
                icon_size = 32;
        else if (icon_size < 60)
                icon_size = 48;
        else
                icon_size = 60;

        g_debug("Settled on icon size %d, and image widget request %dx%d, based on empty button request %dx%d",
                icon_size, xrequest, yrequest, empty_button_request.width, empty_button_request.height);
        
        if (button_data->user_photo) {
                icon = button_data->user_photo;
                g_object_ref(icon);
        } else {
                error = NULL;
                icon = gtk_icon_theme_load_icon (button_data->icon_theme,
                                                 ICON_NAME,
                                                 icon_size, 0, &error);
        }

        if (icon == NULL) {
                g_printerr (_("Failed to load %s: %s\n"), ICON_NAME,
                            error ? error->message : _("Icon not found"));
                if (error) {
                        g_error_free (error);
                        error = NULL;
                }

                icon = gdk_pixbuf_new_from_file (DATADIR "/pixmaps/nobody.png", NULL);
                if (icon == NULL) {
                        gtk_image_set_from_stock (GTK_IMAGE (button_data->image),
                                                  GTK_STOCK_MISSING_IMAGE,
                                                  GTK_ICON_SIZE_SMALL_TOOLBAR);
                        goto done;
                }
        }

        width = gdk_pixbuf_get_width (icon);
        height = gdk_pixbuf_get_height (icon);

        scaled = NULL;

        /* Make it fit on the given panel */
        switch (button_data->orient) {
        case GTK_ORIENTATION_HORIZONTAL:
                width = (icon_size * width) / (double) height;
                height = icon_size;
                break;
        case GTK_ORIENTATION_VERTICAL:
                height = (icon_size * height) / (double) width;
                width = icon_size;
                break;
        }

        scaled = gdk_pixbuf_scale_simple (icon,
                                          width, height,
                                          GDK_INTERP_BILINEAR);

        if (scaled != NULL) {
                gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image),
                                           scaled);
                g_object_unref (scaled);
        } else {
                gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image),
                                           icon);
        }

        /* don't put much size request on the image, since we are scaling
         * to the allocation, if we didn't do this we could a) never be resized
         * smaller and b) get infinite request/alloc loops
         */
        gtk_widget_set_size_request(button_data->image, xrequest, yrequest);

        g_object_unref (icon);

#ifdef GUI_LOG
        {
                GtkRequisition with_image_request;
                gtk_widget_size_request(button_data->button, &with_image_request);
                g_debug("Entire button will request %dx%d", with_image_request.width, with_image_request.height);
        }
#endif
        
done:
        button_data->update_icon_idle = 0;
        return FALSE;
}
static int _camera_storage_image_filename(const dt_camera_t *camera, const char *filename,
                                          CameraFile *preview, CameraFile *exif, void *user_data)
{
  _camera_import_dialog_t *data = (_camera_import_dialog_t *)user_data;
  const char *img;
  unsigned long size;
  GdkPixbuf *pixbuf = NULL;
  GdkPixbuf *thumb = NULL;

  /* stop fetching previews if job is cancelled */
  if(data->preview_job && dt_control_job_get_state(data->preview_job) == DT_JOB_STATE_CANCELLED) return 0;

  char exif_info[1024] = { 0 };

  if(preview)
  {
    gp_file_get_data_and_size(preview, &img, &size);
    if(size > 0)
    {
      // we got preview image data lets create a pixbuf from image blob
      GError *err = NULL;
      GInputStream *stream;
      if((stream = g_memory_input_stream_new_from_data(img, size, NULL)) != NULL)
        pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, &err);
    }

    if(pixbuf)
    {
      // Scale pixbuf to a thumbnail
      double sw = gdk_pixbuf_get_width(pixbuf);
      double scale = 75.0 / gdk_pixbuf_get_height(pixbuf);
      thumb = gdk_pixbuf_scale_simple(pixbuf, sw * scale, 75, GDK_INTERP_BILINEAR);
    }
  }

#if 0
  // libgphoto only supports fetching exif in jpegs, not raw
  char buffer[1024]= {0};
  if ( exif )
  {
    const char *exif_data;
    char *value=NULL;
    gp_file_get_data_and_size(exif, &exif_data, &size);
    if( size > 0 )
    {
      void *exif=dt_exif_data_new((uint8_t *)exif_data,size);
      if( (value=g_strdup( dt_exif_data_get_value(exif,"Exif.Photo.ExposureTime",buffer,1024) ) ) != NULL);
      snprintf(exif_info, sizeof(exif_info), "exposure: %s\n", value);
    }
    else fprintf(stderr,"No exifdata read\n");
  }
#endif

  _image_filename_t *params = (_image_filename_t *)malloc(sizeof(_image_filename_t));
  if(!params)
  {
    if(pixbuf) g_object_unref(pixbuf);
    if(thumb) g_object_unref(thumb);
    return 0;
  }

  // filename\n 1/60 f/2.8 24mm iso 160
  params->file_info = g_strdup_printf("%s%c%s", filename, *exif_info ? '\n' : '\0',
                                      *exif_info ? exif_info : "");
  params->thumb = thumb;
  params->store = data->store;
  g_main_context_invoke(NULL, _camera_storage_image_filename_gui_thread, params);

  if(pixbuf) g_object_unref(pixbuf);

  return 1;
}
Beispiel #18
0
gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
{
/*     g_message("Exposed!!!   %s", GTK_WIDGET_HAS_FOCUS(widget) ? "XXX" : "---" ); */
    gint insetX = 0;
    gint insetY = 0;

    (void)event;
/*
    gint lower = widget->allocation.width;
    lower = (widget->allocation.height < lower) ? widget->allocation.height : lower;
    if ( lower > 16 ) {
        insetX++;
        if ( lower > 18 ) {
            insetX++;
            if ( lower > 22 ) {
                insetX++;
                if ( lower > 24 ) {
                    insetX++;
                    if ( lower > 32 ) {
                        insetX++;
                    }
                }
            }
        }
        insetY = insetX;
    }
*/

    if ( GTK_WIDGET_DRAWABLE( widget ) ) {
        GtkStyle* style = gtk_widget_get_style( widget );

        if ( insetX > 0 || insetY > 0 ) {
            gtk_paint_flat_box( style,
                                widget->window,
                                (GtkStateType)GTK_WIDGET_STATE(widget),
                                GTK_SHADOW_NONE,
                                NULL,
                                widget,
                                NULL,
                                0, 0,
                                widget->allocation.width, widget->allocation.height);
        }

        GdkGC *gc = gdk_gc_new( widget->window );
        EekPreview* preview = EEK_PREVIEW(widget);
        GdkColor fg = {0, static_cast<guint16>(preview->_r), static_cast<guint16>(preview->_g), static_cast<guint16>(preview->_b)};

        gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE );

        gdk_gc_set_foreground( gc, &fg );

        gdk_draw_rectangle( widget->window,
                            gc,
                            TRUE,
                            insetX, insetY,
                            widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) );

        if ( preview->_previewPixbuf ) {
            GtkDrawingArea* da = &(preview->drawing);
            GdkDrawable* drawable = (GdkDrawable*) (((GtkWidget*)da)->window);
            gint w = 0;
            gint h = 0;
            gdk_drawable_get_size(drawable, &w, &h);
            if ((w != preview->_scaledW) || (h != preview->_scaledH)) {
                if (preview->_scaled) {
                    g_object_unref(preview->_scaled);
                }
                preview->_scaled = gdk_pixbuf_scale_simple(preview->_previewPixbuf, w, h, GDK_INTERP_BILINEAR);
                preview->_scaledW = w;
                preview->_scaledH = h;
            }

            GdkPixbuf* pix = (preview->_scaled) ? preview->_scaled : preview->_previewPixbuf;
            gdk_draw_pixbuf( drawable, 0, pix, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0 );
        }


        if ( preview->_linked ) {
            /* Draw arrow */
            GdkRectangle possible = {insetX, insetY, (widget->allocation.width - (insetX * 2)), (widget->allocation.height - (insetY * 2)) };
            GdkRectangle area = {possible.x, possible.y, possible.width / 2, possible.height / 2 };

            /* Make it square */
            if ( area.width > area.height )
                area.width = area.height;
            if ( area.height > area.width )
                area.height = area.width;

            /* Center it horizontally */
            if ( area.width < possible.width ) {
                int diff = (possible.width - area.width) / 2;
                area.x += diff;
            }


            if ( preview->_linked & PREVIEW_LINK_IN ) {
                gtk_paint_arrow( style,
                                 widget->window,
                                 (GtkStateType)widget->state,
                                 GTK_SHADOW_ETCHED_IN,
                                 NULL, /* clip area.  &area, */
                                 widget, /* may be NULL */
                                 NULL, /* detail */
                                 GTK_ARROW_DOWN,
                                 FALSE,
                                 area.x, area.y,
                                 area.width, area.height
                                 );
            }

            if ( preview->_linked & PREVIEW_LINK_OUT ) {
                GdkRectangle otherArea = {area.x, area.y, area.width, area.height};
                if ( otherArea.height < possible.height ) {
                    otherArea.y = possible.y + (possible.height - otherArea.height);
                }

                gtk_paint_arrow( style,
                                 widget->window,
                                 (GtkStateType)widget->state,
                                 GTK_SHADOW_ETCHED_OUT,
                                 NULL, /* clip area.  &area, */
                                 widget, /* may be NULL */
                                 NULL, /* detail */
                                 GTK_ARROW_DOWN,
                                 FALSE,
                                 otherArea.x, otherArea.y,
                                 otherArea.width, otherArea.height
                                 );
            }

            if ( preview->_linked & PREVIEW_LINK_OTHER ) {
                GdkRectangle otherArea = {insetX, area.y, area.width, area.height};
                if ( otherArea.height < possible.height ) {
                    otherArea.y = possible.y + (possible.height - otherArea.height) / 2;
                }

                gtk_paint_arrow( style,
                                 widget->window,
                                 (GtkStateType)widget->state,
                                 GTK_SHADOW_ETCHED_OUT,
                                 NULL, /* clip area.  &area, */
                                 widget, /* may be NULL */
                                 NULL, /* detail */
                                 GTK_ARROW_LEFT,
                                 FALSE,
                                 otherArea.x, otherArea.y,
                                 otherArea.width, otherArea.height
                                 );
            }


            if ( preview->_linked & PREVIEW_FILL ) {
                GdkRectangle otherArea = {possible.x + ((possible.width / 4) - (area.width / 2)),
                                          area.y,
                                          area.width, area.height};
                if ( otherArea.height < possible.height ) {
                    otherArea.y = possible.y + (possible.height - otherArea.height) / 2;
                }
                gtk_paint_check( style,
                                 widget->window,
                                 (GtkStateType)widget->state,
                                 GTK_SHADOW_ETCHED_OUT,
                                 NULL,
                                 widget,
                                 NULL,
                                 otherArea.x, otherArea.y,
                                 otherArea.width, otherArea.height );
            }

            if ( preview->_linked & PREVIEW_STROKE ) {
                GdkRectangle otherArea = {possible.x + (((possible.width * 3) / 4) - (area.width / 2)),
                                          area.y,
                                          area.width, area.height};
                if ( otherArea.height < possible.height ) {
                    otherArea.y = possible.y + (possible.height - otherArea.height) / 2;
                }
                gtk_paint_diamond( style,
                                   widget->window,
                                   (GtkStateType)widget->state,
                                   GTK_SHADOW_ETCHED_OUT,
                                   NULL,
                                   widget,
                                   NULL,
                                   otherArea.x, otherArea.y,
                                   otherArea.width, otherArea.height );
            }
        }


        if ( GTK_WIDGET_HAS_FOCUS(widget) ) {
            gtk_paint_focus( style,
                             widget->window,
                             GTK_STATE_NORMAL,
                             NULL, /* GdkRectangle *area, */
                             widget,
                             NULL,
                             0 + 1, 0 + 1,
                             widget->allocation.width - 2, widget->allocation.height - 2 );
        }
    }


    return FALSE;
}
Beispiel #19
0
static void
colorful_tabs_view_notify_uri_cb (MidoriView*      view,
                                  GParamSpec*      pspec,
                                  MidoriExtension* extension)
{
    GtkWidget* box;
    GtkWidget* label;
    SoupURI* uri;
    gchar* colorstr;
    GdkColor color;
    GdkColor fgcolor;
    GdkPixbuf* icon;

    label = midori_view_get_proxy_tab_label (view);

    if ((uri = soup_uri_new (midori_view_get_display_uri (view)))
      && uri->host && (katze_object_get_enum (view, "load-status") == MIDORI_LOAD_FINISHED))
    {
        icon = midori_view_get_icon (view);

        if (midori_view_get_icon_uri (view) != NULL)
        {
            GdkPixbuf* newpix;
            guchar* pixels;

            newpix = gdk_pixbuf_scale_simple (icon, 1, 1, GDK_INTERP_BILINEAR);
            g_return_if_fail (gdk_pixbuf_get_bits_per_sample (newpix) == 8);
            pixels = gdk_pixbuf_get_pixels (newpix);
            color.red = pixels[0] * 225;
            color.green = pixels[1] * 225;
            color.blue = pixels[2] * 225;
        }
        else
        {
            gchar* hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri->host, 1);
            colorstr = g_strndup (hash, 6 + 1);
            g_free (hash);
            colorstr[0] = '#';
            gdk_color_parse (colorstr, &color);
        }
        soup_uri_free (uri);

        if ((color.red   < 35000)
         && (color.green < 35000)
         && (color.blue  < 35000))
        {
            color.red   += 20000;
            color.green += 20000;
            color.blue  += 20000;
        }

        /* Ensure high contrast by enforcing black/ white text colour. */
        if ((color.red   < 41000)
         && (color.green < 41000)
         && (color.blue  < 41000))
            gdk_color_parse ("#fff", &fgcolor);
        else
            gdk_color_parse ("#000", &fgcolor);

        box = gtk_bin_get_child (GTK_BIN (label));

        gtk_event_box_set_visible_window (GTK_EVENT_BOX (label), TRUE);

        gtk_container_foreach (GTK_CONTAINER (box),
                               (GtkCallback) colorful_tabs_modify_fg,
                               &fgcolor);

        gtk_widget_modify_bg (label, GTK_STATE_NORMAL, &color);

        if (color.red < 10000)
            color.red = 5000;
        else
            color.red -= 5000;
        if (color.blue < 10000)
            color.blue = 5000;
        else
            color.blue -= 5000;
        if (color.green < 10000)
            color.green = 5000;
        else
            color.green -= 5000;

        gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, &color);
    }
    else
    {
        gtk_widget_modify_bg (label, GTK_STATE_NORMAL, NULL);
        gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, NULL);
        gtk_container_foreach (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (label))),
                               (GtkCallback) colorful_tabs_modify_fg,
                               NULL);
    }
}
static void
button_clicked(GtkWidget * button,  ScreenshotData * sd)
{
    GdkPixbuf * screenshot;
    GdkPixbuf * thumbnail;
    GdkWindow * window;
    GdkNativeWindow nwindow;
    gint delay;

    gint width;
    gint height;

    gchar * filename = NULL;
    gchar * basename = NULL;
    gchar * curdir = NULL;

    
    if (sd->whole_screen) {
        window = gdk_get_default_root_window();
    } else {
        if (delay = sd->window_delay) {
            g_timeout_add(1000, delay_callback, &delay);
            gtk_main();
        }
        nwindow = select_window(gdk_screen_get_default());
        if (nwindow) {
            window = gdk_window_foreign_new(nwindow);
        } else {
            window = gdk_get_default_root_window();
        }
    }

    gdk_drawable_get_size(window, &width, &height);
    
    if (delay = sd->screenshot_delay) {
        g_timeout_add(1000, delay_callback, &delay);
        gtk_main();
    }
    
    screenshot = gdk_pixbuf_get_from_drawable (NULL,
					       window,
					       NULL, 0, 0, 0, 0,
					       width, height);
    
    thumbnail = gdk_pixbuf_scale_simple (screenshot,
				         width/5,
				         height/5, GDK_INTERP_BILINEAR);
    
    gtk_image_set_from_pixbuf (GTK_IMAGE (sd->preview), thumbnail);
    g_object_unref (thumbnail);
            filename = generate_filename_for_uri (xfce_file_chooser_get_current_folder(XFCE_FILE_CHOOSER (sd->chooser)));
    
    if (sd->ask_for_file && filename)
    {    
        gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (sd->chooser), filename);
        if (gtk_dialog_run (GTK_DIALOG (sd->chooser)) == GTK_RESPONSE_ACCEPT)
        {    
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(sd->chooser));
        }
        gtk_widget_hide (GTK_WIDGET (sd->chooser));
    }
    else
    {
       /* sd->counter++;
        basename = g_strdup_printf ("Screenshot-%d.png", sd->counter);
       filename = g_build_filename (sd->screenshots_dir, basename, NULL);
        curdir = g_get_current_dir();
        filename = g_build_filename (curdir, basename, NULL);
        g_free(basename);
        */
    }
    
    if (filename) {
        gdk_pixbuf_save (screenshot, filename, "png", NULL, NULL);
        g_free (filename);
    }
}
GdkPixbuf *
panel_make_menu_icon (GtkIconTheme *icon_theme,
                      const char   *icon,
                      const char   *fallback,
                      int           size,
                      gboolean     *long_operation)
{
    GdkPixbuf *pb;
    char *file, *key;
    gboolean loaded;

    g_return_val_if_fail (size > 0, NULL);

    file = NULL;
    if (icon != NULL)
        file = panel_find_icon (icon_theme, icon, size);
    if (file == NULL && fallback != NULL)
        file = panel_find_icon (icon_theme, fallback, size);

    if (file == NULL)
        return NULL;

    if (long_operation != NULL)
        *long_operation = TRUE;

    pb = NULL;

    loaded = FALSE;

    key = g_strdup_printf ("%d:%s", size, file);

    if (loaded_icons != NULL &&
            (pb = g_hash_table_lookup (loaded_icons, key)) != NULL) {
        if (pb != NULL)
            g_object_ref (G_OBJECT (pb));
    }

    if (pb == NULL) {
        pb = gdk_pixbuf_new_from_file (file, NULL);
        if (pb) {
            gint width, height;

            width = gdk_pixbuf_get_width (pb);
            height = gdk_pixbuf_get_height (pb);

            /* if we want 24 and we get 22, do nothing;
             * else scale */
            if (!(size - 2 <= width && width <= size &&
                    size - 2 <= height && height <= size)) {
                GdkPixbuf *tmp;

                tmp = gdk_pixbuf_scale_simple (pb, size, size,
                                               GDK_INTERP_BILINEAR);

                g_object_unref (pb);
                pb = tmp;
            }
        }

        /* add icon to the hash table so we don't load it again */
        loaded = TRUE;
    }

    if (pb == NULL) {
        g_free (file);
        g_free (key);
        return NULL;
    }

    if (loaded &&
            (gdk_pixbuf_get_width (pb) != size &&
             gdk_pixbuf_get_height (pb) != size)) {
        GdkPixbuf *pb2;
        int        dest_width;
        int        dest_height;
        int        width;
        int        height;

        width  = gdk_pixbuf_get_width (pb);
        height = gdk_pixbuf_get_height (pb);

        if (height > width) {
            dest_width  = (size * width) / height;
            dest_height = size;
        } else {
            dest_width  = size;
            dest_height = (size * height) / width;
        }

        pb2 = gdk_pixbuf_scale_simple (pb, dest_width, dest_height,
                                       GDK_INTERP_BILINEAR);
        g_object_unref (G_OBJECT (pb));
        pb = pb2;
    }

    if (loaded) {
        if (loaded_icons == NULL)
            loaded_icons = g_hash_table_new_full
                           (g_str_hash, g_str_equal,
                            (GDestroyNotify) g_free,
                            (GDestroyNotify) g_object_unref);
        g_hash_table_replace (loaded_icons,
                              g_strdup (key),
                              g_object_ref (G_OBJECT (pb)));
        g_object_weak_ref (G_OBJECT (pb),
                           (GWeakNotify) remove_pixmap_from_loaded,
                           g_strdup (key));
    } else {
        /* we didn't load from disk */
        if (long_operation != NULL)
            *long_operation = FALSE;
    }

    g_free (file);
    g_free (key);

    return pb;
}
Beispiel #22
0
static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_format format, int width, int height )
{
	// Obtain properties of frame and producer
	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
	mlt_producer producer = &self->parent;

	// Get index and pixbuf
	int current_idx = refresh_pixbuf( self, frame );

	// optimization for subsequent iterations on single picture
	if ( current_idx != self->image_idx || width != self->width || height != self->height )
		self->image = NULL;
	mlt_log_debug( MLT_PRODUCER_SERVICE( producer ), "image %p pixbuf %p idx %d current_idx %d pixbuf_idx %d width %d\n",
		self->image, self->pixbuf, current_idx, self->image_idx, self->pixbuf_idx, width );

	// If we have a pixbuf and we need an image
	if ( self->pixbuf && ( !self->image || ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) ) )
	{
		char *interps = mlt_properties_get( properties, "rescale.interp" );
		if ( interps ) interps = strdup( interps );
		int interp = GDK_INTERP_BILINEAR;

		if ( !interps ) {
			// Keep bilinear by default
		}
		else if ( strcmp( interps, "nearest" ) == 0 )
			interp = GDK_INTERP_NEAREST;
		else if ( strcmp( interps, "tiles" ) == 0 )
			interp = GDK_INTERP_TILES;
		else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "bicubic" ) == 0 )
			interp = GDK_INTERP_HYPER;
		free( interps );

		// Note - the original pixbuf is already safe and ready for destruction
		pthread_mutex_lock( &g_mutex );
		GdkPixbuf* pixbuf = gdk_pixbuf_scale_simple( self->pixbuf, width, height, interp );

		// Store width and height
		self->width = width;
		self->height = height;

		// Allocate/define image
		int has_alpha = gdk_pixbuf_get_has_alpha( pixbuf );
		int src_stride = gdk_pixbuf_get_rowstride( pixbuf );
		int dst_stride = self->width * ( has_alpha ? 4 : 3 );
		int image_size = dst_stride * ( height + 1 );
		self->image = mlt_pool_alloc( image_size );
		self->alpha = NULL;
		self->format = has_alpha ? mlt_image_rgb24a : mlt_image_rgb24;

		if ( src_stride != dst_stride )
		{
			int y = self->height;
			uint8_t *src = gdk_pixbuf_get_pixels( pixbuf );
			uint8_t *dst = self->image;
			while ( y-- )
			{
				memcpy( dst, src, dst_stride );
				dst += dst_stride;
				src += src_stride;
			}
		}
		else
		{
			memcpy( self->image, gdk_pixbuf_get_pixels( pixbuf ), src_stride * height );
		}
		pthread_mutex_unlock( &g_mutex );

		// Convert image to requested format
		if ( format != mlt_image_none && format != mlt_image_glsl && format != self->format )
		{
			uint8_t *buffer = NULL;

			// First, set the image so it can be converted when we get it
			mlt_frame_replace_image( frame, self->image, self->format, width, height );
			mlt_frame_set_image( frame, self->image, image_size, mlt_pool_release );
			self->format = format;

			// get_image will do the format conversion
			mlt_frame_get_image( frame, &buffer, &format, &width, &height, 0 );

			// cache copies of the image and alpha buffers
			if ( buffer )
			{
				image_size = mlt_image_format_size( format, width, height, NULL );
				self->image = mlt_pool_alloc( image_size );
				memcpy( self->image, buffer, image_size );
			}
			if ( ( buffer = mlt_frame_get_alpha_mask( frame ) ) )
			{
				self->alpha = mlt_pool_alloc( width * height );
				memcpy( self->alpha, buffer, width * height );
			}
		}

		// Update the cache
		mlt_cache_item_close( self->image_cache );
		mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", self->image, image_size, mlt_pool_release );
		self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
		self->image_idx = current_idx;
		mlt_cache_item_close( self->alpha_cache );
		self->alpha_cache = NULL;
		if ( self->alpha )
		{
			mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha", self->alpha, width * height, mlt_pool_release );
			self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" );
		}

		// Finished with pixbuf now
		g_object_unref( pixbuf );
	}

	// Set width/height of frame
	mlt_properties_set_int( properties, "width", self->width );
	mlt_properties_set_int( properties, "height", self->height );
}