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); }
/** * 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; }
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; }
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; }
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; }
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); }
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; }
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); }
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; }
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; } }
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; } }
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); } }
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; }
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); } }
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)); }
/*! * \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; }
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(); }
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; }
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; }
/* ------------------------------ * 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 */
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> <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"); }
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); } }
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; }
/** * 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; }
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; }
/* 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); }
/* * 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 ); }