static void
gs_screenshot_image_complete_cb (SoupSession *session,
				 SoupMessage *msg,
				 gpointer user_data)
{
	g_autoptr(GsScreenshotImage) ssimg = GS_SCREENSHOT_IMAGE (user_data);
	gboolean ret;
	g_autoptr(GError) error = NULL;
	g_autoptr(GdkPixbuf) pixbuf = NULL;
	g_autoptr(GInputStream) stream = NULL;

	/* return immediately if the message was cancelled or if we're in destruction */
	if (msg->status_code == SOUP_STATUS_CANCELLED || ssimg->session == NULL)
		return;

	if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) {
		g_debug ("screenshot has not been modified");
		as_screenshot_show_image (ssimg);
		return;
	}
	if (msg->status_code != SOUP_STATUS_OK) {
                g_warning ("Result of screenshot downloading attempt with "
			   "status code '%u': %s", msg->status_code,
			   msg->reason_phrase);
		/* if we're already showing an image, then don't set the error
		 * as having an image (even if outdated) is better */
		if (ssimg->showing_image)
			return;
		/* TRANSLATORS: this is when we try to download a screenshot and
		 * we get back 404 */
		gs_screenshot_image_set_error (ssimg, _("Screenshot not found"));
		return;
	}

	/* create a buffer with the data */
	stream = g_memory_input_stream_new_from_data (msg->response_body->data,
						      msg->response_body->length,
						      NULL);
	if (stream == NULL)
		return;

	/* load the image */
	pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
	if (pixbuf == NULL) {
		/* TRANSLATORS: possibly image file corrupt or not an image */
		gs_screenshot_image_set_error (ssimg, _("Failed to load image"));
		return;
	}

	/* is image size destination size unknown or exactly the correct size */
	if (ssimg->width == G_MAXUINT || ssimg->height == G_MAXUINT ||
	    (ssimg->width * ssimg->scale == (guint) gdk_pixbuf_get_width (pixbuf) &&
	     ssimg->height * ssimg->scale == (guint) gdk_pixbuf_get_height (pixbuf))) {
		ret = g_file_set_contents (ssimg->filename,
					   msg->response_body->data,
					   msg->response_body->length,
					   &error);
		if (!ret) {
			gs_screenshot_image_set_error (ssimg, error->message);
			return;
		}
	} else if (!gs_screenshot_image_save_downloaded_img (ssimg, pixbuf,
							     &error)) {
		gs_screenshot_image_set_error (ssimg, error->message);
		return;
	}

	/* got image, so show */
	as_screenshot_show_image (ssimg);
}
Example #2
0
/**
 * gd_embed_image_in_frame: 
 * @source_image:
 * @frame_image_path:
 * @slice_width:
 * @border_width:
 *
 * Returns: (transfer full):
 */
