static gboolean gimp_color_profile_can_gegl_copy (GimpColorProfile *src_profile, GimpColorProfile *dest_profile) { static GimpColorProfile *srgb_profile = NULL; static GimpColorProfile *srgb_linear_profile = NULL; static GimpColorProfile *gray_profile = NULL; static GimpColorProfile *gray_linear_profile = NULL; if (gimp_color_profile_is_equal (src_profile, dest_profile)) return TRUE; if (! srgb_profile) { srgb_profile = gimp_color_profile_new_rgb_srgb (); srgb_linear_profile = gimp_color_profile_new_rgb_srgb_linear (); gray_profile = gimp_color_profile_new_gray_srgb (); gray_linear_profile = gimp_color_profile_new_gray_srgb_linear (); } if ((gimp_color_profile_is_equal (src_profile, srgb_profile) || gimp_color_profile_is_equal (src_profile, srgb_linear_profile) || gimp_color_profile_is_equal (src_profile, gray_profile) || gimp_color_profile_is_equal (src_profile, gray_linear_profile)) && (gimp_color_profile_is_equal (dest_profile, srgb_profile) || gimp_color_profile_is_equal (dest_profile, srgb_linear_profile) || gimp_color_profile_is_equal (dest_profile, gray_profile) || gimp_color_profile_is_equal (dest_profile, gray_linear_profile))) return TRUE; return FALSE; }
static GimpColorProfile * get_display_profile (GtkWidget *widget, GimpColorConfig *config) { GimpColorProfile *profile = NULL; if (gimp_color_config_get_display_profile_from_gdk (config)) /* get the toplevel's profile so all a window's colors look the same */ profile = gimp_widget_get_color_profile (gtk_widget_get_toplevel (widget)); if (! profile) profile = gimp_color_config_get_display_color_profile (config, NULL); if (! profile) profile = gimp_color_profile_new_rgb_srgb (); return profile; }
static void gimp_fg_bg_view_create_transform (GimpFgBgView *view) { if (view->color_config) { static GimpColorProfile *profile = NULL; if (G_UNLIKELY (! profile)) profile = gimp_color_profile_new_rgb_srgb (); view->transform = gimp_widget_get_color_transform (GTK_WIDGET (view), view->color_config, profile, babl_format ("R'G'B'A double"), babl_format ("R'G'B'A double")); } }
GimpBuffer * gimp_buffer_new_from_pixbuf (GdkPixbuf *pixbuf, const gchar *name, gint offset_x, gint offset_y) { GimpBuffer *gimp_buffer; GeglBuffer *buffer; guint8 *icc_data; gsize icc_len; GimpColorProfile *profile = NULL; g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); g_return_val_if_fail (name != NULL, NULL); buffer = gimp_pixbuf_create_buffer (pixbuf); gimp_buffer = gimp_buffer_new (buffer, name, offset_x, offset_y, FALSE); icc_data = gimp_pixbuf_get_icc_profile (pixbuf, &icc_len); if (icc_data) { profile = gimp_color_profile_new_from_icc_profile (icc_data, icc_len, NULL); g_free (icc_data); } if (! profile && gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB) { profile = gimp_color_profile_new_rgb_srgb (); } if (profile) { gimp_buffer_set_color_profile (gimp_buffer, profile); g_object_unref (profile); } g_object_unref (buffer); return gimp_buffer; }
/** * gimp_color_transform_can_gegl_copy: * @src_format: src profile * @dest_format: dest profile * * This function checks if a GimpColorTransform is needed at all. * * Return value: %TRUE if pixels can be correctly converted between * @src_profile and @dest_profile by simply using * gegl_buffer_copy(), babl_process() or similar. * * Since: 2.10 **/ gboolean gimp_color_transform_can_gegl_copy (GimpColorProfile *src_profile, GimpColorProfile *dest_profile) { static GimpColorProfile *srgb_profile = NULL; static GimpColorProfile *srgb_linear_profile = NULL; static GimpColorProfile *gray_profile = NULL; static GimpColorProfile *gray_linear_profile = NULL; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), FALSE); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), FALSE); if (gimp_color_profile_is_equal (src_profile, dest_profile)) return TRUE; if (! srgb_profile) { srgb_profile = gimp_color_profile_new_rgb_srgb (); srgb_linear_profile = gimp_color_profile_new_rgb_srgb_linear (); gray_profile = gimp_color_profile_new_d65_gray_srgb_trc (); gray_linear_profile = gimp_color_profile_new_d65_gray_linear (); } if ((gimp_color_profile_is_equal (src_profile, srgb_profile) || gimp_color_profile_is_equal (src_profile, srgb_linear_profile) || gimp_color_profile_is_equal (src_profile, gray_profile) || gimp_color_profile_is_equal (src_profile, gray_linear_profile)) && (gimp_color_profile_is_equal (dest_profile, srgb_profile) || gimp_color_profile_is_equal (dest_profile, srgb_linear_profile) || gimp_color_profile_is_equal (dest_profile, gray_profile) || gimp_color_profile_is_equal (dest_profile, gray_linear_profile))) { return TRUE; } return FALSE; }
static GdkPixbuf * gimp_buffer_get_new_pixbuf (GimpViewable *viewable, GimpContext *context, gint width, gint height) { GimpBuffer *buffer = GIMP_BUFFER (viewable); GdkPixbuf *pixbuf; gdouble scale; pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); scale = MIN ((gdouble) width / (gdouble) gimp_buffer_get_width (buffer), (gdouble) height / (gdouble) gimp_buffer_get_height (buffer)); if (buffer->color_profile) { GimpColorProfile *srgb_profile; GimpTempBuf *temp_buf; GeglBuffer *src_buf; GeglBuffer *dest_buf; srgb_profile = gimp_color_profile_new_rgb_srgb (); temp_buf = gimp_temp_buf_new (width, height, gimp_buffer_get_format (buffer)); gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), scale, gimp_temp_buf_get_format (temp_buf), gimp_temp_buf_get_data (temp_buf), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP); src_buf = gimp_temp_buf_create_buffer (temp_buf); dest_buf = gimp_pixbuf_create_buffer (pixbuf); gimp_temp_buf_unref (temp_buf); gimp_gegl_convert_color_profile (src_buf, GEGL_RECTANGLE (0, 0, width, height), buffer->color_profile, dest_buf, GEGL_RECTANGLE (0, 0, 0, 0), srgb_profile, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, TRUE, NULL); g_object_unref (src_buf); g_object_unref (dest_buf); g_object_unref (srgb_profile); } else { gegl_buffer_get (buffer->buffer, GEGL_RECTANGLE (0, 0, width, height), scale, gimp_pixbuf_get_format (pixbuf), gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_rowstride (pixbuf), GEGL_ABYSS_CLAMP); } return pixbuf; }
GimpColorProfile * gimp_image_get_builtin_color_profile (GimpImage *image) { static GimpColorProfile *srgb_profile = NULL; static GimpColorProfile *linear_rgb_profile = NULL; static GimpColorProfile *gray_profile = NULL; static GimpColorProfile *linear_gray_profile = NULL; const Babl *format; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); format = gimp_image_get_layer_format (image, FALSE); if (gimp_image_get_base_type (image) == GIMP_GRAY) { if (gimp_babl_format_get_linear (format)) { if (! linear_gray_profile) { linear_gray_profile = gimp_color_profile_new_gray_srgb_linear (); g_object_add_weak_pointer (G_OBJECT (linear_gray_profile), (gpointer) &linear_gray_profile); } return linear_gray_profile; } else { if (! gray_profile) { gray_profile = gimp_color_profile_new_gray_srgb (); g_object_add_weak_pointer (G_OBJECT (gray_profile), (gpointer) &gray_profile); } return gray_profile; } } else { if (gimp_babl_format_get_linear (format)) { if (! linear_rgb_profile) { linear_rgb_profile = gimp_color_profile_new_rgb_srgb_linear (); g_object_add_weak_pointer (G_OBJECT (linear_rgb_profile), (gpointer) &linear_rgb_profile); } return linear_rgb_profile; } else { if (! srgb_profile) { srgb_profile = gimp_color_profile_new_rgb_srgb (); g_object_add_weak_pointer (G_OBJECT (srgb_profile), (gpointer) &srgb_profile); } return srgb_profile; } } }
static void gimp_pick_button_pick (GimpPickButton *button, GdkEvent *event) { GdkScreen *screen = gdk_event_get_screen (event); GimpColorProfile *monitor_profile; GdkMonitor *monitor; GimpRGB rgb; gint x_root; gint y_root; gdouble x_win; gdouble y_win; gdk_window_get_origin (gdk_event_get_window (event), &x_root, &y_root); gdk_event_get_coords (event, &x_win, &y_win); x_root += x_win; y_root += y_win; #ifdef G_OS_WIN32 { HDC hdc; RECT rect; COLORREF win32_color; /* For MS Windows, use native GDI functions to get the pixel, as * cairo does not handle the case where you have multiple monitors * with a monitor on the left or above the primary monitor. That * scenario create a cairo primary surface with negative extent, * which is not handled properly (bug 740634). */ hdc = GetDC (HWND_DESKTOP); GetClipBox (hdc, &rect); win32_color = GetPixel (hdc, x_root + rect.left, y_root + rect.top); ReleaseDC (HWND_DESKTOP, hdc); gimp_rgba_set_uchar (&rgb, GetRValue (win32_color), GetGValue (win32_color), GetBValue (win32_color), 255); } #else { GdkWindow *window; gint x_window; gint y_window; cairo_surface_t *image; cairo_t *cr; guchar *data; guchar color[3]; /* we try to pick from the local window under the cursor, and fall * back to picking from the root window if this fails (i.e., if * the cursor is not under a local window). on wayland, picking * from the root window is not supported, so this at least allows * us to pick from local windows. see bug #780375. */ window = gdk_device_get_window_at_position (gdk_event_get_device (event), &x_window, &y_window); if (! window) { window = gdk_screen_get_root_window (screen); x_window = x_root; y_window = y_root; } image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1); cr = cairo_create (image); gdk_cairo_set_source_window (cr, window, -x_window, -y_window); cairo_paint (cr); cairo_destroy (cr); data = cairo_image_surface_get_data (image); GIMP_CAIRO_RGB24_GET_PIXEL (data, color[0], color[1], color[2]); cairo_surface_destroy (image); gimp_rgba_set_uchar (&rgb, color[0], color[1], color[2], 255); } #endif monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), x_root, y_root); monitor_profile = gimp_monitor_get_color_profile (monitor); if (monitor_profile) { GimpColorProfile *srgb_profile; GimpColorTransform *transform; const Babl *format; GimpColorTransformFlags flags = 0; format = babl_format ("R'G'B'A double"); flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; srgb_profile = gimp_color_profile_new_rgb_srgb (); transform = gimp_color_transform_new (monitor_profile, format, srgb_profile, format, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, flags); g_object_unref (srgb_profile); if (transform) { gimp_color_transform_process_pixels (transform, format, &rgb, format, &rgb, 1); gimp_rgb_clamp (&rgb); g_object_unref (transform); } } g_signal_emit_by_name (button, "color-picked", &rgb); }