static void normalize (GimpDrawable *drawable) { NormalizeParam_t param; gint x; guchar range; param.min = 255; param.max = 0; param.has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); param.alpha = (param.has_alpha) ? drawable->bpp - 1 : drawable->bpp; gimp_rgn_iterate1 (drawable, 0 /* unused */, find_min_max, ¶m); /* Calculate LUT */ range = param.max - param.min; if (range != 0) for (x = param.min; x <= param.max; x++) param.lut[x] = 255 * (x - param.min) / range; else param.lut[(gint)param.min] = param.min; gimp_rgn_iterate2 (drawable, 0 /* unused */, normalize_func, ¶m); }
static gboolean gimp_threshold_tool_channel_sensitive (gint value, gpointer data) { GimpDrawable *drawable = GIMP_TOOL (data)->drawable; GimpHistogramChannel channel = value; if (!drawable) return FALSE; switch (channel) { case GIMP_HISTOGRAM_VALUE: return TRUE; case GIMP_HISTOGRAM_RED: case GIMP_HISTOGRAM_GREEN: case GIMP_HISTOGRAM_BLUE: return gimp_drawable_is_rgb (drawable); case GIMP_HISTOGRAM_ALPHA: return gimp_drawable_has_alpha (drawable); case GIMP_HISTOGRAM_RGB: return gimp_drawable_is_rgb (drawable); case GIMP_HISTOGRAM_LUMINANCE: return gimp_drawable_is_rgb (drawable); } return FALSE; }
static void gimp_text_layer_render_layout (GimpTextLayer *layer, GimpTextLayout *layout) { GimpDrawable *drawable = GIMP_DRAWABLE (layer); GimpItem *item = GIMP_ITEM (layer); GeglBuffer *buffer; cairo_t *cr; cairo_surface_t *surface; gint width; gint height; g_return_if_fail (gimp_drawable_has_alpha (drawable)); width = gimp_item_get_width (item); height = gimp_item_get_height (item); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE); cairo_destroy (cr); cairo_surface_flush (surface); buffer = gimp_cairo_surface_create_buffer (surface); gegl_buffer_copy (buffer, NULL, gimp_drawable_get_buffer (drawable), NULL); g_object_unref (buffer); cairo_surface_destroy (surface); gimp_drawable_update (drawable, 0, 0, width, height); }
/* This function operates on PixelArea, whose width and height are multiply of pixel width, and less than the tile size (to enhance its speed). If any coordinates of mask boundary is not multiply of pixel width (e.g. x1 % pixelwidth != 0), operates on the region whose width or height is the remainder. */ static void pixelize_small (GimpDrawable *drawable, gint pixelwidth, gint pixelheight, gint tile_width, gint tile_height) { GimpPixelRgn src_rgn, dest_rgn; gint bpp, has_alpha; gint x1, y1, x2, y2; gint progress, max_progress; gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, x2-x1, y2-y1, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2-x1, y2-y1, TRUE, TRUE); /* Initialize progress */ progress = 0; max_progress = (x2 - x1) * (y2 - y1); bpp = drawable->bpp; has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); area.width = (tile_width / pixelwidth) * pixelwidth; area.height = (tile_height / pixelheight) * pixelheight; area.data= g_new (guchar, (glong) bpp * area.width * area.height); for (area.y = y1; area.y < y2; area.y += area.height - (area.y % area.height)) { area.h = area.height - (area.y % area.height); area.h = MIN (area.h, y2 - area.y); for (area.x = x1; area.x < x2; area.x += area.width - (area.x % area.width)) { area.w = area.width - (area.x % area.width); area.w = MIN(area.w, x2 - area.x); gimp_pixel_rgn_get_rect (&src_rgn, area.data, area.x, area.y, area.w, area.h); pixelize_sub (pixelwidth, pixelheight, bpp, has_alpha); gimp_pixel_rgn_set_rect (&dest_rgn, area.data, area.x, area.y, area.w, area.h); /* Update progress */ progress += area.w * area.h; gimp_progress_update ((double) progress / (double) max_progress); } } g_free(area.data); /* update the pixelized region */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); }
gboolean gimp_edit_clear (GimpImage *image, GimpDrawable *drawable, GimpContext *context) { GimpRGB background; GimpLayerModeEffects paint_mode; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE); g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE); gimp_context_get_background (context, &background); if (gimp_drawable_has_alpha (drawable)) paint_mode = GIMP_ERASE_MODE; else paint_mode = GIMP_NORMAL_MODE; return gimp_edit_fill_full (image, drawable, &background, NULL, GIMP_OPACITY_OPAQUE, paint_mode, C_("undo-type", "Clear")); }
static void waves (GimpDrawable *drawable) { GimpPixelRgn srcPr, dstPr; guchar *src, *dst; guint width, height, bpp, has_alpha; width = drawable->width; height = drawable->height; bpp = drawable->bpp; has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); src = g_new (guchar, width * height * bpp); dst = g_new (guchar, width * height * bpp); gimp_pixel_rgn_init (&srcPr, drawable, 0, 0, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&dstPr, drawable, 0, 0, width, height, TRUE, TRUE); gimp_pixel_rgn_get_rect (&srcPr, src, 0, 0, width, height); wave (src, dst, width, height, bpp, has_alpha, width / 2.0, height / 2.0, wvals.amplitude, wvals.wavelength, wvals.phase, wvals.type == MODE_SMEAR, wvals.reflective, TRUE); gimp_pixel_rgn_set_rect (&dstPr, dst, 0, 0, width, height); g_free (src); g_free (dst); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, 0, 0, width, height); gimp_displays_flush (); }
static void compute_image (GimpDrawable *drawable) { GimpDrawable *effect; guchar *scalarfield = NULL; /* Get some useful info on the input drawable */ /* ========================================== */ if (! gimp_drawable_mask_intersect (drawable->drawable_id, &border_x, &border_y, &border_w, &border_h)) return; gimp_progress_init (_("Van Gogh (LIC)")); if (licvals.effect_convolve == 0) generatevectors (); if (licvals.filtlen < 0.1) licvals.filtlen = 0.1; l = licvals.filtlen; dx = dy = licvals.noisemag; minv = licvals.minv / 10.0; maxv = licvals.maxv / 10.0; isteps = licvals.intsteps; source_drw_has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); effect = gimp_drawable_get (licvals.effect_image_id); effect_width = effect->width; effect_height = effect->height; switch (licvals.effect_channel) { case 0: scalarfield = rgb_to_hsl (effect, LIC_HUE); break; case 1: scalarfield = rgb_to_hsl (effect, LIC_SATURATION); break; case 2: scalarfield = rgb_to_hsl (effect, LIC_BRIGHTNESS); break; } compute_lic (drawable, scalarfield, licvals.effect_operator); g_free (scalarfield); /* Update image */ /* ============ */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, border_x, border_y, border_w, border_h); gimp_displays_flush (); }
const Babl * gimp_drawable_get_preview_format (GimpDrawable *drawable) { gboolean alpha; gboolean linear; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); alpha = gimp_drawable_has_alpha (drawable); linear = gimp_drawable_get_linear (drawable); switch (gimp_drawable_get_base_type (drawable)) { case GIMP_GRAY: return gimp_babl_format (GIMP_GRAY, gimp_babl_precision (GIMP_COMPONENT_TYPE_U8, linear), alpha); case GIMP_RGB: return gimp_babl_format (GIMP_RGB, gimp_babl_precision (GIMP_COMPONENT_TYPE_U8, linear), alpha); case GIMP_INDEXED: if (alpha) return babl_format ("R'G'B'A u8"); else return babl_format ("R'G'B' u8"); } g_return_val_if_reached (NULL); }
void gimp_edit_clear (GimpImage *image, GimpDrawable *drawable, GimpContext *context) { GimpFillOptions *options; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_CONTEXT (context)); options = gimp_fill_options_new (context->gimp); if (gimp_drawable_has_alpha (drawable)) gimp_fill_options_set_by_fill_type (options, context, GIMP_FILL_TRANSPARENT, NULL); else gimp_fill_options_set_by_fill_type (options, context, GIMP_FILL_BACKGROUND, NULL); gimp_edit_fill (image, drawable, options, C_("undo-type", "Clear")); g_object_unref (options); }
static GimpRGB peek_box_image (gint image, gint x, gint y) { static guchar data[4]; GimpRGB color; gimp_pixel_rgn_get_pixel (&box_regions[image], data, x, y); color.r = (gdouble) (data[0]) / 255.0; color.g = (gdouble) (data[1]) / 255.0; color.b = (gdouble) (data[2]) / 255.0; if (box_drawables[image]->bpp == 4) { if (gimp_drawable_has_alpha (box_drawables[image]->drawable_id)) color.a = (gdouble) (data[3]) / 255.0; else color.a = 1.0; } else { color.a = 1.0; } return color; }
static gboolean image_save_gif(image_output out, gboolean interlace) { gint nreturn_vals; // first, convert to indexed-256 color mode gimp_image_convert_indexed( out->image_id, GIMP_FS_DITHER, GIMP_MAKE_PALETTE, gimp_drawable_has_alpha (out->drawable_ids[0]) ? 255 : 256, TRUE, FALSE, "" ); GimpParam *return_vals = gimp_run_procedure( "file_gif_save", &nreturn_vals, GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE, GIMP_PDB_IMAGE, out->image_id, GIMP_PDB_DRAWABLE, 0, // drawable is ignored GIMP_PDB_STRING, out->filepath, GIMP_PDB_STRING, out->filename, GIMP_PDB_INT32, interlace ? 1 : 0, // Try to save as interlaced GIMP_PDB_INT32, 1, // (animated gif) loop infinitely GIMP_PDB_INT32, 0, // (animated gif) Default delay between framese in milliseconds GIMP_PDB_INT32, 0, // (animated gif) Default disposal type (0=don't care, 1=combine, 2=replace) GIMP_PDB_END ); return TRUE; }
static void gimp_curves_tool_color_picked (GimpColorTool *color_tool, GimpColorPickState pick_state, GimpImageType sample_type, GimpRGB *color, gint color_index) { GimpCurvesTool *tool = GIMP_CURVES_TOOL (color_tool); GimpDrawable *drawable; drawable = GIMP_IMAGE_MAP_TOOL (tool)->drawable; tool->picked_color[GIMP_HISTOGRAM_RED] = color->r; tool->picked_color[GIMP_HISTOGRAM_GREEN] = color->g; tool->picked_color[GIMP_HISTOGRAM_BLUE] = color->b; if (gimp_drawable_has_alpha (drawable)) tool->picked_color[GIMP_HISTOGRAM_ALPHA] = color->a; tool->picked_color[GIMP_HISTOGRAM_VALUE] = MAX (MAX (color->r, color->g), color->b); gimp_curve_view_set_xpos (GIMP_CURVE_VIEW (tool->graph), tool->picked_color[tool->config->channel]); }
static void gimp_curves_tool_color_picked (GimpColorTool *color_tool, GimpColorPickState pick_state, gdouble x, gdouble y, const Babl *sample_format, gpointer pixel, const GimpRGB *color) { GimpCurvesTool *tool = GIMP_CURVES_TOOL (color_tool); GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (color_tool); GimpCurvesConfig *config = GIMP_CURVES_CONFIG (im_tool->config); GimpDrawable *drawable; drawable = GIMP_IMAGE_MAP_TOOL (tool)->drawable; tool->picked_color[GIMP_HISTOGRAM_RED] = color->r; tool->picked_color[GIMP_HISTOGRAM_GREEN] = color->g; tool->picked_color[GIMP_HISTOGRAM_BLUE] = color->b; if (gimp_drawable_has_alpha (drawable)) tool->picked_color[GIMP_HISTOGRAM_ALPHA] = color->a; else tool->picked_color[GIMP_HISTOGRAM_ALPHA] = -1; tool->picked_color[GIMP_HISTOGRAM_VALUE] = MAX (MAX (color->r, color->g), color->b); gimp_curve_view_set_xpos (GIMP_CURVE_VIEW (tool->graph), tool->picked_color[config->channel]); }
gint image_setup (GimpDrawable *drawable, gint interactive) { /* Set the tile cache size */ /* ======================= */ gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width() - 1) / gimp_tile_width ()); /* Get some useful info on the input drawable */ /* ========================================== */ input_drawable = drawable; output_drawable = drawable; if (! gimp_drawable_mask_intersect (drawable->drawable_id, &border_x, &border_y, &border_w, &border_h)) return FALSE; width = input_drawable->width; height = input_drawable->height; gimp_pixel_rgn_init (&source_region, input_drawable, 0, 0, width, height, FALSE, FALSE); maxcounter = (glong) width * (glong) height; if (mapvals.transparent_background == TRUE) { gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); } else { gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 1.0); } /* Assume at least RGB */ /* =================== */ in_channels = 3; if (gimp_drawable_has_alpha (input_drawable->drawable_id) == TRUE) in_channels++; if (interactive == TRUE) { preview_rgb_stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, PREVIEW_WIDTH); preview_rgb_data = g_new0 (guchar, preview_rgb_stride * PREVIEW_HEIGHT); preview_surface = cairo_image_surface_create_for_data (preview_rgb_data, CAIRO_FORMAT_RGB24, PREVIEW_WIDTH, PREVIEW_HEIGHT, preview_rgb_stride); } return TRUE; }
/** * gimp_projection_initialize: * @proj: A #GimpProjection. * @x: * @y: * @w: * @h: * * This function determines whether a visible layer with combine mode * Normal provides complete coverage over the specified area. If not, * the projection is initialized to transparent black. */ static void gimp_projection_initialize (GimpProjection *proj, gint x, gint y, gint w, gint h) { GList *list; gint proj_off_x; gint proj_off_y; gboolean coverage = FALSE; gimp_projectable_get_offset (proj->projectable, &proj_off_x, &proj_off_y); for (list = gimp_projectable_get_layers (proj->projectable); list; list = g_list_next (list)) { GimpLayer *layer = list->data; GimpDrawable *drawable = GIMP_DRAWABLE (layer); GimpItem *item = GIMP_ITEM (layer); gint off_x, off_y; gimp_item_get_offset (item, &off_x, &off_y); /* subtract the projectable's offsets because the list of * update areas is in tile-pyramid coordinates, but our * external API is always in terms of image coordinates. */ off_x -= proj_off_x; off_y -= proj_off_y; if (gimp_item_get_visible (item) && ! gimp_drawable_has_alpha (drawable) && ! gimp_layer_get_mask (layer) && gimp_layer_get_mode (layer) == GIMP_NORMAL_MODE && gimp_layer_get_opacity (layer) == GIMP_OPACITY_OPAQUE && off_x <= x && off_y <= y && (off_x + gimp_item_get_width (item)) >= (x + w) && (off_y + gimp_item_get_height (item)) >= (y + h)) { coverage = TRUE; break; } } if (! coverage) { PixelRegion region; pixel_region_init (®ion, gimp_pickable_get_tiles (GIMP_PICKABLE (proj)), x, y, w, h, TRUE); clear_region (®ion); } }
void filters_actions_update (GimpActionGroup *group, gpointer data) { GimpImage *image; GimpDrawable *drawable = NULL; gboolean writable = FALSE; gboolean gray = FALSE; gboolean alpha = FALSE; image = action_data_get_image (data); if (image) { drawable = gimp_image_get_active_drawable (image); if (drawable) { GimpItem *item; alpha = gimp_drawable_has_alpha (drawable); gray = gimp_drawable_is_gray (drawable); if (GIMP_IS_LAYER_MASK (drawable)) item = GIMP_ITEM (gimp_layer_mask_get_layer (GIMP_LAYER_MASK (drawable))); else item = GIMP_ITEM (drawable); writable = ! gimp_item_is_content_locked (item); if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) writable = FALSE; } } #define SET_SENSITIVE(action,condition) \ gimp_action_group_set_action_sensitive (group, action, (condition) != 0) SET_SENSITIVE ("filters-color-reduction", writable); SET_SENSITIVE ("filters-color-temperature", writable && !gray); SET_SENSITIVE ("filters-color-to-alpha", writable && !gray && alpha); SET_SENSITIVE ("filters-difference-of-gaussians", writable); SET_SENSITIVE ("filters-gaussian-blur", writable); SET_SENSITIVE ("filters-laplace", writable); SET_SENSITIVE ("filters-lens-distortion", writable); SET_SENSITIVE ("filters-pixelize", writable); SET_SENSITIVE ("filters-polar-coordinates", writable); SET_SENSITIVE ("filters-ripple", writable); SET_SENSITIVE ("filters-sobel", writable); SET_SENSITIVE ("filters-semi-flatten", writable && alpha); SET_SENSITIVE ("filters-threshold-alpha", writable && alpha); SET_SENSITIVE ("filters-unsharp-mask", writable); #undef SET_SENSITIVE }
gint webx_indexed_target_get_image (WebxIndexedTarget *indexed, WebxTargetInput *input, gint *layer) { gint tmp_image; gint tmp_layer; gint *layers; gint num_layers; gchar *custom_palette; gint num_colors; gboolean converted; g_return_val_if_fail (WEBX_IS_INDEXED_TARGET (indexed), -1); if (indexed->palette_type == GIMP_REUSE_PALETTE) { *layer = input->indexed_layer; return input->indexed_image; } custom_palette = indexed->custom_palette; if (! custom_palette) custom_palette = ""; tmp_image = input->rgb_image; tmp_layer = input->rgb_layer; num_colors = indexed->num_colors; if (num_colors == 256 && gimp_drawable_has_alpha (tmp_layer)) num_colors = 255; tmp_image = gimp_image_duplicate (tmp_image); converted = gimp_image_convert_indexed (tmp_image, indexed->dither_type, indexed->palette_type, num_colors, indexed->alpha_dither, indexed->remove_unused, custom_palette); if (! converted) { gimp_image_delete (tmp_image); *layer = -1; return -1; } layers = gimp_image_get_layers (tmp_image, &num_layers); g_assert (num_layers == 1); tmp_layer = layers[0]; indexed->image = tmp_image; indexed->layer = tmp_layer; *layer= tmp_layer; return tmp_image; }
gint image_setup (GimpDrawable *drawable, gint interactive) { /* Set the tile cache size */ /* ======================= */ gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width() - 1) / gimp_tile_width ()); /* Get some useful info on the input drawable */ /* ========================================== */ input_drawable = drawable; output_drawable = drawable; gimp_drawable_mask_bounds (drawable->drawable_id, &border_x1, &border_y1, &border_x2, &border_y2); width = input_drawable->width; height = input_drawable->height; gimp_pixel_rgn_init (&source_region, input_drawable, 0, 0, width, height, FALSE, FALSE); maxcounter = (glong) width * (glong) height; if (mapvals.transparent_background == TRUE) { gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); } else { gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 1.0); } /* Assume at least RGB */ /* =================== */ in_channels = 3; if (gimp_drawable_has_alpha (input_drawable->drawable_id) == TRUE) in_channels++; if (interactive == TRUE) { preview_rgb_data = g_new0 (guchar, PREVIEW_HEIGHT * PREVIEW_WIDTH * 3); } return TRUE; }
static gboolean gimp_levels_tool_initialize (GimpTool *tool, GimpDisplay *display, GError **error) { GimpLevelsTool *l_tool = GIMP_LEVELS_TOOL (tool); GimpDrawable *drawable = gimp_image_get_active_drawable (display->image); if (! drawable) return FALSE; if (gimp_drawable_is_indexed (drawable)) { g_set_error (error, 0, 0, _("Levels does not operate on indexed layers.")); return FALSE; } if (! l_tool->hist) l_tool->hist = gimp_histogram_new (); levels_init (l_tool->levels); l_tool->channel = GIMP_HISTOGRAM_VALUE; l_tool->color = gimp_drawable_is_rgb (drawable); l_tool->alpha = gimp_drawable_has_alpha (drawable); if (l_tool->active_picker) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (l_tool->active_picker), FALSE); GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error); gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (l_tool->channel_menu), levels_menu_sensitivity, l_tool, NULL); gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (l_tool->channel_menu), l_tool->channel); /* FIXME: hack */ if (! l_tool->color) l_tool->channel = (l_tool->channel == GIMP_HISTOGRAM_ALPHA) ? 1 : 0; levels_update (l_tool, ALL); gimp_drawable_calculate_histogram (drawable, l_tool->hist); gimp_histogram_view_set_histogram (GIMP_HISTOGRAM_VIEW (l_tool->hist_view), l_tool->hist); return TRUE; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[2]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpExportReturn export = GIMP_EXPORT_CANCEL; GError *error = NULL; INIT_I18N (); gegl_init (NULL, NULL); run_mode = param[0].data.d_int32; *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; if (run_mode == GIMP_RUN_INTERACTIVE && strcmp (name, SAVE_PROC) == 0) { gint32 image_ID = param[1].data.d_int32; gint32 drawable_ID = param[2].data.d_int32; GimpParasite *parasite; gchar *x; gimp_get_data (SAVE_PROC, &config); config.prefixed_name = "gimp_image"; config.comment = NULL; config.alpha = gimp_drawable_has_alpha (drawable_ID); parasite = gimp_image_get_parasite (image_ID, "gimp-comment"); if (parasite) { config.comment = g_strndup (gimp_parasite_data (parasite), gimp_parasite_data_size (parasite)); gimp_parasite_free (parasite); } x = config.comment; gimp_ui_init (PLUG_IN_BINARY, FALSE); export = gimp_export_image (&image_ID, &drawable_ID, "C Source",
static void export_convert_indexed (gint32 image_ID, gint32 *drawable_ID) { gint32 nlayers; /* check alpha */ g_free (gimp_image_get_layers (image_ID, &nlayers)); if (nlayers > 1 || gimp_drawable_has_alpha (*drawable_ID)) gimp_image_convert_indexed (image_ID, GIMP_NO_DITHER, GIMP_MAKE_PALETTE, 255, FALSE, FALSE, ""); else gimp_image_convert_indexed (image_ID, GIMP_NO_DITHER, GIMP_MAKE_PALETTE, 256, FALSE, FALSE, ""); }
static void export_add_alpha (gint32 image_ID, gint32 *drawable_ID) { gint32 nlayers; gint32 i; gint32 *layers; layers = gimp_image_get_layers (image_ID, &nlayers); for (i = 0; i < nlayers; i++) { if (!gimp_drawable_has_alpha (layers[i])) gimp_layer_add_alpha (layers[i]); } g_free (layers); }
void gimp_drawable_curves_spline (GimpDrawable *drawable, GimpProgress *progress, gint32 channel, const guint8 *points, gint n_points) { GimpCurvesConfig *config; GimpCurve *curve; gint i; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (! gimp_drawable_is_indexed (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (channel >= GIMP_HISTOGRAM_VALUE && channel <= GIMP_HISTOGRAM_ALPHA); if (channel == GIMP_HISTOGRAM_ALPHA) g_return_if_fail (gimp_drawable_has_alpha (drawable)); if (gimp_drawable_is_gray (drawable)) g_return_if_fail (channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA); config = g_object_new (GIMP_TYPE_CURVES_CONFIG, NULL); curve = config->curve[channel]; gimp_data_freeze (GIMP_DATA (curve)); /* FIXME: create a curves object with the right number of points */ /* unset the last point */ gimp_curve_set_point (curve, curve->n_points - 1, -1, -1); n_points = MIN (n_points / 2, curve->n_points); for (i = 0; i < n_points; i++) gimp_curve_set_point (curve, i, (gdouble) points[i * 2] / 255.0, (gdouble) points[i * 2 + 1] / 255.0); gimp_data_thaw (GIMP_DATA (curve)); gimp_drawable_curves (drawable, progress, config); g_object_unref (config); }
/* * Red Eye Removal Alorithm, based on using a threshold to detect * red pixels. Having a user-made selection around the eyes will * prevent incorrect pixels from being selected. */ static void remove_redeye (GimpDrawable *drawable) { GimpPixelRgn src_rgn; GimpPixelRgn dest_rgn; gint progress, max_progress; gboolean has_alpha; gint x, y; gint width, height; gint i; gpointer pr; if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x, &y, &width, &height)) return; gimp_progress_init (_("Removing red eye")); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); progress = 0; max_progress = width * height; gimp_pixel_rgn_init (&src_rgn, drawable, x, y, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, x, y, width, height, TRUE, TRUE); for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), i = 0; pr != NULL; pr = gimp_pixel_rgns_process (pr), i++) { redeye_inner_loop (src_rgn.data, dest_rgn.data, src_rgn.w, src_rgn.h, src_rgn.bpp, has_alpha, src_rgn.rowstride); progress += src_rgn.w * src_rgn.h; if (i % 16 == 0) gimp_progress_update ((gdouble) progress / (gdouble) max_progress); } gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x, y, width, height); }
static GimpPDBStatusType main_function (GimpDrawable *drawable, GimpPreview *preview) { MaxRgbParam_t param; param.init_value = (pvals.max_p > 0) ? 0 : 255; param.flag = (0 < pvals.max_p) ? 1 : -1; param.has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); if (preview) { gint i; guchar *buffer; guchar *src; gint width, height, bpp; src = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview), &width, &height, &bpp); buffer = g_new (guchar, width * height * bpp); for (i = 0; i < width * height; i++) { max_rgb_func (src + i * bpp, buffer + i * bpp, bpp, ¶m); } gimp_preview_draw_buffer (preview, buffer, width * bpp); g_free (buffer); g_free (src); } else { gimp_progress_init (_("Max RGB")); gimp_rgn_iterate2 (drawable, 0 /* unused */, max_rgb_func, ¶m); gimp_drawable_detach (drawable); } return GIMP_PDB_SUCCESS; }
/* Returns NGRADSAMPLES samples of active gradient. Each sample has (gimp_drawable_bpp (drawable_id)) bytes. "ripped" from gradmap.c. */ static guchar * get_gradient_samples (gint32 drawable_id, gboolean reverse) { gchar *gradient_name; gint n_f_samples; gdouble *f_samples, *f_samp; /* float samples */ guchar *b_samples, *b_samp; /* byte samples */ gint bpp, color, has_alpha, alpha; gint i, j; gradient_name = gimp_context_get_gradient (); gimp_gradient_get_uniform_samples (gradient_name, NGRADSAMPLES, reverse, &n_f_samples, &f_samples); g_free (gradient_name); bpp = gimp_drawable_bpp (drawable_id); color = gimp_drawable_is_rgb (drawable_id); has_alpha = gimp_drawable_has_alpha (drawable_id); alpha = (has_alpha ? bpp - 1 : bpp); b_samples = g_new (guchar, NGRADSAMPLES * bpp); for (i = 0; i < NGRADSAMPLES; i++) { b_samp = &b_samples[i * bpp]; f_samp = &f_samples[i * 4]; if (color) for (j = 0; j < 3; j++) b_samp[j] = f_samp[j] * 255; else b_samp[0] = GIMP_RGB_LUMINANCE (f_samp[0], f_samp[1], f_samp[2]) * 255; if (has_alpha) b_samp[alpha] = f_samp[3] * 255; } g_free (f_samples); return b_samples; }
void gimp_channel_select_alpha (GimpChannel *channel, GimpDrawable *drawable, GimpChannelOps op, gboolean feather, gdouble feather_radius_x, gdouble feather_radius_y) { GimpItem *item; GimpChannel *add_on; gint off_x, off_y; g_return_if_fail (GIMP_IS_CHANNEL (channel)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel))); g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); item = GIMP_ITEM (channel); if (gimp_drawable_has_alpha (drawable)) { add_on = gimp_channel_new_from_alpha (gimp_item_get_image (item), drawable, NULL, NULL); } else { /* no alpha is equivalent to completely opaque alpha, * so simply select the whole layer's extents. --mitch */ add_on = gimp_channel_new_mask (gimp_item_get_image (item), gimp_item_get_width (GIMP_ITEM (drawable)), gimp_item_get_height (GIMP_ITEM (drawable))); gimp_channel_all (add_on, FALSE); } gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); gimp_channel_select_channel (channel, C_("undo-type", "Alpha to Selection"), add_on, off_x, off_y, op, feather, feather_radius_x, feather_radius_y); g_object_unref (add_on); }
void gimp_drawable_curves_explicit (GimpDrawable *drawable, GimpProgress *progress, gint32 channel, const guint8 *points, gint n_points) { GimpCurvesConfig *config; GimpCurve *curve; gint i; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (! gimp_drawable_is_indexed (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (channel >= GIMP_HISTOGRAM_VALUE && channel <= GIMP_HISTOGRAM_ALPHA); if (channel == GIMP_HISTOGRAM_ALPHA) g_return_if_fail (gimp_drawable_has_alpha (drawable)); if (gimp_drawable_is_gray (drawable)) g_return_if_fail (channel == GIMP_HISTOGRAM_VALUE || channel == GIMP_HISTOGRAM_ALPHA); config = g_object_new (GIMP_TYPE_CURVES_CONFIG, NULL); curve = config->curve[channel]; gimp_data_freeze (GIMP_DATA (curve)); gimp_curve_set_curve_type (curve, GIMP_CURVE_FREE); for (i = 0; i < 256; i++) gimp_curve_set_curve (curve, (gdouble) i / 255.0, (gdouble) points[i] / 255.0); gimp_data_thaw (GIMP_DATA (curve)); gimp_drawable_curves (drawable, progress, config); g_object_unref (config); }
static void check_drawables (void) { if (mapvals.bump_mapped) { if (mapvals.bumpmap_id != -1 && gimp_item_get_image (mapvals.bumpmap_id) == -1) { mapvals.bump_mapped = FALSE; mapvals.bumpmap_id = -1; } if (gimp_drawable_is_indexed (mapvals.bumpmap_id) || (gimp_drawable_width (mapvals.drawable_id) != gimp_drawable_width (mapvals.bumpmap_id)) || (gimp_drawable_height (mapvals.drawable_id) != gimp_drawable_height (mapvals.bumpmap_id))) { mapvals.bump_mapped = FALSE; mapvals.bumpmap_id = -1; } } if (mapvals.env_mapped) { if (mapvals.envmap_id != -1 && gimp_item_get_image (mapvals.envmap_id) == -1) { mapvals.env_mapped = FALSE; mapvals.envmap_id = -1; } if (gimp_drawable_is_gray (mapvals.envmap_id) || gimp_drawable_has_alpha (mapvals.envmap_id)) { mapvals.env_mapped = FALSE; mapvals.envmap_id = -1; } } }
static void remove_redeye_preview (GimpDrawable *drawable, GimpPreview *preview) { guchar *src; guchar *dest; gboolean has_alpha; gint width, height; gint bpp; gint rowstride; src = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview), &width, &height, &bpp); dest = g_new (guchar, height * width * bpp); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); rowstride = bpp * width; redeye_inner_loop (src, dest, width, height, bpp, has_alpha, rowstride); gimp_preview_draw_buffer (preview, dest, rowstride); g_free (src); g_free (dest); }