GdkPixbuf *
gd_embed_image_in_frame (GdkPixbuf *source_image,
                         const gchar *frame_image_path,
                         GtkBorder *slice_width,
                         GtkBorder *border_width)
{
  cairo_surface_t *surface;
  cairo_t *cr;
  int source_width, source_height;
  int dest_width, dest_height;
  gchar *css_str;
  GtkCssProvider *provider;
  GtkStyleContext *context;
  GError *error = NULL;
  GdkPixbuf *retval;
  GtkWidgetPath *path;
 
  source_width = gdk_pixbuf_get_width (source_image);
  source_height = gdk_pixbuf_get_height (source_image);

  dest_width = source_width +  border_width->left + border_width->right;
  dest_height = source_height + border_width->top + border_width->bottom;

  css_str = g_strdup_printf (".embedded-image { border-image: url(\"%s\") %d %d %d %d / %dpx %dpx %dpx %dpx }",
                             frame_image_path, 
                             slice_width->top, slice_width->right, slice_width->bottom, slice_width->left,
                             border_width->top, border_width->right, border_width->bottom, border_width->left);
  provider = gtk_css_provider_new ();
  gtk_css_provider_load_from_data (provider, css_str, -1, &error);

  if (error != NULL) 
    {
      g_warning ("Unable to create the thumbnail frame image: %s", error->message);
      g_error_free (error);
      g_free (css_str);

      return g_object_ref (source_image);
    }

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dest_width, dest_height);
  cr = cairo_create (surface);

  context = gtk_style_context_new ();
  path = gtk_widget_path_new ();
  gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW);

  gtk_style_context_set_path (context, path);
  gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), 600);

  gtk_style_context_save (context);
  gtk_style_context_add_class (context, "embedded-image");

  gtk_render_frame (context, cr,
                    0, 0,
                    dest_width, dest_height);

  gtk_style_context_restore (context);

  gtk_render_icon (context, cr,
                   source_image,
                   border_width->left, border_width->top);

  retval = gdk_pixbuf_get_from_surface (surface,
                                        0, 0, dest_width, dest_height);

  cairo_surface_destroy (surface);
  cairo_destroy (cr);

  gtk_widget_path_unref (path);
  g_object_unref (provider);
  g_object_unref (context);
  g_free (css_str);

  return retval;
}
Example #3
0
static gboolean
draw_gap_image(GtkStyle       *style,
	       GdkWindow      *window,
	       GdkRectangle   *area,
	       GtkWidget      *widget,
	       ThemeMatchData *match_data,
	       gboolean        draw_center,
	       gint            x,
	       gint            y,
	       gint            width,
	       gint            height,
	       GtkPositionType gap_side,
	       gint            gap_x,
	       gint            gap_width)
{
  ThemeImage *image;
  gboolean setbg = FALSE;
  
  if ((width == -1) && (height == -1))
    {
      gdk_drawable_get_size(window, &width, &height);
      setbg = TRUE;
    }
  else if (width == -1)
    gdk_drawable_get_size(window, &width, NULL);
  else if (height == -1)
    gdk_drawable_get_size(window, NULL, &height);

  if (!(match_data->flags & THEME_MATCH_ORIENTATION))
    {
      match_data->flags |= THEME_MATCH_ORIENTATION;
      
      if (height > width)
	match_data->orientation = GTK_ORIENTATION_VERTICAL;
      else
	match_data->orientation = GTK_ORIENTATION_HORIZONTAL;
    }

  match_data->flags |= THEME_MATCH_GAP_SIDE;
  match_data->gap_side = gap_side;
    
  image = match_theme_image (style, match_data);
  if (image)
    {
      gint thickness;
      GdkRectangle r1 = {0,0,0,0}, r2 = {0,0,0,0}, r3 = {0,0,0,0};
      GdkPixbuf *pixbuf = NULL;
      guint components = COMPONENT_ALL;

      if (!draw_center)
	components |= COMPONENT_CENTER;

      if (image->gap_start)
	pixbuf = theme_pixbuf_get_pixbuf (image->gap_start, -1, -1);

      switch (gap_side)
	{
	case GTK_POS_TOP:
	  if (pixbuf)
	    thickness = gdk_pixbuf_get_height (pixbuf);
	  else
	    thickness = style->ythickness;
	  
	  if (!draw_center)
	    components |= COMPONENT_NORTH_WEST | COMPONENT_NORTH | COMPONENT_NORTH_EAST;

	  r1.x      = x;
	  r1.y      = y;
	  r1.width  = gap_x;
	  r1.height = thickness;
	  r2.x      = x + gap_x;
	  r2.y      = y;
	  r2.width  = gap_width;
	  r2.height = thickness;
	  r3.x      = x + gap_x + gap_width;
	  r3.y      = y;
	  r3.width  = width - (gap_x + gap_width);
	  r3.height = thickness;
	  break;
	  
	case GTK_POS_BOTTOM:
	  if (pixbuf)
	    thickness = gdk_pixbuf_get_height (pixbuf);
	  else
	    thickness = style->ythickness;

	  if (!draw_center)
	    components |= COMPONENT_SOUTH_WEST | COMPONENT_SOUTH | COMPONENT_SOUTH_EAST;

	  r1.x      = x;
	  r1.y      = y + height - thickness;
	  r1.width  = gap_x;
	  r1.height = thickness;
	  r2.x      = x + gap_x;
	  r2.y      = y + height - thickness;
	  r2.width  = gap_width;
	  r2.height = thickness;
	  r3.x      = x + gap_x + gap_width;
	  r3.y      = y + height - thickness;
	  r3.width  = width - (gap_x + gap_width);
	  r3.height = thickness;
	  break;
	  
	case GTK_POS_LEFT:
	  if (pixbuf)
	    thickness = gdk_pixbuf_get_width (pixbuf);
	  else
	    thickness = style->xthickness;

	  if (!draw_center)
	    components |= COMPONENT_NORTH_WEST | COMPONENT_WEST | COMPONENT_SOUTH_WEST;

	  r1.x      = x;
	  r1.y      = y;
	  r1.width  = thickness;
	  r1.height = gap_x;
	  r2.x      = x;
	  r2.y      = y + gap_x;
	  r2.width  = thickness;
	  r2.height = gap_width;
	  r3.x      = x;
	  r3.y      = y + gap_x + gap_width;
	  r3.width  = thickness;
	  r3.height = height - (gap_x + gap_width);
	  break;
	  
	case GTK_POS_RIGHT:
	  if (pixbuf)
	    thickness = gdk_pixbuf_get_width (pixbuf);
	  else
	    thickness = style->xthickness;

	  if (!draw_center)
	    components |= COMPONENT_NORTH_EAST | COMPONENT_EAST | COMPONENT_SOUTH_EAST;

	  r1.x      = x + width - thickness;
	  r1.y      = y;
	  r1.width  = thickness;
	  r1.height = gap_x;
	  r2.x      = x + width - thickness;
	  r2.y      = y + gap_x;
	  r2.width  = thickness;
	  r2.height = gap_width;
	  r3.x      = x + width - thickness;
	  r3.y      = y + gap_x + gap_width;
	  r3.width  = thickness;
	  r3.height = height - (gap_x + gap_width);
	  break;
	}

      if (image->background)
	theme_pixbuf_render (image->background,
			     window, NULL, area, components, FALSE,
			     x, y, width, height);
      if (image->gap_start)
	theme_pixbuf_render (image->gap_start,
			     window, NULL, area, COMPONENT_ALL, FALSE,
			     r1.x, r1.y, r1.width, r1.height);
      if (image->gap)
	theme_pixbuf_render (image->gap,
			     window, NULL, area, COMPONENT_ALL, FALSE,
			     r2.x, r2.y, r2.width, r2.height);
      if (image->gap_end)
	theme_pixbuf_render (image->gap_end,
			     window, NULL, area, COMPONENT_ALL, FALSE,
			     r3.x, r3.y, r3.width, r3.height);

      return TRUE;
    }
  else
    return FALSE;
}
Example #4
0
GdkPixbuf *
gl_pixbuf_util_create_shadow_pixbuf (const GdkPixbuf *pixbuf,
                                     guint            shadow_color,
                                     gdouble          shadow_opacity)
{
        gint             bits_per_sample, channels;
        gboolean         src_has_alpha;
        gint             width, height, src_rowstride, dest_rowstride;
        GdkPixbuf       *dest_pixbuf;
        guchar          *buf_src, *buf_dest;
        guchar          *p_src, *p_dest;
        gint             ix, iy;
        guchar           shadow_r, shadow_g, shadow_b;

        g_return_val_if_fail (pixbuf && GDK_IS_PIXBUF (pixbuf), NULL);

        shadow_r = GL_COLOR_F_RED   (shadow_color) * 255.0;
        shadow_g = GL_COLOR_F_GREEN (shadow_color) * 255.0;
        shadow_b = GL_COLOR_F_BLUE  (shadow_color) * 255.0;

        /* extract pixels and parameters from source pixbuf. */
        buf_src         = gdk_pixbuf_get_pixels (pixbuf);
        bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
        channels        = gdk_pixbuf_get_n_channels (pixbuf);
        src_has_alpha   = gdk_pixbuf_get_has_alpha (pixbuf);
        width           = gdk_pixbuf_get_width (pixbuf);
        height          = gdk_pixbuf_get_height (pixbuf);
        src_rowstride   = gdk_pixbuf_get_rowstride (pixbuf);

        /* validate assumptions about source pixbuf. */
        g_return_val_if_fail (buf_src, NULL);
        g_return_val_if_fail (bits_per_sample == 8, NULL);
        g_return_val_if_fail ((channels >= 3) && (channels <= 4), NULL);
        g_return_val_if_fail (width > 0, NULL);
        g_return_val_if_fail (height > 0, NULL);
        g_return_val_if_fail (src_rowstride > 0, NULL);

        /* Allocate a destination pixbuf */
        dest_pixbuf    = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, bits_per_sample, width, height);
        dest_rowstride = gdk_pixbuf_get_rowstride (dest_pixbuf);
        buf_dest       = gdk_pixbuf_get_pixels (dest_pixbuf);
        if (!buf_dest) {
                return NULL;
        }

        /* Process pixels: set rgb components and composite alpha with shadow_opacity. */
        p_src  = buf_src;
        p_dest = buf_dest;
        for ( iy=0; iy < height; iy++ )
        {
        
                p_src  = buf_src + iy*src_rowstride;
                p_dest = buf_dest + iy*dest_rowstride;

                for ( ix=0; ix < width; ix++ )
                {

                        p_src += 3; /* skip RGB */

                        *p_dest++ = shadow_r;
                        *p_dest++ = shadow_g;
                        *p_dest++ = shadow_b;

                        if ( src_has_alpha )
                        {
                                *p_dest++ = *p_src++ * shadow_opacity;
                        }
                        else
                        {
                                *p_dest++ = shadow_opacity * 255.0;
                        }


                }

        }

        return dest_pixbuf;
}
Example #5
0
static nsresult
moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI *aURI,
                          nsIChannel **aChannel)
{
  int width = gdk_pixbuf_get_width(aPixbuf);
  int height = gdk_pixbuf_get_height(aPixbuf);
  NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 &&
                 gdk_pixbuf_get_colorspace(aPixbuf) == GDK_COLORSPACE_RGB &&
                 gdk_pixbuf_get_bits_per_sample(aPixbuf) == 8 &&
                 gdk_pixbuf_get_has_alpha(aPixbuf) &&
                 gdk_pixbuf_get_n_channels(aPixbuf) == 4,
                 NS_ERROR_UNEXPECTED);

  const int n_channels = 4;
  gsize buf_size = 2 + n_channels * height * width;
  uint8_t * const buf = (uint8_t*)NS_Alloc(buf_size);
  NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
  uint8_t *out = buf;

  *(out++) = width;
  *(out++) = height;

  const guchar * const pixels = gdk_pixbuf_get_pixels(aPixbuf);
  int rowextra = gdk_pixbuf_get_rowstride(aPixbuf) - width * n_channels;

  // encode the RGB data and the A data
  const guchar * in = pixels;
  for (int y = 0; y < height; ++y, in += rowextra) {
    for (int x = 0; x < width; ++x) {
      uint8_t r = *(in++);
      uint8_t g = *(in++);
      uint8_t b = *(in++);
      uint8_t a = *(in++);
#define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
#ifdef IS_LITTLE_ENDIAN
      *(out++) = DO_PREMULTIPLY(b);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = a;
#else
      *(out++) = a;
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(b);
#endif
#undef DO_PREMULTIPLY
    }
  }

  NS_ASSERTION(out == buf + buf_size, "size miscalculation");

  nsresult rv;
  nsCOMPtr<nsIStringInputStream> stream =
    do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = stream->AdoptData((char*)buf, buf_size);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = NS_NewInputStreamChannel(aChannel, aURI, stream,
                                NS_LITERAL_CSTRING("image/icon"));
  return rv;
}
Example #6
0
void generate_thumbnails_with_gdk_pixbuf(ThumbnailTask* task)
{
    /* FIXME: only formats supported by GdkPixbuf should be handled this way. */
    GFile* gf = fm_path_to_gfile(task->fi->path);
    GFileInputStream* ins;
    GdkPixbuf* normal_pix = NULL;
    GdkPixbuf* large_pix = NULL;

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

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

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

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

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

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

    g_object_unref(gf);
}
Example #7
0
static gboolean
real_save_jpeg (GdkPixbuf          *pixbuf,
		gchar             **keys,
		gchar             **values,
		GError            **error,
		gboolean            to_callback,
		FILE               *f,
		GdkPixbufSaveFunc   save_func,
		gpointer            user_data)
{
        /* FIXME error handling is broken */
        
       struct jpeg_compress_struct cinfo;
       guchar *buf = NULL;
       guchar *ptr;
       guchar *pixels = NULL;
       JSAMPROW *jbuf;
       int y = 0;
       volatile int quality = 75; /* default; must be between 0 and 100 */
       int i, j;
       int w, h = 0;
       int rowstride = 0;
       int n_channels;
       struct error_handler_data jerr;
       ToFunctionDestinationManager to_callback_destmgr;
       gchar *icc_profile = NULL;
       gchar *data;
       gint retval = TRUE;
       gsize icc_profile_size = 0;

       to_callback_destmgr.buffer = NULL;

       if (keys && *keys) {
               gchar **kiter = keys;
               gchar **viter = values;

               while (*kiter) {
                       if (strcmp (*kiter, "quality") == 0) {
                               char *endptr = NULL;
                               quality = strtol (*viter, &endptr, 10);

                               if (endptr == *viter) {
                                       g_set_error (error,
                                                    GDK_PIXBUF_ERROR,
                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                    _("JPEG quality must be a value between 0 and 100; value '%s' could not be parsed."),
                                                    *viter);

                                       retval = FALSE;
                                       goto cleanup;
                               }
                               
                               if (quality < 0 ||
                                   quality > 100) {
                                       /* This is a user-visible error;
                                        * lets people skip the range-checking
                                        * in their app.
                                        */
                                       g_set_error (error,
                                                    GDK_PIXBUF_ERROR,
                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                    _("JPEG quality must be a value between 0 and 100; value '%d' is not allowed."),
                                                    quality);

                                       retval = FALSE;
                                       goto cleanup;
                               }
                       } else if (strcmp (*kiter, "icc-profile") == 0) {
                               /* decode from base64 */
                               icc_profile = (gchar*) g_base64_decode (*viter, &icc_profile_size);
                               if (icc_profile_size < 127) {
                                       /* This is a user-visible error */
                                       g_set_error (error,
                                                    GDK_PIXBUF_ERROR,
                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                    _("Color profile has invalid length '%u'."),
                                                    (guint) icc_profile_size);
                                       retval = FALSE;
                                       goto cleanup;
                               }
                       } else {
                               g_warning ("Unrecognized parameter (%s) passed to JPEG saver.", *kiter);
                       }
               
                       ++kiter;
                       ++viter;
               }
       }
       
       rowstride = gdk_pixbuf_get_rowstride (pixbuf);
       n_channels = gdk_pixbuf_get_n_channels (pixbuf);

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

       /* Allocate a small buffer to convert image data,
	* and a larger buffer if doing to_callback save.
	*/
       buf = g_try_malloc (w * 3 * sizeof (guchar));
       if (!buf) {
	       g_set_error_literal (error,
                                    GDK_PIXBUF_ERROR,
                                    GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                                    _("Couldn't allocate memory for loading JPEG file"));
	       retval = FALSE;
	       goto cleanup;
       }
       if (to_callback) {
	       to_callback_destmgr.buffer = g_try_malloc (TO_FUNCTION_BUF_SIZE);
	       if (!to_callback_destmgr.buffer) {
		       g_set_error_literal (error,
                                            GDK_PIXBUF_ERROR,
                                            GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                                            _("Couldn't allocate memory for loading JPEG file"));
		       retval = FALSE;
		       goto cleanup;
	       }
       }

       /* set up error handling */
       cinfo.err = jpeg_std_error (&(jerr.pub));
       jerr.pub.error_exit = fatal_error_handler;
       jerr.pub.output_message = output_message_handler;
       jerr.error = error;
       
       if (sigsetjmp (jerr.setjmp_buffer, 1)) {
               jpeg_destroy_compress (&cinfo);
	       retval = FALSE;
	       goto cleanup;
       }

       /* setup compress params */
       jpeg_create_compress (&cinfo);
       if (to_callback) {
	       to_callback_destmgr.pub.init_destination    = to_callback_init;
	       to_callback_destmgr.pub.empty_output_buffer = to_callback_empty_output_buffer;
	       to_callback_destmgr.pub.term_destination    = to_callback_terminate;
	       to_callback_destmgr.error = error;
	       to_callback_destmgr.save_func = save_func;
	       to_callback_destmgr.user_data = user_data;
	       cinfo.dest = (struct jpeg_destination_mgr*) &to_callback_destmgr;
       } else {
	       jpeg_stdio_dest (&cinfo, f);
       }
       cinfo.image_width      = w;
       cinfo.image_height     = h;
       cinfo.input_components = 3; 
       cinfo.in_color_space   = JCS_RGB;

       /* set up jepg compression parameters */
       jpeg_set_defaults (&cinfo);
       jpeg_set_quality (&cinfo, quality, TRUE);

       jpeg_start_compress (&cinfo, TRUE);

	/* write ICC profile data */
	if (icc_profile != NULL) {
		/* optimise for the common case where only one APP2 segment is required */
		if (icc_profile_size < 0xffef) {
			data = g_new (gchar, icc_profile_size + 14);
			memcpy (data, "ICC_PROFILE\000\001\001", 14);
			memcpy (data + 14, icc_profile, icc_profile_size);
			jpeg_write_marker (&cinfo, JPEG_APP0+2, (const JOCTET *) data, icc_profile_size + 14);
			g_free (data);
		} else {
			guint segments;
			guint size = 0xffef;
			guint offset;

			segments = (guint) ceilf ((gfloat) icc_profile_size / (gfloat) 0xffef);
			data = g_new (gchar, 0xffff);
			memcpy (data, "ICC_PROFILE\000", 12);
			data[13] = segments;
			for (i=0; i<=segments; i++) {
				data[12] = i;
				offset = 0xffef * i;

				/* last segment */
				if (i == segments)
					size = icc_profile_size % 0xffef;

				memcpy (data + 14, icc_profile + offset, size);
				jpeg_write_marker (&cinfo, JPEG_APP0+2, (const JOCTET *) data, size + 14);
			}
			g_free (data);
		}
	}

       /* get the start pointer */
       ptr = pixels;
       /* go one scanline at a time... and save */
       i = 0;
       while (cinfo.next_scanline < cinfo.image_height) {
               /* convert scanline from ARGB to RGB packed */
               for (j = 0; j < w; j++)
                       memcpy (&(buf[j*3]), &(ptr[i*rowstride + j*n_channels]), 3);

               /* write scanline */
               jbuf = (JSAMPROW *)(&buf);
               jpeg_write_scanlines (&cinfo, jbuf, 1);
               i++;
               y++;

       }

       /* finish off */
       jpeg_finish_compress (&cinfo);
       jpeg_destroy_compress(&cinfo);
cleanup:
	g_free (buf);
	g_free (to_callback_destmgr.buffer);
	g_free (icc_profile);
	return retval;
}
Example #8
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);
}
Example #9
0
static gboolean
gst_gdk_pixbuf_overlay_load_image (GstGdkPixbufOverlay * overlay, GError ** err)
{
  GstVideoMeta *video_meta;
  GdkPixbuf *pixbuf;
  guint8 *pixels, *p;
  gint width, height, stride, w, h, plane;

  pixbuf = gdk_pixbuf_new_from_file (overlay->location, err);

  if (pixbuf == NULL)
    return FALSE;

  if (!gdk_pixbuf_get_has_alpha (pixbuf)) {
    GdkPixbuf *alpha_pixbuf;

    /* FIXME: we could do this much more efficiently ourselves below, but
     * we're lazy for now */
    /* FIXME: perhaps expose substitute_color via properties */
    alpha_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
    g_object_unref (pixbuf);
    pixbuf = alpha_pixbuf;
  }

  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);
  stride = gdk_pixbuf_get_rowstride (pixbuf);
  pixels = gdk_pixbuf_get_pixels (pixbuf);

  /* the memory layout in GdkPixbuf is R-G-B-A, we want:
   *  - B-G-R-A on little-endian platforms
   *  - A-R-G-B on big-endian platforms
   */
  for (h = 0; h < height; ++h) {
    p = pixels + (h * stride);
    for (w = 0; w < width; ++w) {
      guint8 tmp;

      /* R-G-B-A ==> B-G-R-A */
      tmp = p[0];
      p[0] = p[2];
      p[2] = tmp;

      if (G_BYTE_ORDER == G_BIG_ENDIAN) {
        /* B-G-R-A ==> A-R-G-B */
        /* we can probably assume sane alignment */
        *((guint32 *) p) = GUINT32_SWAP_LE_BE (*((guint32 *) p));
      }

      p += 4;
    }
  }

  /* assume we have row padding even for the last row */
  /* transfer ownership of pixbuf to the buffer */
  overlay->pixels = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
      pixels, height * stride, 0, height * stride, pixbuf,
      (GDestroyNotify) g_object_unref);

  video_meta = gst_buffer_add_video_meta (overlay->pixels,
      GST_VIDEO_FRAME_FLAG_NONE, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB,
      width, height);

  for (plane = 0; plane < video_meta->n_planes; ++plane)
    video_meta->stride[plane] = stride;

  overlay->update_composition = TRUE;

  GST_INFO_OBJECT (overlay, "Loaded image, %d x %d", width, height);
  return TRUE;
}
Example #10
0
static void
_gdk_pixbuf_draw_rectangle (GdkPixbuf *pixbuf, 
			    int        offset,
			    guchar     alpha)
{
	guchar   *pixels;
	guchar   *p;
	int       width, height;
	int       n_channels, rowstride;
	int       w, h;
	
	g_return_if_fail (GDK_IS_PIXBUF (pixbuf));

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

	if (width == 0 || height == 0)
		return;

	pixels = gdk_pixbuf_get_pixels (pixbuf);
	n_channels = gdk_pixbuf_get_n_channels (pixbuf);
	rowstride = gdk_pixbuf_get_rowstride (pixbuf);

	offset = MIN (offset, width / 2);
	offset = MIN (offset, height / 2);

	width -= offset * 2;
	height -= offset * 2;

	width = MAX (0, width);
	height = MAX (0, height);

	p = pixels + (rowstride * offset) + (offset * n_channels);
	for (w = 0; w <= width; w++) {
		p[0] = 0x00;
		p[1] = 0x00;
		p[2] = 0x00;
		p[3] = alpha;
		p += n_channels;
	}

	p = pixels + (rowstride * (height + offset)) + (offset * n_channels);
	for (w = 0; w <= width; w++) {
		p[0] = 0x00;
		p[1] = 0x00;
		p[2] = 0x00;
		p[3] = alpha;
		p += n_channels;
	}

	p = pixels + (rowstride * offset) + (offset * n_channels);
	for (h = offset; h <= height + offset; h++) {
		p[0] = 0x00;
		p[1] = 0x00;
		p[2] = 0x00;
		p[3] = alpha;
		p += rowstride;
	}

	p = pixels + (rowstride * offset) + ((offset + width) * n_channels);
	for (h = offset; h <= height + offset; h++) {
		p[0] = 0x00;
		p[1] = 0x00;
		p[2] = 0x00;
		p[3] = alpha;
		p += rowstride;
	}
}
Example #11
0
static void
_gdk_pixbuf_fill_triangle (GdkPixbuf *shadow, 
			   guint32    color1,
			   guint32    color2)
{
	guint32   r, g, b, a;
	guint32   r1, g1, b1, a1;
	guint32   r2, g2, b2, a2;
	int       i, j;
	int       w, h;
	double    x, dx;
	int       n_channels, rowstride;
	guchar   *p;
	guchar   *pixels;

	r1 = (color1 & 0xff000000) >> 24;
	g1 = (color1 & 0x00ff0000) >> 16;
	b1 = (color1 & 0x0000ff00) >> 8;
	a1 = (color1 & 0x000000ff);

	r2 = (color2 & 0xff000000) >> 24;
	g2 = (color2 & 0x00ff0000) >> 16;
	b2 = (color2 & 0x0000ff00) >> 8;
	a2 = (color2 & 0x000000ff);

	w = gdk_pixbuf_get_width (shadow);
	h = gdk_pixbuf_get_height (shadow);
	n_channels = gdk_pixbuf_get_n_channels (shadow);
	rowstride = gdk_pixbuf_get_rowstride (shadow);
	pixels = gdk_pixbuf_get_pixels (shadow);

	dx = ((double) w) / h;
	x  = w;

	for (j = 0; j < h; j++) {
		p = pixels;

		for (i = 0; i < w; i++) {
			if (i < (int) x) {
				r = r1;	
				g = g1;	
				b = b1;	
				a = a1;	
			} else {
				r = r2;	
				g = g2;	
				b = b2;	
				a = a2;	
			}

			p[0] = r; 
			p[1] = g; 
			p[2] = b;

			switch (n_channels) {
			case 3:
				p += 3;
				break;
			case 4:
				p[3] = a;
				p += 4;
				break;
			default:
				break;
			}
		}

		x -= dx;
		pixels += rowstride;
	}
}
Example #12
0
static void
update_surface (FishApplet *fish)
{
	GtkWidget     *widget = fish->drawing_area;
	GtkRequisition prev_requisition;
	GtkAllocation  allocation;
	int            width  = -1;
	int            height = -1;
	int            pixbuf_width = -1;
	int            pixbuf_height = -1;
	gboolean       rotate = FALSE;
	cairo_t       *cr;
	cairo_matrix_t matrix;
	cairo_pattern_t *pattern;

	gtk_widget_get_allocation (widget, &allocation);

	if (!gtk_widget_get_realized (widget) ||
	    allocation.width <= 0 ||
	    allocation.height <= 0)
		return;

	if (!fish->pixbuf && !load_fish_image (fish))
		return;

	if (fish->rotate &&
	    (fish->orientation == PANEL_APPLET_ORIENT_LEFT ||
	     fish->orientation == PANEL_APPLET_ORIENT_RIGHT))
		rotate = TRUE;

	pixbuf_width  = gdk_pixbuf_get_width  (fish->pixbuf);
	pixbuf_height = gdk_pixbuf_get_height (fish->pixbuf);

	prev_requisition = fish->requisition;

	if (fish->orientation == PANEL_APPLET_ORIENT_UP ||
	    fish->orientation == PANEL_APPLET_ORIENT_DOWN) {
		height = allocation.height;
		width  = pixbuf_width * ((gdouble) height / pixbuf_height);

		fish->requisition.width = width / fish->n_frames;
		fish->requisition.height = height;
	} else {
		if (!rotate) {
			width = allocation.width * fish->n_frames;
			height = pixbuf_height * ((gdouble) width / pixbuf_width);
			fish->requisition.width = allocation.width;
			fish->requisition.height = height;
		} else {
			width = allocation.width;
			height = pixbuf_width * ((gdouble) width / pixbuf_height);
			fish->requisition.width = width;
			fish->requisition.height = height / fish->n_frames;
		}
	}

	if (prev_requisition.width  != fish->requisition.width ||
	    prev_requisition.height != fish->requisition.height) {
		gtk_widget_set_size_request (widget,
					     fish->requisition.width,
					     fish->requisition.height);
	}

	g_assert (width != -1 && height != -1);

	if (width == 0 || height == 0)
		return;

	if (fish->surface)
		cairo_surface_destroy (fish->surface);
	fish->surface = gdk_window_create_similar_surface (
			               gtk_widget_get_window (widget),
			               CAIRO_CONTENT_COLOR_ALPHA,
			               width, height);

	gtk_widget_queue_resize (widget);

	g_assert (pixbuf_width != -1 && pixbuf_height != -1);

	cr = cairo_create (fish->surface);

	cairo_set_source_rgb (cr, 1, 1, 1);
	cairo_paint (cr);

	gdk_cairo_set_source_pixbuf (cr, fish->pixbuf, 0, 0);
	pattern = cairo_get_source (cr);
	cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);

	cairo_matrix_init_identity (&matrix);

	if (fish->april_fools) {
		cairo_matrix_translate (&matrix,
					pixbuf_width - 1, pixbuf_height - 1);
		cairo_matrix_rotate (&matrix, M_PI);
	}

	if (rotate) {
		if (fish->orientation == PANEL_APPLET_ORIENT_RIGHT) {
			cairo_matrix_translate (&matrix, pixbuf_width - 1, 0);
			cairo_matrix_rotate (&matrix, M_PI * 0.5);
		} else {
			cairo_matrix_translate (&matrix, 0, pixbuf_height - 1);
			cairo_matrix_rotate (&matrix, M_PI * 1.5);
		}
		cairo_matrix_scale (&matrix,
				    (double) (pixbuf_height - 1) / width,
				    (double) (pixbuf_width - 1) / height);
	} else {
		cairo_matrix_scale (&matrix,
				    (double) (pixbuf_width - 1) / width,
				    (double) (pixbuf_height - 1) / height);
	}

	cairo_pattern_set_matrix (pattern, &matrix);

	cairo_rectangle (cr, 0, 0, width, height);
	cairo_fill (cr);

	if (fish->april_fools) {
		cairo_set_source_rgb (cr, 1, 0.5, 0);
		cairo_paint_with_alpha (cr, 0.25);
	}

	cairo_destroy (cr);
}
static GstFlowReturn
gst_gdk_pixbuf_dec_flush (GstGdkPixbufDec * filter)
{
  GstBuffer *outbuf;
  GdkPixbuf *pixbuf;
  int y;
  guint8 *out_pix;
  guint8 *in_pix;
  int in_rowstride, out_rowstride;
  GstFlowReturn ret;
  GstCaps *caps = NULL;
  gint width, height;
  gint n_channels;
  GstVideoFrame frame;

  pixbuf = gdk_pixbuf_loader_get_pixbuf (filter->pixbuf_loader);
  if (pixbuf == NULL)
    goto no_pixbuf;

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

  if (GST_VIDEO_INFO_FORMAT (&filter->info) == GST_VIDEO_FORMAT_UNKNOWN) {
    GstVideoInfo info;
    GstVideoFormat fmt;
    GList *l;

    GST_DEBUG ("Set size to %dx%d", width, height);

    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
    switch (n_channels) {
      case 3:
        fmt = GST_VIDEO_FORMAT_RGB;
        break;
      case 4:
        fmt = GST_VIDEO_FORMAT_RGBA;
        break;
      default:
        goto channels_not_supported;
    }


    gst_video_info_init (&info);
    gst_video_info_set_format (&info, fmt, width, height);
    info.fps_n = filter->in_fps_n;
    info.fps_d = filter->in_fps_d;
    caps = gst_video_info_to_caps (&info);

    filter->info = info;

    gst_pad_set_caps (filter->srcpad, caps);
    gst_caps_unref (caps);

    gst_gdk_pixbuf_dec_setup_pool (filter, &info);

    for (l = filter->pending_events; l; l = l->next)
      gst_pad_push_event (filter->srcpad, l->data);
    g_list_free (filter->pending_events);
    filter->pending_events = NULL;
  }

  ret = gst_buffer_pool_acquire_buffer (filter->pool, &outbuf, NULL);
  if (ret != GST_FLOW_OK)
    goto no_buffer;

  GST_BUFFER_TIMESTAMP (outbuf) = filter->last_timestamp;
  GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;

  in_pix = gdk_pixbuf_get_pixels (pixbuf);
  in_rowstride = gdk_pixbuf_get_rowstride (pixbuf);

  gst_video_frame_map (&frame, &filter->info, outbuf, GST_MAP_WRITE);
  out_pix = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
  out_rowstride = GST_VIDEO_FRAME_PLANE_STRIDE (&frame, 0);

  for (y = 0; y < height; y++) {
    memcpy (out_pix, in_pix, width * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, 0));
    in_pix += in_rowstride;
    out_pix += out_rowstride;
  }

  gst_video_frame_unmap (&frame);

  GST_DEBUG ("pushing... %" G_GSIZE_FORMAT " bytes",
      gst_buffer_get_size (outbuf));
  ret = gst_pad_push (filter->srcpad, outbuf);

  if (ret != GST_FLOW_OK)
    GST_DEBUG_OBJECT (filter, "flow: %s", gst_flow_get_name (ret));

  return ret;

  /* ERRORS */
