static gboolean apply_color(color_settings settings, image_output out) { gboolean success = TRUE; int default_drawable = out->drawable_ids[0]; if (settings->brightness != 0 || settings->contrast != 0) { // brightness or contrast have been modified, apply the manipulation if (!gimp_drawable_is_rgb(default_drawable)) { gimp_image_convert_rgb(out->image_id); } int i; for (i = 0; i < out->drawable_count; i++) { success = gimp_brightness_contrast( out->drawable_ids[i], settings->brightness, settings->contrast ); } } if (settings->grayscale && !gimp_drawable_is_gray(default_drawable)) { // do grayscale conversion success = gimp_image_convert_grayscale(out->image_id); } if (settings->levels_auto) { // do levels correction int i; for (i = 0; i < out->drawable_count; i++) { success = gimp_levels_stretch(out->drawable_ids[i]); } } if (settings->curve_file != NULL && !gimp_drawable_is_indexed(default_drawable)) { // apply curve if (!colorcurve_init) { // read from the curve file only the first time success = parse_curve_file( settings->curve_file, &colorcurve_num_points_v, &colorcurve_ctr_points_v, &colorcurve_num_points_r, &colorcurve_ctr_points_r, &colorcurve_num_points_g, &colorcurve_ctr_points_g, &colorcurve_num_points_b, &colorcurve_ctr_points_b, &colorcurve_num_points_a, &colorcurve_ctr_points_a ); colorcurve_init = TRUE; } else success = TRUE; if (success) { int i; for (i = 0; i < out->drawable_count; i++) { if (colorcurve_num_points_v >= 4 && colorcurve_num_points_v <= 34) { success = gimp_curves_spline(out->drawable_ids[i], GIMP_HISTOGRAM_VALUE, colorcurve_num_points_v, colorcurve_ctr_points_v); } if (colorcurve_num_points_r >= 4 && colorcurve_num_points_r <= 34) { success = gimp_curves_spline(out->drawable_ids[i], GIMP_HISTOGRAM_RED, colorcurve_num_points_r, colorcurve_ctr_points_r); } if (colorcurve_num_points_g >= 4 && colorcurve_num_points_g <= 34) { success = gimp_curves_spline(out->drawable_ids[i], GIMP_HISTOGRAM_GREEN, colorcurve_num_points_g, colorcurve_ctr_points_g); } if (colorcurve_num_points_b >= 4 && colorcurve_num_points_b <= 34) { success = gimp_curves_spline(out->drawable_ids[i], GIMP_HISTOGRAM_BLUE, colorcurve_num_points_b, colorcurve_ctr_points_b); } if (colorcurve_num_points_a >= 4 && colorcurve_num_points_a <= 34) { success = gimp_curves_spline(out->drawable_ids[i], GIMP_HISTOGRAM_ALPHA, colorcurve_num_points_a, colorcurve_ctr_points_a); } } } } return success; }
static void ico_dialog_update_icon_preview (GtkWidget *dialog, gint32 layer, gint bpp) { GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer); GdkPixbuf *pixbuf; gint w = gimp_drawable_width (layer); gint h = gimp_drawable_height (layer); if (! preview) return; if (bpp <= 8) { GimpDrawable *drawable; GimpDrawable *tmp; GimpPixelRgn src_pixel_rgn, dst_pixel_rgn; gint32 image; gint32 tmp_image; gint32 tmp_layer; guchar *buffer; guchar *cmap; gint num_colors; image = gimp_item_get_image (layer); tmp_image = gimp_image_new (w, h, gimp_image_base_type (image)); gimp_image_undo_disable (tmp_image); if (gimp_drawable_is_indexed (layer)) { cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); g_free (cmap); } tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h, gimp_drawable_type (layer), 100, GIMP_NORMAL_MODE); gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0); drawable = gimp_drawable_get (layer); tmp = gimp_drawable_get (tmp_layer); gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE); gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, TRUE, FALSE); buffer = g_malloc (w * h * 4); gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h); gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h); gimp_drawable_detach (tmp); gimp_drawable_detach (drawable); if (gimp_drawable_is_indexed (layer)) gimp_image_convert_rgb (tmp_image); gimp_image_convert_indexed (tmp_image, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, 1 <<bpp, TRUE, FALSE, "dummy"); cmap = gimp_image_get_colormap (tmp_image, &num_colors); if ( num_colors == (1 << bpp) && !ico_cmap_contains_black (cmap, num_colors)) { /* Windows icons with color maps need the color black. * We need to eliminate one more color to make room for black. */ if (gimp_drawable_is_indexed (layer)) { g_free (cmap); cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); } else if (gimp_drawable_is_gray (layer)) { gimp_image_convert_grayscale (tmp_image); } else { gimp_image_convert_rgb (tmp_image); } tmp = gimp_drawable_get (tmp_layer); gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, TRUE, FALSE); gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h); gimp_drawable_detach (tmp); if (!gimp_drawable_is_rgb (layer)) gimp_image_convert_rgb (tmp_image); gimp_image_convert_indexed (tmp_image, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, (1<<bpp) - 1, TRUE, FALSE, "dummy"); } g_free (cmap); g_free (buffer); pixbuf = gimp_drawable_get_thumbnail (tmp_layer, MIN (w, 128), MIN (h, 128), GIMP_PIXBUF_SMALL_CHECKS); gimp_image_delete (tmp_image); } else if (bpp == 24) { GimpDrawable *drawable; GimpDrawable *tmp; GimpPixelRgn src_pixel_rgn, dst_pixel_rgn; gint32 image; gint32 tmp_image; gint32 tmp_layer; guchar *buffer; GimpParam *return_vals; gint n_return_vals; image = gimp_item_get_image (layer); tmp_image = gimp_image_new (w, h, gimp_image_base_type (image)); gimp_image_undo_disable (tmp_image); if (gimp_drawable_is_indexed (layer)) { guchar *cmap; gint num_colors; cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); g_free (cmap); } tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h, gimp_drawable_type (layer), 100, GIMP_NORMAL_MODE); gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0); drawable = gimp_drawable_get (layer); tmp = gimp_drawable_get (tmp_layer); gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE); gimp_pixel_rgn_init (&dst_pixel_rgn, tmp, 0, 0, w, h, TRUE, FALSE); buffer = g_malloc (w * h * 4); gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h); gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h); g_free (buffer); gimp_drawable_detach (tmp); gimp_drawable_detach (drawable); if (gimp_drawable_is_indexed (layer)) gimp_image_convert_rgb (tmp_image); return_vals = gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals, GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE, GIMP_PDB_IMAGE, tmp_image, GIMP_PDB_DRAWABLE, tmp_layer, GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD, GIMP_PDB_END); gimp_destroy_params (return_vals, n_return_vals); pixbuf = gimp_drawable_get_thumbnail (tmp_layer, MIN (w, 128), MIN (h, 128), GIMP_PIXBUF_SMALL_CHECKS); gimp_image_delete (tmp_image); } else { pixbuf = gimp_drawable_get_thumbnail (layer, MIN (w, 128), MIN (h, 128), GIMP_PIXBUF_SMALL_CHECKS); } gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf); g_object_unref (pixbuf); }
static void ico_image_get_reduced_buf (guint32 layer, gint bpp, gint *num_colors, guchar **cmap_out, guchar **buf_out) { gint32 tmp_image; gint32 tmp_layer; gint w, h; guchar *buf; guchar *cmap = NULL; GeglBuffer *buffer = gimp_drawable_get_buffer (layer); const Babl *format; w = gegl_buffer_get_width (buffer); h = gegl_buffer_get_height (buffer); switch (gimp_drawable_type (layer)) { case GIMP_RGB_IMAGE: format = babl_format ("R'G'B' u8"); break; case GIMP_RGBA_IMAGE: format = babl_format ("R'G'B'A u8"); break; case GIMP_GRAY_IMAGE: format = babl_format ("Y' u8"); break; case GIMP_GRAYA_IMAGE: format = babl_format ("Y'A u8"); break; case GIMP_INDEXED_IMAGE: case GIMP_INDEXEDA_IMAGE: format = gegl_buffer_get_format (buffer); default: g_return_if_reached (); } *num_colors = 0; buf = g_new (guchar, w * h * 4); if (bpp <= 8 || bpp == 24 || babl_format_get_bytes_per_pixel (format) != 4) { gint32 image = gimp_item_get_image (layer); GeglBuffer *tmp; tmp_image = gimp_image_new (w, h, gimp_image_base_type (image)); gimp_image_undo_disable (tmp_image); if (gimp_drawable_is_indexed (layer)) { guchar *cmap; gint num_colors; cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); g_free (cmap); } tmp_layer = gimp_layer_new (tmp_image, "tmp", w, h, gimp_drawable_type (layer), 100, GIMP_NORMAL_MODE); gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0); tmp = gimp_drawable_get_buffer (tmp_layer); gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format, buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, tmp, NULL); g_object_unref (tmp); if (! gimp_drawable_is_rgb (tmp_layer)) gimp_image_convert_rgb (tmp_image); if (bpp <= 8) { gimp_image_convert_indexed (tmp_image, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, 1 << bpp, TRUE, FALSE, "dummy"); cmap = gimp_image_get_colormap (tmp_image, num_colors); if (*num_colors == (1 << bpp) && ! ico_cmap_contains_black (cmap, *num_colors)) { /* Windows icons with color maps need the color black. * We need to eliminate one more color to make room for black. */ if (gimp_drawable_is_indexed (layer)) { g_free (cmap); cmap = gimp_image_get_colormap (image, num_colors); gimp_image_set_colormap (tmp_image, cmap, *num_colors); } else if (gimp_drawable_is_gray (layer)) { gimp_image_convert_grayscale (tmp_image); } else { gimp_image_convert_rgb (tmp_image); } tmp = gimp_drawable_get_buffer (tmp_layer); gegl_buffer_set (tmp, GEGL_RECTANGLE (0, 0, w, h), 0, format, buf, GEGL_AUTO_ROWSTRIDE); g_object_unref (tmp); if (! gimp_drawable_is_rgb (layer)) gimp_image_convert_rgb (tmp_image); gimp_image_convert_indexed (tmp_image, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, (1<<bpp) - 1, TRUE, FALSE, "dummy"); g_free (cmap); cmap = gimp_image_get_colormap (tmp_image, num_colors); } gimp_image_convert_rgb (tmp_image); } else if (bpp == 24) { GimpParam *return_vals; gint n_return_vals; return_vals = gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals, GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE, GIMP_PDB_IMAGE, tmp_image, GIMP_PDB_DRAWABLE, tmp_layer, GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD, GIMP_PDB_END); gimp_destroy_params (return_vals, n_return_vals); } gimp_layer_add_alpha (tmp_layer); tmp = gimp_drawable_get_buffer (tmp_layer); gegl_buffer_get (tmp, GEGL_RECTANGLE (0, 0, w, h), 1.0, NULL, buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); g_object_unref (tmp); gimp_image_delete (tmp_image); } else { gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format, buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); } g_object_unref (buffer); *cmap_out = cmap; *buf_out = buf; }
static void export_convert_grayscale (gint32 image_ID, gint32 *drawable_ID) { gimp_image_convert_grayscale (image_ID); }
/* ------------------------------------------------------- * gap_image_set_selection_from_selection_or_drawable * ------------------------------------------------------- * create a selection in the specified image_id. * The selection is a scaled copy of the selection in another image, * referred by ref_drawable_id, or a Grayscale copy of the specified ref_drawable_id * (in case the referred image has no selection or the flag force_from_drawable is TRUE) * * - operates on a duplicate of the image referred by ref_drawable_id. * - this duplicate is scaled to same size as specified image_id * * return TRUE in case the selection was successfully created . */ gboolean gap_image_set_selection_from_selection_or_drawable(gint32 image_id, gint32 ref_drawable_id , gboolean force_from_drawable) { gint32 l_aux_channel_id; gint32 ref_image_id; gint32 work_drawable_id; /* the duplicate of the layer that is used as selction mask */ gint32 dup_image_id; gboolean has_selection; gboolean non_empty; gint x1, y1, x2, y2; if ((image_id < 0) || (ref_drawable_id < 0)) { return (FALSE); } ref_image_id = gimp_item_get_image(ref_drawable_id); if (ref_image_id < 0) { printf("ref_drawable_id does not refer to a valid image layer_id:%d\n", (int)ref_drawable_id); return (FALSE); } dup_image_id = gimp_image_duplicate(ref_image_id); if (dup_image_id < 0) { printf("duplicating of image failed, referred souce image_id:%d\n", (int)ref_image_id); return (FALSE); } /* clear undo stack */ if (gimp_image_undo_is_enabled(dup_image_id)) { gimp_image_undo_disable(dup_image_id); } if ((gimp_image_width(image_id) != gimp_image_width(dup_image_id)) || (gimp_image_height(image_id) != gimp_image_height(dup_image_id))) { if(gap_debug) { printf("scaling tmp image_id: %d\n", (int)dup_image_id); } gimp_image_scale(dup_image_id, gimp_image_width(image_id), gimp_image_height(image_id)); } has_selection = gimp_selection_bounds(ref_image_id, &non_empty, &x1, &y1, &x2, &y2); if ((has_selection) && (non_empty) && (force_from_drawable != TRUE)) { /* use scaled copy of the already exisating selection in the referred image */ work_drawable_id = gimp_image_get_selection(dup_image_id); } else { gint32 active_layer_stackposition; /* create selection as gray copy of the alt_selection layer */ active_layer_stackposition = gap_layer_get_stackposition(ref_image_id, ref_drawable_id); if(gimp_image_base_type(dup_image_id) != GIMP_GRAY) { if(gap_debug) { printf("convert to GRAYSCALE tmp image_id: %d\n", (int)dup_image_id); } gimp_image_convert_grayscale(dup_image_id); } work_drawable_id = gap_layer_get_id_by_stackposition(dup_image_id, active_layer_stackposition); gimp_layer_resize_to_image_size (work_drawable_id); } gimp_selection_all(image_id); //l_sel_channel_id = gimp_image_get_selection(image_id); l_aux_channel_id = gimp_selection_save(image_id); /* copy the work drawable (layer or channel) into the selection channel * the work layer is a grayscale copy GRAY or GRAYA of the alt_selection layer * that is already scaled and resized to fit the size of the target image * the work channel is the scaled selection of the image refred by ref_drawable_id * * copying is done into an auxiliary channel from where we regulary load the selection. * this is done because subseqent queries of the selection boudaries will deliver * full channel size rectangle after a direct copy into the selection. */ gap_layer_copy_picked_channel (l_aux_channel_id /* dst_drawable_id*/ , 0 /* dst_channel_pick */ , work_drawable_id /* src_drawable_id */ , 0 /* src_channel_pick */ , FALSE /* gboolean shadow */ ); gimp_image_select_item(image_id, GIMP_CHANNEL_OP_REPLACE, l_aux_channel_id); gimp_image_remove_channel(image_id, l_aux_channel_id); gap_image_delete_immediate(dup_image_id); return (TRUE); } /* end gap_image_set_selection_from_selection_or_drawable */
static void ico_dialog_update_icon_preview (GtkWidget *dialog, gint32 layer, gint bpp) { GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer); GdkPixbuf *pixbuf; const Babl *format; gint w = gimp_drawable_width (layer); gint h = gimp_drawable_height (layer); if (! preview) return; switch (gimp_drawable_type (layer)) { case GIMP_RGB_IMAGE: format = babl_format ("R'G'B' u8"); break; case GIMP_RGBA_IMAGE: format = babl_format ("R'G'B'A u8"); break; case GIMP_GRAY_IMAGE: format = babl_format ("Y' u8"); break; case GIMP_GRAYA_IMAGE: format = babl_format ("Y'A u8"); break; case GIMP_INDEXED_IMAGE: case GIMP_INDEXEDA_IMAGE: format = gimp_drawable_get_format (layer); default: g_return_if_reached (); } if (bpp <= 8) { GeglBuffer *buffer; GeglBuffer *tmp; gint32 image; gint32 tmp_image; gint32 tmp_layer; guchar *buf; guchar *cmap; gint num_colors; image = gimp_item_get_image (layer); tmp_image = gimp_image_new (w, h, gimp_image_base_type (image)); gimp_image_undo_disable (tmp_image); if (gimp_drawable_is_indexed (layer)) { cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); g_free (cmap); } tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h, gimp_drawable_type (layer), 100, GIMP_NORMAL_MODE); gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0); buffer = gimp_drawable_get_buffer (layer); tmp = gimp_drawable_get_buffer (tmp_layer); buf = g_malloc (w * h * 4); gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format, buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); gegl_buffer_copy (buffer, NULL, tmp, NULL); g_object_unref (tmp); g_object_unref (buffer); if (gimp_drawable_is_indexed (layer)) gimp_image_convert_rgb (tmp_image); gimp_image_convert_indexed (tmp_image, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, 1 << bpp, TRUE, FALSE, "dummy"); cmap = gimp_image_get_colormap (tmp_image, &num_colors); if (num_colors == (1 << bpp) && ! ico_cmap_contains_black (cmap, num_colors)) { /* Windows icons with color maps need the color black. * We need to eliminate one more color to make room for black. */ if (gimp_drawable_is_indexed (layer)) { g_free (cmap); cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); } else if (gimp_drawable_is_gray (layer)) { gimp_image_convert_grayscale (tmp_image); } else { gimp_image_convert_rgb (tmp_image); } tmp = gimp_drawable_get_buffer (tmp_layer); gegl_buffer_set (tmp, GEGL_RECTANGLE (0, 0, w, h), 0, format, buf, GEGL_AUTO_ROWSTRIDE); g_object_unref (tmp); if (!gimp_drawable_is_rgb (layer)) gimp_image_convert_rgb (tmp_image); gimp_image_convert_indexed (tmp_image, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, (1 << bpp) - 1, TRUE, FALSE, "dummy"); } g_free (cmap); g_free (buf); pixbuf = gimp_drawable_get_thumbnail (tmp_layer, MIN (w, 128), MIN (h, 128), GIMP_PIXBUF_SMALL_CHECKS); gimp_image_delete (tmp_image); } else if (bpp == 24) { GeglBuffer *buffer; GeglBuffer *tmp; gint32 image; gint32 tmp_image; gint32 tmp_layer; GimpParam *return_vals; gint n_return_vals; image = gimp_item_get_image (layer); tmp_image = gimp_image_new (w, h, gimp_image_base_type (image)); gimp_image_undo_disable (tmp_image); if (gimp_drawable_is_indexed (layer)) { guchar *cmap; gint num_colors; cmap = gimp_image_get_colormap (image, &num_colors); gimp_image_set_colormap (tmp_image, cmap, num_colors); g_free (cmap); } tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h, gimp_drawable_type (layer), 100, GIMP_NORMAL_MODE); gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0); buffer = gimp_drawable_get_buffer (layer); tmp = gimp_drawable_get_buffer (tmp_layer); gegl_buffer_copy (buffer, NULL, tmp, NULL); g_object_unref (tmp); g_object_unref (buffer); if (gimp_drawable_is_indexed (layer)) gimp_image_convert_rgb (tmp_image); return_vals = gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals, GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE, GIMP_PDB_IMAGE, tmp_image, GIMP_PDB_DRAWABLE, tmp_layer, GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD, GIMP_PDB_END); gimp_destroy_params (return_vals, n_return_vals); pixbuf = gimp_drawable_get_thumbnail (tmp_layer, MIN (w, 128), MIN (h, 128), GIMP_PIXBUF_SMALL_CHECKS); gimp_image_delete (tmp_image); } else { pixbuf = gimp_drawable_get_thumbnail (layer, MIN (w, 128), MIN (h, 128), GIMP_PIXBUF_SMALL_CHECKS); } gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf); g_object_unref (pixbuf); }