void gimp_gegl_progress_connect (GeglNode *node, GimpProgress *progress, const gchar *text) { GObject *operation = NULL; g_return_if_fail (GEGL_IS_NODE (node)); g_return_if_fail (GIMP_IS_PROGRESS (progress)); g_object_get (node, "gegl-operation", &operation, NULL); g_return_if_fail (operation != NULL); g_signal_connect (operation, "notify::progress", G_CALLBACK (gimp_gegl_progress_notify), progress); if (text) g_object_set_data_full (operation, "gimp-progress-text", g_strdup (text), (GDestroyNotify) g_free); g_object_unref (operation); }
void gimp_gegl_mode_node_set_mode (GeglNode *node, GimpLayerModeEffects mode, gboolean linear) { const gchar *operation = "gimp:normal-mode"; gdouble opacity; g_return_if_fail (GEGL_IS_NODE (node)); switch (mode) { case GIMP_NORMAL_MODE: operation = "gimp:normal-mode"; break; case GIMP_DISSOLVE_MODE: operation = "gimp:dissolve-mode"; break; case GIMP_BEHIND_MODE: operation = "gimp:behind-mode"; break; case GIMP_MULTIPLY_MODE: operation = "gimp:multiply-mode"; break; case GIMP_SCREEN_MODE: operation = "gimp:screen-mode"; break; case GIMP_OVERLAY_MODE: operation = "gimp:softlight-mode"; break; case GIMP_DIFFERENCE_MODE: operation = "gimp:difference-mode"; break; case GIMP_ADDITION_MODE: operation = "gimp:addition-mode"; break; case GIMP_SUBTRACT_MODE: operation = "gimp:subtract-mode"; break; case GIMP_DARKEN_ONLY_MODE: operation = "gimp:darken-only-mode"; break; case GIMP_LIGHTEN_ONLY_MODE: operation = "gimp:lighten-only-mode"; break; case GIMP_HUE_MODE: operation = "gimp:hue-mode"; break; case GIMP_SATURATION_MODE: operation = "gimp:saturation-mode"; break; case GIMP_COLOR_MODE: operation = "gimp:color-mode"; break; case GIMP_VALUE_MODE: operation = "gimp:value-mode"; break; case GIMP_DIVIDE_MODE: operation = "gimp:divide-mode"; break; case GIMP_DODGE_MODE: operation = "gimp:dodge-mode"; break; case GIMP_BURN_MODE: operation = "gimp:burn-mode"; break; case GIMP_HARDLIGHT_MODE: operation = "gimp:hardlight-mode"; break; case GIMP_SOFTLIGHT_MODE: operation = "gimp:softlight-mode"; break; case GIMP_GRAIN_EXTRACT_MODE: operation = "gimp:grain-extract-mode"; break; case GIMP_GRAIN_MERGE_MODE: operation = "gimp:grain-merge-mode"; break; case GIMP_COLOR_ERASE_MODE: operation = "gimp:color-erase-mode"; break; case GIMP_NEW_OVERLAY_MODE: operation = "gimp:overlay-mode"; break; case GIMP_ERASE_MODE: operation = "gimp:erase-mode"; break; case GIMP_REPLACE_MODE: operation = "gimp:replace-mode"; break; case GIMP_ANTI_ERASE_MODE: operation = "gimp:anti-erase-mode"; break; case GIMP_LCH_HUE_MODE: operation = "gimp:lch-hue-mode"; break; case GIMP_LCH_CHROMA_MODE: operation = "gimp:lch-chroma-mode"; break; case GIMP_LCH_COLOR_MODE: operation = "gimp:lch-color-mode"; break; case GIMP_LCH_LIGHTNESS_MODE: operation = "gimp:lch-lightness-mode"; break; default: break; } gegl_node_get (node, "opacity", &opacity, NULL); /* setting the operation creates a new instance, so we have to set * all its properties */ gegl_node_set (node, "operation", operation, "linear", linear, "opacity", opacity, NULL); }
static void dispose (GObject *gobject) { GeglCache *self = GEGL_CACHE (gobject); while (g_idle_remove_by_data (gobject)) ; /* Check with GEGL_IS_NODE since sometimes the node is destroyed * before we get here */ if (GEGL_IS_NODE (self->node)) { gint handler = g_signal_handler_find (self->node, G_SIGNAL_MATCH_DATA, g_signal_lookup ("invalidated", GEGL_TYPE_NODE), 0, NULL, NULL, self); if (handler) { g_signal_handler_disconnect (self->node, handler); } self->node = NULL; } G_OBJECT_CLASS (gegl_cache_parent_class)->dispose (gobject); }
GeglNode * gimp_gegl_add_buffer_source (GeglNode *parent, GeglBuffer *buffer, gint offset_x, gint offset_y) { GeglNode *buffer_source; g_return_val_if_fail (GEGL_IS_NODE (parent), NULL); g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL); buffer_source = gegl_node_new_child (parent, "operation", "gegl:buffer-source", "buffer", buffer, NULL); if (offset_x != 0 || offset_y != 0) { GeglNode *translate = gegl_node_new_child (parent, "operation", "gegl:translate", "x", (gdouble) offset_x, "y", (gdouble) offset_y, NULL); gegl_node_connect_to (buffer_source, "output", translate, "input"); buffer_source = translate; } return buffer_source; }
void gimp_drawable_apply_operation_to_tiles (GimpDrawable *drawable, GimpProgress *progress, const gchar *undo_desc, GeglNode *operation, gboolean linear, TileManager *new_tiles) { GeglRectangle rect; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); g_return_if_fail (undo_desc != NULL); g_return_if_fail (GEGL_IS_NODE (operation)); g_return_if_fail (new_tiles != NULL); rect.x = 0; rect.y = 0; rect.width = tile_manager_width (new_tiles); rect.height = tile_manager_height (new_tiles); gimp_drawable_apply_operation_private (drawable, progress, undo_desc, operation, linear, new_tiles, &rect); if (progress) gimp_progress_end (progress); }
void gimp_gegl_config_proxy_sync (GimpObject *proxy, GeglNode *node) { GParamSpec **pspecs; gchar *operation; guint n_pspecs; gint i; g_return_if_fail (GIMP_IS_OBJECT (proxy)); g_return_if_fail (GEGL_IS_NODE (node)); gegl_node_get (node, "operation", &operation, NULL); g_return_if_fail (operation != NULL); pspecs = gegl_operation_list_properties (operation, &n_pspecs); g_free (operation); for (i = 0; i < n_pspecs; i++) { GParamSpec *gegl_pspec = pspecs[i]; GParamSpec *gimp_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), gegl_pspec->name); if (gimp_pspec) { GValue value = { 0, }; g_value_init (&value, gimp_pspec->value_type); g_object_get_property (G_OBJECT (proxy), gimp_pspec->name, &value); if (GEGL_IS_PARAM_SPEC_COLOR (gegl_pspec)) { GimpRGB gimp_color; GeglColor *gegl_color; gimp_value_get_rgb (&value, &gimp_color); g_value_unset (&value); gegl_color = gimp_gegl_color_new (&gimp_color); g_value_init (&value, gegl_pspec->value_type); g_value_take_object (&value, gegl_color); } gegl_node_set_property (node, gegl_pspec->name, &value); g_value_unset (&value); } } g_free (pspecs); }
void gegl_pad_set_node (GeglPad *self, GeglNode *node) { g_return_if_fail (GEGL_IS_PAD (self)); g_return_if_fail (GEGL_IS_NODE (node)); self->node = node; }
void gimp_gegl_mode_node_set_opacity (GeglNode *node, gdouble opacity) { g_return_if_fail (GEGL_IS_NODE (node)); gegl_node_set (node, "opacity", opacity, NULL); }
GeglTileHandler * gimp_tile_handler_projection_new (GeglNode *graph) { GimpTileHandlerProjection *projection; g_return_val_if_fail (GEGL_IS_NODE (graph), NULL); projection = g_object_new (GIMP_TYPE_TILE_HANDLER_PROJECTION, NULL); projection->graph = g_object_ref (graph); return GEGL_TILE_HANDLER (projection); }
void gegl_operation_attach (GeglOperation *self, GeglNode *node) { GeglOperationClass *klass; g_return_if_fail (GEGL_IS_OPERATION (self)); g_return_if_fail (GEGL_IS_NODE (node)); klass = GEGL_OPERATION_GET_CLASS (self); g_assert (klass->attach); self->node = node; klass->attach (self); }
static void gimp_warp_tool_remove_op (GimpWarpTool *wt, GeglNode *op) { GeglNode *previous; g_return_if_fail (GEGL_IS_NODE (wt->render_node)); previous = gegl_node_get_producer (op, "input", NULL); gegl_node_disconnect (op, "input"); gegl_node_connect_to (previous, "output", wt->render_node, "aux"); gegl_node_remove_child (wt->graph, op); }
void gimp_gegl_node_set_matrix (GeglNode *node, const GimpMatrix3 *matrix) { gchar *matrix_string; g_return_if_fail (GEGL_IS_NODE (node)); g_return_if_fail (matrix != NULL); matrix_string = gegl_matrix3_to_string ((GeglMatrix3 *) matrix); gegl_node_set (node, "transform", matrix_string, NULL); g_free (matrix_string); }
void gimp_gegl_node_set_color (GeglNode *node, const GimpRGB *color) { GeglColor *gegl_color; g_return_if_fail (GEGL_IS_NODE (node)); g_return_if_fail (color != NULL); gegl_color = gimp_gegl_color_new (color); gegl_node_set (node, "value", gegl_color, NULL); g_object_unref (gegl_color); }
static void gimp_warp_tool_add_op (GimpWarpTool *wt, GeglNode *new_op) { GeglNode *last_op; g_return_if_fail (GEGL_IS_NODE (wt->render_node)); gegl_node_add_child (wt->graph, new_op); last_op = gegl_node_get_producer (wt->render_node, "aux", NULL); gegl_node_disconnect (wt->render_node, "aux"); gegl_node_connect_to (last_op, "output", new_op, "input"); gegl_node_connect_to (new_op, "output", wt->render_node, "aux"); }
void gimp_brightness_contrast_config_set_node (GimpBrightnessContrastConfig *config, GeglNode *node) { gdouble brightness; gdouble contrast; g_return_if_fail (GIMP_IS_BRIGHTNESS_CONTRAST_CONFIG (config)); g_return_if_fail (GEGL_IS_NODE (node)); brightness = config->brightness / 2.0; contrast = (config->contrast < 0 ? (config->contrast + 1.0) : config->contrast * 4.0 + 1.0); gegl_node_set (node, "brightness", brightness, "contrast", contrast, NULL); }
void gimp_drawable_apply_operation (GimpDrawable *drawable, GimpProgress *progress, const gchar *undo_desc, GeglNode *operation, gboolean linear) { GeglRectangle rect; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); g_return_if_fail (undo_desc != NULL); g_return_if_fail (GEGL_IS_NODE (operation)); if (! gimp_item_mask_intersect (GIMP_ITEM (drawable), &rect.x, &rect.y, &rect.width, &rect.height)) return; gimp_drawable_apply_operation_private (drawable, progress, undo_desc, operation, linear, gimp_drawable_get_shadow_tiles (drawable), &rect); gimp_drawable_merge_shadow_tiles (drawable, TRUE, undo_desc); gimp_drawable_free_shadow_tiles (drawable); gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height); if (progress) gimp_progress_end (progress); }
GimpApplicator * gimp_applicator_new (GeglNode *parent, gboolean linear, gboolean use_split_preview, gboolean use_result_cache) { GimpApplicator *applicator; g_return_val_if_fail (parent == NULL || GEGL_IS_NODE (parent), NULL); applicator = g_object_new (GIMP_TYPE_APPLICATOR, NULL); applicator->linear = linear; if (parent) applicator->node = g_object_ref (parent); else applicator->node = gegl_node_new (); applicator->input_node = gegl_node_get_input_proxy (applicator->node, "input"); applicator->aux_node = gegl_node_get_input_proxy (applicator->node, "aux"); applicator->output_node = gegl_node_get_output_proxy (applicator->node, "output"); applicator->mode_node = gegl_node_new_child (applicator->node, "operation", "gimp:normal-mode", NULL); gimp_gegl_mode_node_set_mode (applicator->mode_node, applicator->paint_mode, applicator->linear); gimp_gegl_mode_node_set_opacity (applicator->mode_node, applicator->opacity); gegl_node_connect_to (applicator->input_node, "output", applicator->mode_node, "input"); applicator->apply_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); applicator->dup_apply_buffer_node = gegl_node_new_child (applicator->node, "operation", "gegl:copy-buffer", NULL); gegl_node_link_many (applicator->aux_node, applicator->apply_offset_node, applicator->dup_apply_buffer_node, NULL); if (use_split_preview) { applicator->preview_cache_node = gegl_node_new_child (applicator->node, "operation", "gegl:cache", NULL); applicator->preview_crop_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); gegl_node_link_many (applicator->dup_apply_buffer_node, applicator->preview_cache_node, applicator->preview_crop_node, NULL); gegl_node_connect_to (applicator->preview_crop_node, "output", applicator->mode_node, "aux"); } else { gegl_node_connect_to (applicator->dup_apply_buffer_node, "output", applicator->mode_node, "aux"); } applicator->mask_node = gegl_node_new_child (applicator->node, "operation", "gegl:buffer-source", NULL); applicator->mask_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); gegl_node_connect_to (applicator->mask_node, "output", applicator->mask_offset_node, "input"); /* don't connect the the mask offset node to mode's aux2 yet */ applicator->affect_node = gegl_node_new_child (applicator->node, "operation", "gimp:mask-components", "mask", applicator->affect, NULL); if (use_result_cache) { applicator->output_cache_node = gegl_node_new_child (applicator->node, "operation", "gegl:cache", NULL); gegl_node_link_many (applicator->input_node, applicator->affect_node, applicator->output_cache_node, applicator->output_node, NULL); } else { gegl_node_link_many (applicator->input_node, applicator->affect_node, applicator->output_node, NULL); } gegl_node_connect_to (applicator->mode_node, "output", applicator->affect_node, "aux"); return applicator; }
gboolean gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer, GimpProgress *progress, const gchar *undo_desc, GeglNode *operation, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, GeglBuffer *cache, const GeglRectangle *valid_rects, gint n_valid_rects, gboolean cancellable) { GeglNode *gegl; GeglNode *dest_node; GeglRectangle rect = { 0, }; GeglProcessor *processor = NULL; gboolean progress_started = FALSE; gdouble value; gboolean cancel = FALSE; g_return_val_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer), FALSE); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE); g_return_val_if_fail (GEGL_IS_NODE (operation), FALSE); g_return_val_if_fail (GEGL_IS_BUFFER (dest_buffer), FALSE); g_return_val_if_fail (cache == NULL || GEGL_IS_BUFFER (cache), FALSE); g_return_val_if_fail (valid_rects == NULL || cache != NULL, FALSE); g_return_val_if_fail (valid_rects == NULL || n_valid_rects != 0, FALSE); if (dest_rect) { rect = *dest_rect; } else { rect = *GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (dest_buffer), gegl_buffer_get_height (dest_buffer)); } gegl = gegl_node_new (); if (! gegl_node_get_parent (operation)) gegl_node_add_child (gegl, operation); if (src_buffer && gegl_node_has_pad (operation, "input")) { GeglNode *src_node; /* dup() because reading and writing the same buffer doesn't * work with area ops when using a processor. See bug #701875. */ if (progress && (src_buffer == dest_buffer)) src_buffer = gegl_buffer_dup (src_buffer); else g_object_ref (src_buffer); src_node = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", src_buffer, NULL); g_object_unref (src_buffer); gegl_node_connect_to (src_node, "output", operation, "input"); } dest_node = gegl_node_new_child (gegl, "operation", "gegl:write-buffer", "buffer", dest_buffer, NULL); gegl_node_connect_to (operation, "output", dest_node, "input"); if (progress) { processor = gegl_node_new_processor (dest_node, &rect); if (gimp_progress_is_active (progress)) { if (undo_desc) gimp_progress_set_text_literal (progress, undo_desc); progress_started = FALSE; cancellable = FALSE; } else { gimp_progress_start (progress, cancellable, "%s", undo_desc); if (cancellable) g_signal_connect (progress, "cancel", G_CALLBACK (gimp_gegl_apply_operation_cancel), &cancel); progress_started = TRUE; } } if (cache) { cairo_region_t *region; gint all_pixels; gint done_pixels = 0; gint n_rects; gint i; region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect); all_pixels = rect.width * rect.height; for (i = 0; i < n_valid_rects; i++) { gegl_buffer_copy (cache, valid_rects + i, GEGL_ABYSS_NONE, dest_buffer, valid_rects + i); cairo_region_subtract_rectangle (region, (cairo_rectangle_int_t *) valid_rects + i); done_pixels += valid_rects[i].width * valid_rects[i].height; if (progress) gimp_progress_set_value (progress, (gdouble) done_pixels / (gdouble) all_pixels); } n_rects = cairo_region_num_rectangles (region); for (i = 0; ! cancel && (i < n_rects); i++) { cairo_rectangle_int_t render_rect; cairo_region_get_rectangle (region, i, &render_rect); if (progress) { gint rect_pixels = render_rect.width * render_rect.height; #ifdef REUSE_PROCESSOR gegl_processor_set_rectangle (processor, (GeglRectangle *) &render_rect); #else g_object_unref (processor); processor = gegl_node_new_processor (dest_node, (GeglRectangle *) &render_rect); #endif while (! cancel && gegl_processor_work (processor, &value)) { gimp_progress_set_value (progress, ((gdouble) done_pixels + value * rect_pixels) / (gdouble) all_pixels); if (cancellable) while (! cancel && g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); } done_pixels += rect_pixels; } else { gegl_node_blit (dest_node, 1.0, (GeglRectangle *) &render_rect, NULL, NULL, 0, GEGL_BLIT_DEFAULT); } } cairo_region_destroy (region); } else { if (progress) { while (! cancel && gegl_processor_work (processor, &value)) { gimp_progress_set_value (progress, value); if (cancellable) while (! cancel && g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); } } else { gegl_node_blit (dest_node, 1.0, &rect, NULL, NULL, 0, GEGL_BLIT_DEFAULT); } } if (processor) g_object_unref (processor); g_object_unref (gegl); if (progress_started) { gimp_progress_end (progress); if (cancellable) g_signal_handlers_disconnect_by_func (progress, gimp_gegl_apply_operation_cancel, &cancel); } return ! cancel; }
GimpApplicator * gimp_applicator_new (GeglNode *parent) { GimpApplicator *applicator; g_return_val_if_fail (parent == NULL || GEGL_IS_NODE (parent), NULL); applicator = g_object_new (GIMP_TYPE_APPLICATOR, NULL); if (parent) applicator->node = g_object_ref (parent); else applicator->node = gegl_node_new (); applicator->input_node = gegl_node_get_input_proxy (applicator->node, "input"); applicator->aux_node = gegl_node_get_input_proxy (applicator->node, "aux"); applicator->output_node = gegl_node_get_output_proxy (applicator->node, "output"); applicator->mode_node = gegl_node_new_child (applicator->node, "operation", "gimp:normal", NULL); gimp_gegl_mode_node_set_mode (applicator->mode_node, applicator->paint_mode, applicator->blend_space, applicator->composite_space, applicator->composite_mode); gimp_gegl_mode_node_set_opacity (applicator->mode_node, applicator->opacity); gegl_node_connect_to (applicator->input_node, "output", applicator->mode_node, "input"); applicator->apply_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); gegl_node_link_many (applicator->aux_node, applicator->apply_offset_node, NULL); gegl_node_connect_to (applicator->apply_offset_node, "output", applicator->mode_node, "aux"); applicator->mask_node = gegl_node_new_child (applicator->node, "operation", "gegl:buffer-source", NULL); applicator->mask_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); gegl_node_connect_to (applicator->mask_node, "output", applicator->mask_offset_node, "input"); /* don't connect the the mask offset node to mode's aux2 yet */ applicator->affect_node = gegl_node_new_child (applicator->node, "operation", "gimp:mask-components", "mask", applicator->affect, NULL); applicator->convert_format_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); applicator->cache_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); applicator->crop_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); gegl_node_link_many (applicator->input_node, applicator->affect_node, applicator->convert_format_node, applicator->cache_node, applicator->crop_node, applicator->output_node, NULL); gegl_node_connect_to (applicator->mode_node, "output", applicator->affect_node, "aux"); return applicator; }
void gimp_gegl_apply_operation (GeglBuffer *src_buffer, GimpProgress *progress, const gchar *undo_desc, GeglNode *operation, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect) { GeglNode *gegl; GeglNode *dest_node; GeglRectangle rect = { 0, }; gdouble value; gboolean progress_active = FALSE; g_return_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); g_return_if_fail (GEGL_IS_NODE (operation)); g_return_if_fail (GEGL_IS_BUFFER (dest_buffer)); if (dest_rect) { rect = *dest_rect; } else { rect = *GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (dest_buffer), gegl_buffer_get_height (dest_buffer)); } gegl = gegl_node_new (); if (! gegl_node_get_parent (operation)) gegl_node_add_child (gegl, operation); if (src_buffer && gegl_node_has_pad (operation, "input")) { GeglNode *src_node; /* dup() because reading and writing the same buffer doesn't * work with area ops when using a processor. See bug #701875. */ if (progress && (src_buffer == dest_buffer)) src_buffer = gegl_buffer_dup (src_buffer); else g_object_ref (src_buffer); src_node = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", src_buffer, NULL); g_object_unref (src_buffer); gegl_node_connect_to (src_node, "output", operation, "input"); } dest_node = gegl_node_new_child (gegl, "operation", "gegl:write-buffer", "buffer", dest_buffer, NULL); gegl_node_connect_to (operation, "output", dest_node, "input"); if (progress) { GeglProcessor *processor; processor = gegl_node_new_processor (dest_node, &rect); progress_active = gimp_progress_is_active (progress); if (progress_active) { if (undo_desc) gimp_progress_set_text (progress, undo_desc); } else { gimp_progress_start (progress, undo_desc, FALSE); } while (gegl_processor_work (processor, &value)) gimp_progress_set_value (progress, value); g_object_unref (processor); } else { gegl_node_blit (dest_node, 1.0, &rect, NULL, NULL, 0, GEGL_BLIT_DEFAULT); } g_object_unref (gegl); if (progress && ! progress_active) gimp_progress_end (progress); }