no_pixbuf:
  {
    GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL), ("error geting pixbuf"));
    return GST_FLOW_ERROR;
  }
channels_not_supported:
  {
    GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL),
        ("%d channels not supported", n_channels));
    return GST_FLOW_ERROR;
  }
no_buffer:
  {
    GST_DEBUG ("Failed to create outbuffer - %s", gst_flow_get_name (ret));
    return ret;
  }
}
static void
gs_plugin_key_colors_set_for_pixbuf (GsApp *app, GdkPixbuf *pb, guint number)
{
	GList *l;
	gint rowstride, n_channels;
	gint x, y;
	guchar *pixels, *p;
	guint bin_size = 200;
	guint i;
	guint number_of_bins;
	g_autoptr(AsImage) im = NULL;

	/* go through each pixel */
	n_channels = gdk_pixbuf_get_n_channels (pb);
	rowstride = gdk_pixbuf_get_rowstride (pb);
	pixels = gdk_pixbuf_get_pixels (pb);
	for (bin_size = 250; bin_size > 0; bin_size -= 2) {
		g_autoptr(GHashTable) hash = NULL;
		hash = g_hash_table_new_full (g_direct_hash,  g_direct_equal,
					      NULL, g_free);
		for (y = 0; y < gdk_pixbuf_get_height (pb); y++) {
			for (x = 0; x < gdk_pixbuf_get_width (pb); x++) {
				CdColorRGB8 tmp;
				GsColorBin *s;
				gpointer key;

				/* disregard any with alpha */
				p = pixels + y * rowstride + x * n_channels;
				if (p[3] != 255)
					continue;

				/* find in cache */
				tmp.R = (guint8) (p[0] / bin_size);
				tmp.G = (guint8) (p[1] / bin_size);
				tmp.B = (guint8) (p[2] / bin_size);
				key = GUINT_TO_POINTER (cd_color_rgb8_to_uint32 (&tmp));
				s = g_hash_table_lookup (hash, key);
				if (s != NULL) {
					s->color.red += _convert_from_rgb8 (p[0]);
					s->color.green += _convert_from_rgb8 (p[1]);
					s->color.blue += _convert_from_rgb8 (p[2]);
					s->cnt++;
					continue;
				}

				/* add to hash table */
				s = g_new0 (GsColorBin, 1);
				s->color.red = _convert_from_rgb8 (p[0]);
				s->color.green = _convert_from_rgb8 (p[1]);
				s->color.blue = _convert_from_rgb8 (p[2]);
				s->color.alpha = 1.0;
				s->cnt = 1;
				g_hash_table_insert (hash, key, s);
			}
		}

		number_of_bins = g_hash_table_size (hash);
//		g_debug ("number of colors: %i", number_of_bins);
		if (number_of_bins >= number) {
			g_autoptr(GList) values = NULL;

			/* order by most popular */
			values = g_hash_table_get_values (hash);
			values = g_list_sort (values, gs_color_bin_sort_cb);
			for (l = values; l != NULL; l = l->next) {
				GsColorBin *s = l->data;
				g_autofree GdkRGBA *color = g_new0 (GdkRGBA, 1);
				color->red = s->color.red / s->cnt;
				color->green = s->color.green / s->cnt;
				color->blue = s->color.blue / s->cnt;
				gs_app_add_key_color (app, color);
			}
			return;
		}
	}

	/* the algorithm failed, so just return a monochrome ramp */
	for (i = 0; i < 3; i++) {
		g_autofree GdkRGBA *color = g_new0 (GdkRGBA, 1);
		color->red = (gdouble) i / 3.f;
		color->green = color->red;
		color->blue = color->red;
		color->alpha = 1.0f;
		gs_app_add_key_color (app, color);
	}
}
Example #15
0
static gboolean real_save_png (GdkPixbuf        *pixbuf, 
                               gchar           **keys,
                               gchar           **values,
                               GError          **error,
                               gboolean          to_callback,
                               FILE             *f,
                               GdkPixbufSaveFunc save_func,
                               gpointer          user_data)
{
       png_structp png_ptr = NULL;
       png_infop info_ptr;
       png_textp text_ptr = NULL;
       guchar *ptr;
       guchar *pixels;
       int y;
       int i;
       png_bytep row_ptr;
       png_color_8 sig_bit;
       int w, h, rowstride;
       int has_alpha;
       int bpc;
       int num_keys;
       int compression = -1;
       gboolean success = TRUE;
       guchar *icc_profile = NULL;
       gsize icc_profile_size = 0;
       SaveToFunctionIoPtr to_callback_ioptr;

       num_keys = 0;

       if (keys && *keys) {
               gchar **kiter = keys;
               gchar **viter = values;

               while (*kiter) {
                       if (strncmp (*kiter, "tEXt::", 6) == 0) {
                               gchar  *key = *kiter + 6;
                               int     len = strlen (key);
                               if (len <= 1 || len > 79) {
                                       g_set_error_literal (error,
                                                            GDK_PIXBUF_ERROR,
                                                            GDK_PIXBUF_ERROR_BAD_OPTION,
                                                            _("Keys for PNG text chunks must have at least 1 and at most 79 characters."));
                                       success = FALSE;
                                       goto cleanup;
                               }
                               for (i = 0; i < len; i++) {
                                       if ((guchar) key[i] > 127) {
                                               g_set_error_literal (error,
                                                                    GDK_PIXBUF_ERROR,
                                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                                    _("Keys for PNG text chunks must be ASCII characters."));
                                               success = FALSE;
                                               goto cleanup;
                                       }
                               }
                               num_keys++;
                       } else if (strcmp (*kiter, "icc-profile") == 0) {
                               /* decode from base64 */
                               icc_profile = g_base64_decode (*viter, &icc_profile_size);
                               if (icc_profile_size < 127) {
                                       /* This is a user-visible error */
                                       g_set_error (error,
                                                    GDK_PIXBUF_ERROR,
                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                    _("Color profile has invalid length %d."),
                                                    (gint)icc_profile_size);
                                       success = FALSE;
                                       goto cleanup;
                               }
                       } else if (strcmp (*kiter, "compression") == 0) {
                               char *endptr = NULL;
                               compression = strtol (*viter, &endptr, 10);

                               if (endptr == *viter) {
                                       g_set_error (error,
                                                    GDK_PIXBUF_ERROR,
                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                    _("PNG compression level must be a value between 0 and 9; value '%s' could not be parsed."),
                                                    *viter);
                                       success = FALSE;
                                       goto cleanup;
                               }
                               if (compression < 0 || compression > 9) {
                                       /* This is a user-visible error;
                                        * lets people skip the range-checking
                                        * in their app.
                                        */
                                       g_set_error (error,
                                                    GDK_PIXBUF_ERROR,
                                                    GDK_PIXBUF_ERROR_BAD_OPTION,
                                                    _("PNG compression level must be a value between 0 and 9; value '%d' is not allowed."),
                                                    compression);
                                       success = FALSE;
                                       goto cleanup;
                               }
                       } else {
                               g_warning ("Unrecognized parameter (%s) passed to PNG saver.", *kiter);
                       }

                       ++kiter;
                       ++viter;
               }
       }

       if (num_keys > 0) {
               text_ptr = g_new0 (png_text, num_keys);
               for (i = 0; i < num_keys; i++) {
                       text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE;
                       text_ptr[i].key  = keys[i] + 6;
                       text_ptr[i].text = g_convert (values[i], -1, 
                                                     "ISO-8859-1", "UTF-8", 
                                                     NULL, &text_ptr[i].text_length, 
                                                     NULL);

#ifdef PNG_iTXt_SUPPORTED 
                       if (!text_ptr[i].text) {
                               text_ptr[i].compression = PNG_ITXT_COMPRESSION_NONE;
                               text_ptr[i].text = g_strdup (values[i]);
                               text_ptr[i].text_length = 0;
                               text_ptr[i].itxt_length = strlen (text_ptr[i].text);
                               text_ptr[i].lang = NULL;
                               text_ptr[i].lang_key = NULL;
                       }
#endif

                       if (!text_ptr[i].text) {
                               g_set_error (error,
                                            GDK_PIXBUF_ERROR,
                                            GDK_PIXBUF_ERROR_BAD_OPTION,
                                            _("Value for PNG text chunk %s cannot be converted to ISO-8859-1 encoding."), keys[i] + 6);
                               num_keys = i;
                               for (i = 0; i < num_keys; i++)
                                       g_free (text_ptr[i].text);
                               g_free (text_ptr);
                               return FALSE;
                       }
               }
       }

       bpc = gdk_pixbuf_get_bits_per_sample (pixbuf);
       w = gdk_pixbuf_get_width (pixbuf);
       h = gdk_pixbuf_get_height (pixbuf);
       rowstride = gdk_pixbuf_get_rowstride (pixbuf);
       has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
       pixels = gdk_pixbuf_get_pixels (pixbuf);

       png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
                                          error,
                                          png_simple_error_callback,
                                          png_simple_warning_callback);
       if (png_ptr == NULL) {
	       success = FALSE;
	       goto cleanup;
       }

       info_ptr = png_create_info_struct (png_ptr);
       if (info_ptr == NULL) {
	       success = FALSE;
	       goto cleanup;
       }
       if (setjmp (png_jmpbuf(png_ptr))) {
	       success = FALSE;
	       goto cleanup;
       }

       if (num_keys > 0) {
               png_set_text (png_ptr, info_ptr, text_ptr, num_keys);
       }

       if (to_callback) {
               to_callback_ioptr.save_func = save_func;
               to_callback_ioptr.user_data = user_data;
               to_callback_ioptr.error = error;
               png_set_write_fn (png_ptr, &to_callback_ioptr,
                                 png_save_to_callback_write_func,
                                 png_save_to_callback_flush_func);
       } else {
               png_init_io (png_ptr, f);
       }

       if (compression >= 0)
               png_set_compression_level (png_ptr, compression);

#if defined(PNG_iCCP_SUPPORTED)
        /* the proper ICC profile title is encoded in the profile */
        if (icc_profile != NULL) {
                png_set_iCCP (png_ptr, info_ptr,
                              "ICC profile", PNG_COMPRESSION_TYPE_BASE,
                              (gchar*) icc_profile, icc_profile_size);
        }
#endif

       if (has_alpha) {
               png_set_IHDR (png_ptr, info_ptr, w, h, bpc,
                             PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
                             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
       } else {
               png_set_IHDR (png_ptr, info_ptr, w, h, bpc,
                             PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
                             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
       }
       sig_bit.red = bpc;
       sig_bit.green = bpc;
       sig_bit.blue = bpc;
       sig_bit.alpha = bpc;
       png_set_sBIT (png_ptr, info_ptr, &sig_bit);
       png_write_info (png_ptr, info_ptr);
       png_set_shift (png_ptr, &sig_bit);
       png_set_packing (png_ptr);

       ptr = pixels;
       for (y = 0; y < h; y++) {
               row_ptr = (png_bytep)ptr;
               png_write_rows (png_ptr, &row_ptr, 1);
               ptr += rowstride;
       }

       png_write_end (png_ptr, info_ptr);

cleanup:
        if (png_ptr != NULL)
                png_destroy_write_struct (&png_ptr, &info_ptr);

        g_free (icc_profile);

        if (text_ptr != NULL) {
                for (i = 0; i < num_keys; i++)
                        g_free (text_ptr[i].text);
                g_free (text_ptr);
        }

       return success;
}
Example #16
0
static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
    image_decoder_t *this = (image_decoder_t *) this_gen;
    GError *error = NULL;

    if (!this->video_open) {
        lprintf("opening video\n");
        (this->stream->video_out->open) (this->stream->video_out, this->stream);
        this->video_open = 1;
    }

    if (this->loader == NULL) {
        this->loader = gdk_pixbuf_loader_new ();
    }

    if (gdk_pixbuf_loader_write (this->loader, buf->mem, buf->size, &error) == FALSE) {
        lprintf("error loading image: %s\n", error->message);
        g_error_free (error);
        gdk_pixbuf_loader_close (this->loader, NULL);
        g_object_unref (G_OBJECT (this->loader));
        this->loader = NULL;
        return;
    }

    if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
        GdkPixbuf         *pixbuf;
        int                width, height, rowstride, n_channels;
        guchar            *img_buf;
        vo_frame_t        *img;
        int                color_matrix, flags;
        void              *rgb2yuy2;

        /*
         * this->image -> rgb data
         */
        if (gdk_pixbuf_loader_close (this->loader, &error) == FALSE) {
            lprintf("error loading image: %s\n", error->message);
            g_error_free (error);
            g_object_unref (G_OBJECT (this->loader));
            this->loader = NULL;
            return;
        }

        pixbuf = gdk_pixbuf_loader_get_pixbuf (this->loader);
        if (pixbuf != NULL)
            g_object_ref (G_OBJECT (pixbuf));
        g_object_unref (this->loader);
        this->loader = NULL;

        if (pixbuf == NULL) {
            lprintf("error loading image\n");
            return;
        }

        width = gdk_pixbuf_get_width (pixbuf) & ~1; /* must be even for init_yuv_planes */
        height = gdk_pixbuf_get_height (pixbuf);
        img_buf = gdk_pixbuf_get_pixels (pixbuf);

        _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width);
        _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height);

        lprintf("image loaded successfully\n");

        flags = VO_BOTH_FIELDS;
        color_matrix =
            this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE ? 11 : 10;
        VO_SET_FLAGS_CM (color_matrix, flags);

        /*
         * alloc video frame
         */
        img = this->stream->video_out->get_frame (this->stream->video_out, width, height,
                (double)width / (double)height,
                XINE_IMGFMT_YUY2,
                flags);

        /* crop if allocated frame is smaller than requested */
        if (width > img->width)
            width = img->width;
        if (height > img->height)
            height = img->height;
        img->ratio = (double)width / (double)height;

        /* rgb data -> yuv */
        n_channels = gdk_pixbuf_get_n_channels (pixbuf);
        rowstride = gdk_pixbuf_get_rowstride (pixbuf);

        rgb2yuy2 = rgb2yuy2_alloc (color_matrix, n_channels > 3 ? "rgba" : "rgb");
        if (!img->proc_slice || (img->height & 15)) {
            /* do all at once */
            rgb2yuy2_slice (rgb2yuy2, img_buf, rowstride, img->base[0], img->pitches[0], width, height);
        } else {
            /* sliced */
            uint8_t *sptr[1];
            int     y, h = 16;
            for (y = 0; y < height; y += 16) {
                if (y + 16 > height)
                    h = height & 15;
                sptr[0] = img->base[0] + y * img->pitches[0];
                rgb2yuy2_slice (rgb2yuy2, img_buf + y * rowstride, rowstride, sptr[0], img->pitches[0],
                                width, h);
                img->proc_slice (img, sptr);
            }
        }
        rgb2yuy2_free (rgb2yuy2);
        gdk_pixbuf_unref (pixbuf);

        /*
         * draw video frame
         */
        img->pts = buf->pts;
        img->duration = 3600;
        img->bad_frame = 0;

        _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration);

        img->draw(img, this->stream);
        img->free(img);
    }
}
Example #17
0
static nsresult
moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
                          nsIChannel** aChannel)
{
  int width = gdk_pixbuf_get_width(aPixbuf);
  int height = gdk_pixbuf_get_height(aPixbuf);
  NS_ENSURE_TRUE(height < 256 && width < 256 && height > 0 && width > 0 &&
                 gdk_pixbuf_get_colorspace(aPixbuf) == GDK_COLORSPACE_RGB &&
                 gdk_pixbuf_get_bits_per_sample(aPixbuf) == 8 &&
                 gdk_pixbuf_get_has_alpha(aPixbuf) &&
                 gdk_pixbuf_get_n_channels(aPixbuf) == 4,
                 NS_ERROR_UNEXPECTED);

  const int n_channels = 4;
  gsize buf_size = 2 + n_channels * height * width;
  uint8_t* const buf = (uint8_t*)moz_xmalloc(buf_size);
  NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
  uint8_t* out = buf;

  *(out++) = width;
  *(out++) = height;

  const guchar* const pixels = gdk_pixbuf_get_pixels(aPixbuf);
  int rowextra = gdk_pixbuf_get_rowstride(aPixbuf) - width * n_channels;

  // encode the RGB data and the A data
  const guchar* in = pixels;
  for (int y = 0; y < height; ++y, in += rowextra) {
    for (int x = 0; x < width; ++x) {
      uint8_t r = *(in++);
      uint8_t g = *(in++);
      uint8_t b = *(in++);
      uint8_t a = *(in++);
#define DO_PREMULTIPLY(c_) uint8_t(uint16_t(c_) * uint16_t(a) / uint16_t(255))
#if MOZ_LITTLE_ENDIAN
      *(out++) = DO_PREMULTIPLY(b);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = a;
#else
      *(out++) = a;
      *(out++) = DO_PREMULTIPLY(r);
      *(out++) = DO_PREMULTIPLY(g);
      *(out++) = DO_PREMULTIPLY(b);
#endif
#undef DO_PREMULTIPLY
    }
  }

  NS_ASSERTION(out == buf + buf_size, "size miscalculation");

  nsresult rv;
  nsCOMPtr<nsIStringInputStream> stream =
    do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);

  // Prevent the leaking of buf
  if (NS_WARN_IF(NS_FAILED(rv))) {
    free(buf);
    return rv;
  }

  // stream takes ownership of buf and will free it on destruction.
  // This function cannot fail.
  rv = stream->AdoptData((char*)buf, buf_size);

  // If this no longer holds then re-examine buf's lifetime.
  MOZ_ASSERT(NS_SUCCEEDED(rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
  NS_ENSURE_TRUE(nullPrincipal, NS_ERROR_FAILURE);

  return NS_NewInputStreamChannel(aChannel,
                                  aURI,
                                  stream,
                                  nullPrincipal,
                                  nsILoadInfo::SEC_NORMAL,
                                  nsIContentPolicy::TYPE_OTHER,
                                  NS_LITERAL_CSTRING(IMAGE_ICON_MS));
}
Example #18
0
/*!
 * \brief Create a dialog window containing a pre-defined pixbuf (from
 * file).
 *
 * The \c footprint_name variable is used in the dialog title.
 *
 * \return 0 when successful.
 */
int
dimensions_create_window
(
        gchar *image_filename,
                /*!< : is the filename of the image to draw in the
                 * window.*/
        gchar *footprint_type
                /*!< : is the footprint type.*/
)
{
        /* Create a dimensions window */
        GtkWidget *dimensions_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        /* Destroy the dimensions window when the main window of pcb-gfpw gets
         * destroyed */
        gtk_window_set_destroy_with_parent (GTK_WINDOW (dimensions_window),
                TRUE);
        /* Set the preview window title */
        gchar *dimensions_window_title = g_strdup_printf (_("dimensions of %s"),
                footprint_type);
        gtk_window_set_title (GTK_WINDOW (dimensions_window),
                dimensions_window_title);
        g_free (dimensions_window_title);
        gtk_container_set_border_width (GTK_CONTAINER (dimensions_window), 10);
        /* Set the delete signal for the window */
        g_signal_connect
        (
                GTK_OBJECT (dimensions_window),
                "delete_event",
                (GtkSignalFunc) dimensions_window_delete_event,
                NULL
        );
        /* Create a vertical box */
        GtkWidget *vbox = gtk_vbox_new (FALSE, 10);
        gtk_container_add (GTK_CONTAINER (dimensions_window), vbox);
        /* Load a pre-cooked dimensions image for the footprint type
         * and set the name accordingly */
        GdkPixbuf *dimensions_image = gdk_pixbuf_new_from_file (image_filename, NULL);
        GtkWidget *drawing_area = gtk_drawing_area_new ();
        gtk_widget_set_app_paintable (drawing_area, TRUE);
        /* Set the expose signal for the window */
        g_signal_connect
        (
                GTK_OBJECT (drawing_area),
                "expose-event",
                (GtkSignalFunc) dimensions_window_expose_event,
                dimensions_image
        );
        /* Get size of drawing_area and resize */
        gint width = gdk_pixbuf_get_width (dimensions_image);
        gint height = gdk_pixbuf_get_height (dimensions_image);
        gtk_widget_set_size_request (GTK_WIDGET (drawing_area), width, height);
        gtk_container_add (GTK_CONTAINER (vbox), drawing_area);
        /* Create a horizontal button box */
        GtkWidget *hbox = gtk_hbutton_box_new ();
        gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
        /* Create a close button */
        GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
        g_signal_connect
        (
                G_OBJECT (button),
                "clicked",
                G_CALLBACK (dimensions_window_close_cb),
                dimensions_window
        );
        /* Pack the button into the hbox */
        gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
        /* Pack the hbox into the vbox */
        gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
        /* Show the window */
        gtk_window_set_resizable (GTK_WINDOW (dimensions_window), FALSE);
        gtk_widget_realize (dimensions_window);
        gtk_widget_show_all (dimensions_window);
        /* Enter the GTK main loop */
        gtk_main ();
        return 0;
}
Example #19
0
File: vtegl.c Project: Cordia/vte
static void
_vte_gl_clear(struct _vte_draw *draw, gint x, gint y, gint width, gint height)
{
	struct _vte_gl_data *data;
	long xstop, ystop, i, j;
	int pixbufw, pixbufh, w, h, channels, stride;
	GLenum format = 0;
	guchar *pixels;

	data = (struct _vte_gl_data*) draw->impl_data;

	glXMakeCurrent(data->display, data->glwindow, data->context);

	if (data->bgpixbuf != NULL) {
		pixbufw = gdk_pixbuf_get_width(data->bgpixbuf);
		pixbufh = gdk_pixbuf_get_height(data->bgpixbuf);
	} else {
		pixbufw = pixbufh = 0;
	}

	if ((pixbufw == 0) || (pixbufh == 0)) {
		glColor4us(data->color.red,
			   data->color.green,
			   data->color.blue,
			   0xffff);
		glBegin(GL_POLYGON);
		glVertex2d(x, y);
		glVertex2d(x + width, y);
		glVertex2d(x + width, y + height - 1);
		glVertex2d(x, y + height - 1);
		glEnd();
		return;
	}

	/* Flood fill. */
	xstop = x + width;
	ystop = y + height;

	pixels = gdk_pixbuf_get_pixels(data->bgpixbuf);
	channels = gdk_pixbuf_get_n_channels(data->bgpixbuf);
	stride = gdk_pixbuf_get_rowstride(data->bgpixbuf);

	switch (channels) {
	case 3:
		format = GL_RGB;
		break;
	case 4:
		format = GL_RGBA;
		break;
	default:
		g_assert_not_reached();
		break;
	}

	y = ystop - height;
	j = (data->scrolly + y) % pixbufh;
	while (y < ystop) {
		x = xstop - width;
		i = (data->scrollx + x) % pixbufw;

		/* h = MIN(pixbufh - (j % pixbufh), ystop - y); */
		h = 1;
		while (x < xstop) {
			w = MIN(pixbufw - (i % pixbufw), xstop - x);

			glRasterPos2i(x, y);
			glDrawPixels(w, h,
				     format, GL_UNSIGNED_BYTE,
				     pixels + stride * j + channels * i);
			x += w;
			i = 0;
		}
		y += h;
		j = (data->scrolly + y) % pixbufh;
	}
	glFlush();
}
Example #20
0
static void create_win_message(char *icon, char *text, int duration)
{
  GtkWidget *gwin_message = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_has_resize_grip(GTK_WINDOW(gwin_message), FALSE);
  gtk_container_set_border_width (GTK_CONTAINER (gwin_message), 0);
  gtk_widget_realize (gwin_message);
  GdkWindow *gdkwin = gtk_widget_get_window(gwin_message);
  set_no_focus(gwin_message);

  GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (gwin_message), hbox);

  if (icon[0] != '-') {
    GtkWidget *image = gtk_image_new_from_file(icon);
    if (text[0] == '-') {
#if GTK_CHECK_VERSION(2,91,0)
      GdkPixbuf *pixbuf = NULL;
      GdkPixbufAnimation *anime = NULL;
      switch(gtk_image_get_storage_type(GTK_IMAGE(image))) {
        case GTK_IMAGE_PIXBUF:
          pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image));
          break;
        case GTK_IMAGE_ANIMATION:
          anime = gtk_image_get_animation(GTK_IMAGE(image));
          pixbuf = gdk_pixbuf_animation_get_static_image(anime);
          break;
        default:
          break;
      }
      cairo_surface_t *img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
      cairo_t *cr = cairo_create(img);
      gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
      cairo_paint(cr);
      cairo_region_t *mask = gdk_cairo_region_create_from_surface(img);
      gtk_widget_shape_combine_region(gwin_message, mask);
      cairo_region_destroy(mask);
      cairo_destroy(cr);
      cairo_surface_destroy(img);
#else
      GdkBitmap *bitmap = NULL;
      gdk_pixbuf_render_pixmap_and_mask(gdk_pixbuf_new_from_file(icon, NULL), NULL, &bitmap, 128);
      gtk_widget_shape_combine_mask(gwin_message, bitmap, 0, 0);
#endif
    }
    gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
  }

  if (text[0] != '-') {
    GtkWidget *label = gtk_label_new(text);
    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  }

  gtk_widget_show_all(gwin_message);

  int width, height;
  get_win_size(gwin_message, &width, &height);

  int ox=-1, oy;
  int szx, szy;
  if (tray_da_win) {
    gdk_window_get_origin  (tray_da_win, &ox, &oy);
#if !GTK_CHECK_VERSION(2,91,0)
    gdk_drawable_get_size(tray_da_win, &szx, &szy);
#else
    szx = gdk_window_get_width(tray_da_win);
    szy = gdk_window_get_height(tray_da_win);
#endif

    if (oy<height) {
      oy = szy;
    } else {
      oy -= height;
      if (oy + height > dpy_yl)
        oy = dpy_yl - height;
      if (oy < 0)
        oy = 0;
    }

    if (ox + width > dpy_xl)
      ox = dpy_xl - width;
    if (ox < 0)
      ox = 0;
  } else
  if (icon_main) {
    GdkRectangle rect;
    GtkOrientation ori;
    if (gtk_status_icon_get_geometry(icon_main, NULL, &rect, &ori)) {
      dbg("rect %d,%d\n", rect.x, rect.y, rect.width, rect.height);
      if (ori==GTK_ORIENTATION_HORIZONTAL) {
        ox=rect.x;
        if (rect.y > 100)
          oy=rect.y - height;
        else
          oy=rect.y + rect.height;
      } else {
        oy=rect.y;
        if (rect.x > 100)
          ox=rect.x - width;
        else
          ox=rect.x + rect.width;
      }
    }
  }

  if (ox < 0) {
    ox = dpy_xl - width;
    oy = dpy_yl - height;
  }

  gtk_window_move(GTK_WINDOW(gwin_message), ox, oy);

  g_timeout_add(duration, (GSourceFunc)timeout_destroy_window, gwin_message);
}
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;
}
Example #22
0
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;
}
Example #23
0
/* ------------------------------
 * gap_pview_render_f_from_pixbuf (slow)
 * ------------------------------
 * render drawing_area widget from src_pixbuf buffer
 * scaling and flattening against checkerboard background
 * is done implicite using GDK-pixbuf procedures
 *            
 * Thumbnails at size 128 rendered to Widget Size 256x256 pixels
 * at my Pentium IV 2600 MHZ
 * can be Played at Speed of  98 Frames/sec without dropping frames.
 *
 * The other Implementation without GDK-pixbuf procedures
 * is faster (at least on my machine), therefore GAP_PVIEW_USE_GDK_PIXBUF_RENDERING
 * is NOT defined per default.
 */
void
gap_pview_render_f_from_pixbuf (GapPView *pv_ptr
  , GdkPixbuf *src_pixbuf
  , gint32 flip_request
  , gint32 flip_status
  )
{
  static int l_checksize_tab[17] = { 2, 4, 8, 8, 16, 16, 16, 32, 32, 32, 32, 32, 32, 64, 64, 64, 64 };
  int l_check_size;

  /* printf("gap_pview_render_f_from_pixbuf --- USE GDK-PIXBUF procedures\n"); */
  
  if(pv_ptr == NULL) { return; }
  if(pv_ptr->da_widget == NULL) { return; }
  if(pv_ptr->da_widget->window == NULL)
  { 
    if(gap_debug)
    {
      printf("gap_pview_render_f_from_pixbuf: drawing_area window pointer is NULL, cant render\n");
    }
    return ;
  }

  if(src_pixbuf == NULL)
  {
    if(gap_debug)
    {
      printf("gap_pview_render_f_from_pixbuf: src_pixbuf is NULL, cant render\n");
    }
    return ;
  }

  /* clear flag to let gap_pview_repaint procedure know
   * to use the pixbuf rather than pv_area_data or pixmap for refresh
   */
  pv_ptr->use_pixmap_repaint = FALSE;
  pv_ptr->use_pixbuf_repaint = TRUE;
  p_free_desaturated_area_data(pv_ptr);

  /* l_check_size must be a power of 2 (using fixed size for 1.st test) */
  l_check_size = l_checksize_tab[MIN((pv_ptr->pv_check_size >> 2), 8)];
  if(pv_ptr->pixbuf)
  {
    /* free old (refresh) pixbuf if there is one */
    g_object_unref(pv_ptr->pixbuf);
  }
  
  /* scale and flatten the pixbuf */
  pv_ptr->pixbuf = gdk_pixbuf_composite_color_simple(
                         src_pixbuf
                      , (int) pv_ptr->pv_width
                      , (int) pv_ptr->pv_height
                      , GDK_INTERP_NEAREST
                      , 255                          /* overall_alpha */
                      , (int)l_check_size            /* power of 2 required */
                      , PREVIEW_BG_GRAY1_GDK
                      , PREVIEW_BG_GRAY2_GDK
                      );
  if(gap_debug)
  {
    int nchannels;
    int rowstride;
    int width;
    int height;
    guchar *pix_data;
    gboolean has_alpha;

    width = gdk_pixbuf_get_width(pv_ptr->pixbuf);
    height = gdk_pixbuf_get_height(pv_ptr->pixbuf);
    nchannels = gdk_pixbuf_get_n_channels(pv_ptr->pixbuf);
    pix_data = gdk_pixbuf_get_pixels(pv_ptr->pixbuf);
    has_alpha = gdk_pixbuf_get_has_alpha(pv_ptr->pixbuf);
    rowstride = gdk_pixbuf_get_rowstride(pv_ptr->pixbuf);

    printf("gap_pview_render_f_from_pixbuf (AFTER SCALE/FLATTEN):\n");
    printf(" l_check_size: %d (%d)\n", (int)l_check_size, pv_ptr->pv_check_size);
    printf(" width: %d\n", (int)width );
    printf(" height: %d\n", (int)height );
    printf(" nchannels: %d\n", (int)nchannels );
    printf(" pix_data: %d\n", (int)pix_data );
    printf(" has_alpha: %d\n", (int)has_alpha );
    printf(" rowstride: %d\n", (int)rowstride );
  }

  {
    gint32 l_flip_to_perform;
  
    l_flip_to_perform = p_calculate_flip_request(pv_ptr, flip_request, flip_status);
    if(l_flip_to_perform != GAP_STB_FLIP_NONE)
    {
      p_replace_pixbuf_by_flipped_pixbuf(pv_ptr, l_flip_to_perform);
    }
  }

  gap_pview_repaint(pv_ptr);

}       /* end gap_pview_render_f_from_pixbuf */
Example #24
0
static void
render_compact (EABContactFormatter *formatter,
                EContact *contact,
                GString *buffer)
{
	const gchar *str;
	gchar *html;
	EContactPhoto *photo;

	g_string_append (buffer, HTML_HEADER);
	g_string_append (buffer,"<body class=\"-e-web-view-background-color -e-web-view-text-color\">");

	if (contact == NULL) {
		g_string_append (buffer, "</body></html>");
		return;
	}

	g_string_append_printf (
		buffer,
		"<table><tr><td valign=\"top\">");

	photo = e_contact_get (contact, E_CONTACT_PHOTO);

	if (photo == NULL)
		photo = e_contact_get (contact, E_CONTACT_LOGO);

	if (photo != NULL) {
		gint calced_width = MAX_COMPACT_IMAGE_DIMENSION;
		gint calced_height = MAX_COMPACT_IMAGE_DIMENSION;
		GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
		GdkPixbuf *pixbuf;

		/* figure out if we need to downscale the
		 * image here.  we don't scale the pixbuf
		 * itself, just insert width/height tags in
		 * the html */
		if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
			gdk_pixbuf_loader_write (
				loader, photo->data.inlined.data,
				photo->data.inlined.length, NULL);
		} else if (photo->type == E_CONTACT_PHOTO_TYPE_URI &&
				photo->data.uri &&
				g_ascii_strncasecmp (photo->data.uri, "file://", 7) == 0) {
			gchar *filename, *contents = NULL;
			gsize length;

			filename = g_filename_from_uri (photo->data.uri, NULL, NULL);

			if (filename) {
				if (g_file_get_contents (filename, &contents, &length, NULL)) {
					gdk_pixbuf_loader_write (loader, (const guchar *) contents, length, NULL);
					g_free (contents);
				}

				g_free (filename);
			}
		}

		gdk_pixbuf_loader_close (loader, NULL);
		pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);

		if (pixbuf)
			g_object_ref (pixbuf);

		g_object_unref (loader);

		if (pixbuf) {
			gint max_dimension;

			calced_width = gdk_pixbuf_get_width (pixbuf);
			calced_height = gdk_pixbuf_get_height (pixbuf);

			max_dimension = calced_width;

			if (max_dimension < calced_height)
				max_dimension = calced_height;

			if (max_dimension > MAX_COMPACT_IMAGE_DIMENSION) {
				calced_width *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension);
				calced_height *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension);
			}

			g_object_unref (pixbuf);
		}

		if (photo->type == E_CONTACT_PHOTO_TYPE_URI &&
			photo->data.uri && *photo->data.uri) {
			gboolean is_local = g_str_has_prefix (photo->data.uri, "file://");
			const gchar *uri = photo->data.uri;
			/* WebKit 2.2.x doesn't re-escape URIs, thus do this for versions before and after this */
			#if !(WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION == 2)
			gchar *unescaped = g_uri_unescape_string (uri, NULL);
			uri = unescaped;
			#endif
			g_string_append_printf (
				buffer,
				"<img id=\"__evo-contact-photo\" width=\"%dpx\" height=\"%dpx\" src=\"%s%s\">",
				calced_width, calced_height,
				is_local ? "evo-" : "", uri);
			#if !(WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION == 2)
			g_free (unescaped);
			#endif
		} else {
			gchar *photo_data;

			photo_data = g_base64_encode (
					photo->data.inlined.data,
					photo->data.inlined.length);
			g_string_append_printf (
				buffer,
				"<img id=\"__evo-contact-photo\" border=\"1\" src=\"data:%s;base64,%s\" "
					"width=\"%dpx\" height=\"%dpx\">",
				photo->data.inlined.mime_type,
				photo_data,
				calced_width, calced_height);
				g_free (photo_data);
		}

		e_contact_photo_free (photo);
	}

	g_string_append (buffer, "</td><td width=\"5\"></td><td valign=\"top\">\n");

	str = e_contact_get_const (contact, E_CONTACT_FILE_AS);

	if (str) {
		html = e_text_to_html (str, 0);
		g_string_append_printf (buffer, "<b>%s</b>", html);
		g_free (html);
	} else {
		str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);

		if (str) {
			html = e_text_to_html (str, 0);
			g_string_append_printf (buffer, "<b>%s</b>", html);
			g_free (html);
		}
	}

	g_string_append (buffer, "<hr>");

	if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
		GList *email_list;
		GList *l;

		g_string_append (
			buffer,
			"<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
			"<tr><td valign=\"top\">");
		g_string_append_printf (
			buffer,
			"<b>%s:</b>&nbsp;<td>", _ ("List Members"));

		email_list = e_contact_get (contact, E_CONTACT_EMAIL);

		for (l = email_list; l; l = l->next) {
			if (l->data) {
				html = e_text_to_html (l->data, 0);
				g_string_append_printf (buffer, "%s, ", html);
				g_free (html);
			}
		}

		g_list_free_full (email_list, g_free);

		g_string_append (buffer, "</td></tr></table>");

	} else {

		gboolean comma = FALSE;
		str = e_contact_get_const (contact, E_CONTACT_TITLE);

		if (str) {
			html = e_text_to_html (str, 0);
			g_string_append_printf (buffer, "<b>%s:</b> %s<br>", _ ("Job Title"), str);
			g_free (html);
		}

		#define print_email() { \
			html = eab_parse_qp_email_to_html (str); \
 \
			if (!html) \
				html = e_text_to_html (str, 0); \
 \
			g_string_append_printf (buffer, "%s%s", comma ? ", " : "", html); \
			g_free (html); \
			comma = TRUE; \
		}

		g_string_append_printf (buffer, "<b>%s:</b> ", _ ("Email"));
		str = e_contact_get_const (contact, E_CONTACT_EMAIL_1);

		if (str)
			print_email ();

		str = e_contact_get_const (contact, E_CONTACT_EMAIL_2);

		if (str)
			print_email ();

		str = e_contact_get_const (contact, E_CONTACT_EMAIL_3);

		if (str)
			print_email ();

		g_string_append (buffer, "<br>");

		#undef print_email

		str = e_contact_get_const (contact, E_CONTACT_HOMEPAGE_URL);

		if (str) {
			html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
			g_string_append_printf (
				buffer, "<b>%s:</b> %s<br>",
				_ ("Home page"), html);
			g_free (html);
		}

		str = e_contact_get_const (contact, E_CONTACT_BLOG_URL);

		if (str) {
			html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
			g_string_append_printf (
				buffer, "<b>%s:</b> %s<br>",
				_ ("Blog"), html);
		}
	}

	g_string_append (buffer, "</td></tr></table>\n");

	g_string_append (buffer, "</body></html>\n");
}
Example #25
0
static void
gimp_view_renderer_real_draw (GimpViewRenderer *renderer,
                              GtkWidget        *widget,
                              cairo_t          *cr,
                              gint              available_width,
                              gint              available_height)
{
  if (renderer->needs_render)
    GIMP_VIEW_RENDERER_GET_CLASS (renderer)->render (renderer, widget);

  if (renderer->pixbuf)
    {
      gint  width  = gdk_pixbuf_get_width  (renderer->pixbuf);
      gint  height = gdk_pixbuf_get_height (renderer->pixbuf);
      gint  x, y;

      if (renderer->bg_icon_name)
        {
          if (! renderer->pattern)
            {
              renderer->pattern = gimp_view_renderer_create_background (renderer,
                                                                        widget);
            }

          cairo_set_source (cr, renderer->pattern);
          cairo_paint (cr);
        }

      x = (available_width  - width)  / 2;
      y = (available_height - height) / 2;

      gdk_cairo_set_source_pixbuf (cr, renderer->pixbuf, x, y);
      cairo_rectangle (cr, x, y, width, height);
      cairo_fill (cr);
    }
  else if (renderer->surface)
    {
      cairo_content_t content  = cairo_surface_get_content (renderer->surface);
      gint            width    = renderer->width;
      gint            height   = renderer->height;
      gint            offset_x = (available_width  - width)  / 2;
      gint            offset_y = (available_height - height) / 2;

      cairo_translate (cr, offset_x, offset_y);

      cairo_rectangle (cr, 0, 0, width, height);

      if (content == CAIRO_CONTENT_COLOR_ALPHA)
        {
          if (! renderer->pattern)
            renderer->pattern =
              gimp_cairo_checkerboard_create (cr, GIMP_CHECK_SIZE_SM,
                                              gimp_render_light_check_color (),
                                              gimp_render_dark_check_color ());

          cairo_set_source (cr, renderer->pattern);
          cairo_fill_preserve (cr);
        }

      cairo_set_source_surface (cr, renderer->surface, 0, 0);
      cairo_fill (cr);

      cairo_translate (cr, - offset_x, - offset_y);
    }
}
Example #26
0
static gboolean
avatar_image_button_press_event (GtkWidget *widget, GdkEventButton *event)
{
	EmpathyAvatarImagePriv *priv;
	GtkWidget             *popup;
	GtkWidget             *frame;
	GtkWidget             *image;
	gint                   x, y;
	gint                   popup_width, popup_height;
	gint                   width, height;
	GdkPixbuf             *pixbuf;
	GtkAllocation          allocation;

	priv = GET_PRIV (widget);

	if (priv->popup) {
		gtk_widget_destroy (priv->popup);
		priv->popup = NULL;
	}

	if (event->button != 1 || event->type != GDK_BUTTON_PRESS || !priv->pixbuf) {
		return FALSE;
	}

	popup_width = gdk_pixbuf_get_width (priv->pixbuf);
	popup_height = gdk_pixbuf_get_height (priv->pixbuf);

	gtk_widget_get_allocation (priv->image, &allocation);
	width = allocation.width;
	height = allocation.height;

	/* Don't show a popup if the popup is smaller then the currently avatar
	 * image.
	 */
	if (popup_height <= height && popup_width <= width) {
		return TRUE;
	}

	pixbuf = tpaw_pixbuf_scale_down_if_necessary (priv->pixbuf, MAX_LARGE);
	popup_width = gdk_pixbuf_get_width (pixbuf);
	popup_height = gdk_pixbuf_get_height (pixbuf);

	popup = gtk_window_new (GTK_WINDOW_POPUP);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);

	gtk_container_add (GTK_CONTAINER (popup), frame);

	image = gtk_image_new ();
	gtk_container_add (GTK_CONTAINER (frame), image);

	gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
	g_object_unref (pixbuf);

	gdk_window_get_origin (gtk_widget_get_window (priv->image), &x, &y);

	x = x - (popup_width - width) / 2;
	y = y - (popup_height - height) / 2;

	gtk_window_move (GTK_WINDOW (popup), x, y);

	priv->popup = popup;

	gtk_widget_show_all (popup);

	return TRUE;
}
Example #27
0
/**
 * gd_create_collection_icon:
 * @base_size:
 * @pixbufs: (element-type GdkPixbuf):
 *
 * Returns: (transfer full):
 */
GIcon *
gd_create_collection_icon (gint base_size,
                           GList *pixbufs)
{
  cairo_surface_t *surface;
  GIcon *retval;
  cairo_t *cr;
  GtkStyleContext *context;
  GtkWidgetPath *path;
  gint padding, tile_size, scale_size;
  gint pix_width, pix_height;
  gint idx, cur_x, cur_y;
  GList *l;
  GdkPixbuf *pix;

  /* TODO: do not hardcode 4, but scale to another layout if more
   * pixbufs are provided.
   */

  padding = MAX (floor (base_size / 10), 4);
  tile_size = (base_size - (3 * padding)) / 2;

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

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

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

  gtk_render_background (context, cr,
                         0, 0, base_size, base_size);

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

  while (l != NULL && idx < 4)
    {
      pix = l->data;
      pix_width = gdk_pixbuf_get_width (pix);
      pix_height = gdk_pixbuf_get_height (pix);

      scale_size = MIN (pix_width, pix_height);

      cairo_save (cr);

      cairo_translate (cr, cur_x, cur_y);

      cairo_rectangle (cr, 0, 0,
                       tile_size, tile_size);
      cairo_clip (cr);

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

      cairo_paint (cr);
      cairo_restore (cr);

      if ((idx % 2) == 0)
        {
          cur_x += tile_size + padding;
        }
      else
        {
          cur_x = padding;
          cur_y += tile_size + padding;
        }

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

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

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

  return retval;
}
Example #28
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;
}
Example #29
0
/* This function chooses a gray value for the text color, based on
 * the average luminance of the text area of the splash image.
 */
static gboolean
splash_average_text_area (GimpSplash *splash,
                          GdkPixbuf  *pixbuf,
                          GdkColor   *color)
{
  const guchar *pixels;
  gint          rowstride;
  gint          channels;
  gint          luminance = 0;
  guint         sum[3]    = { 0, 0, 0 };
  GdkRectangle  image     = { 0, 0, 0, 0 };
  GdkRectangle  area      = { 0, 0, 0, 0 };

  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
  g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8, FALSE);

  image.width  = gdk_pixbuf_get_width (pixbuf);
  image.height = gdk_pixbuf_get_height (pixbuf);
  rowstride    = gdk_pixbuf_get_rowstride (pixbuf);
  channels     = gdk_pixbuf_get_n_channels (pixbuf);
  pixels       = gdk_pixbuf_get_pixels (pixbuf);

  splash_position_layouts (splash, "Short text", "Somewhat longer text", &area);
  splash_position_layouts (splash, "", "", NULL);

  if (gdk_rectangle_intersect (&image, &area, &area))
    {
      const gint count = area.width * area.height;
      gint       x, y;

      pixels += area.x * channels;
      pixels += area.y * rowstride;

      for (y = 0; y < area.height; y++)
        {
          const guchar *src = pixels;

          for (x = 0; x < area.width; x++)
            {
              sum[0] += src[0];
              sum[1] += src[1];
              sum[2] += src[2];

              src += channels;
            }

          pixels += rowstride;
        }

      luminance = GIMP_RGB_LUMINANCE (sum[0] / count,
                                      sum[1] / count,
                                      sum[2] / count);

      luminance = CLAMP0255 (luminance > 127 ?
                             luminance - 223 : luminance + 223);

    }

  color->red = color->green = color->blue = (luminance << 8 | luminance);

  return gdk_colormap_alloc_color (gtk_widget_get_colormap (splash->area),
                                   color, FALSE, TRUE);
}
Example #30
0
/*
 * Same as display_image but for the dataset
 * The imagelist contains the list of images to be displayed when this dataset is selected
 */
static void
display_image_set(gchar *imagename, GSList *imagelist)
{
  GdkPixbuf *pixmap = NULL;
  GooCanvasItem *item;
  GooCanvasItem *rootitem_set;
  double xratio, yratio;
  double iw, ih;

  if (imagename == NULL || !images_selector_displayed)
    return;

  pixmap = gc_pixmap_load_or_null(imagename);
  if (!pixmap)
    return;

  iw = LIST_IMAGE_WIDTH * gc_zoom_factor_get();
  ih = LIST_IMAGE_HEIGHT * gc_zoom_factor_get();

  /* Calc the max to resize width or height */
  xratio = (double) ((iw/(double)gdk_pixbuf_get_width(pixmap)));
  yratio = (double) ((ih/(double)gdk_pixbuf_get_height(pixmap)));
  xratio = MIN(yratio, xratio);

  item = goo_canvas_image_new (goo_canvas_get_root_item(GOO_CANVAS(canvas_list_selector)),
			       pixmap,
			       0,
			       0,
			       NULL);
  goo_canvas_item_translate(item, 5, isy);
  goo_canvas_item_scale(item, xratio, xratio);
#if GDK_PIXBUF_MAJOR <= 2 && GDK_PIXBUF_MINOR <= 24
  gdk_pixbuf_unref(pixmap);
#else
  g_object_unref(pixmap);
#endif
  g_object_set_data (G_OBJECT (item), "imagelist", imagelist);

  g_signal_connect(item, "button_press_event",
		     (GCallback) item_event_imageset_selector,
		     imagename);
  gc_item_focus_init(item, NULL);

  isy += ih + IMAGE_GAP;

  gdouble upper = MAX(isy + ih + IMAGE_GAP,
		      (LIST_AREA_Y2 - LIST_AREA_Y1)
		      * gc_zoom_factor_get());

  goo_canvas_set_bounds (GOO_CANVAS(canvas_list_selector),
			 0, 0,
			 (LIST_AREA_X2 - LIST_AREA_X1)
			 * gc_zoom_factor_get(),
			 upper);

  g_object_set(list_bg_item,
	       "height", upper,
	       NULL);

  g_object_set(list_adj,
	       "upper", upper,
	       NULL);

  /* Create a root item to put the image list in it */
  rootitem_set = \
    goo_canvas_group_new (goo_canvas_get_root_item(GOO_CANVAS(canvas_image_selector)),
			  NULL);

  g_object_set_data (G_OBJECT (item), "rootitem", rootitem_set);
  g_object_set_data (G_OBJECT (item), "imageset_done", GINT_TO_POINTER (0));
  g_object_set_data_full (G_OBJECT (item), "imagelist",
			  imagelist, (GDestroyNotify)free_stuff );
}