static void gimp_gegl_progress_notify (GObject *object, const GParamSpec *pspec, GimpProgress *progress) { const gchar *text; gdouble value; g_object_get (object, "progress", &value, NULL); text = g_object_get_data (object, "gimp-progress-text"); if (text) { if (value == 0.0) { gimp_progress_start (progress, text, FALSE); return; } else if (value == 1.0) { gimp_progress_end (progress); return; } } gimp_progress_set_value (progress, value); }
static void gimp_cage_tool_compute_coef (GimpCageTool *ct) { GimpCageConfig *config = ct->config; GimpProgress *progress; const Babl *format; GeglNode *gegl; GeglNode *input; GeglNode *output; GeglProcessor *processor; GeglBuffer *buffer; gdouble value; progress = gimp_progress_start (GIMP_PROGRESS (ct), _("Computing Cage Coefficients"), FALSE); if (ct->coef) { g_object_unref (ct->coef); ct->coef = NULL; } format = babl_format_n (babl_type ("float"), gimp_cage_config_get_n_points (config) * 2); gegl = gegl_node_new (); input = gegl_node_new_child (gegl, "operation", "gimp:cage-coef-calc", "config", ct->config, NULL); output = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer, "format", format, NULL); gegl_node_connect_to (input, "output", output, "input"); processor = gegl_node_new_processor (output, NULL); while (gegl_processor_work (processor, &value)) { if (progress) gimp_progress_set_value (progress, value); } if (progress) gimp_progress_end (progress); g_object_unref (processor); ct->coef = buffer; g_object_unref (gegl); ct->dirty_coef = FALSE; }
static void gimp_gegl_progress_callback (GObject *object, gdouble value, GimpProgress *progress) { const gchar *text; text = g_object_get_data (object, "gimp-progress-text"); if (text) { if (value == 0.0) { if (gimp_progress_is_active (progress)) gimp_progress_set_text (progress, "%s", text); else gimp_progress_start (progress, FALSE, "%s", text); return; } else if (value == 1.0) { gimp_progress_end (progress); return; } } gimp_progress_set_value (progress, value); }
static void gimp_file_dialog_progress_set_value (GimpProgress *progress, gdouble percentage) { GimpFileDialog *dialog = GIMP_FILE_DIALOG (progress); gimp_progress_set_value (GIMP_PROGRESS (dialog->progress), percentage); }
static void gimp_display_shell_progress_set_value (GimpProgress *progress, gdouble percentage) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (progress); GimpStatusbar *statusbar = gimp_display_shell_get_statusbar (shell); gimp_progress_set_value (GIMP_PROGRESS (statusbar), percentage); }
static void gimp_display_progress_set_value (GimpProgress *progress, gdouble percentage) { GimpDisplay *display = GIMP_DISPLAY (progress); if (display->shell) gimp_progress_set_value (GIMP_PROGRESS (display->shell), percentage); }
static void gimp_sub_progress_set_value (GimpProgress *progress, gdouble percentage) { GimpSubProgress *sub = GIMP_SUB_PROGRESS (progress); if (sub->progress) gimp_progress_set_value (sub->progress, sub->start + percentage * (sub->end - sub->start)); }
static void gimp_progress_dialog_progress_set_value (GimpProgress *progress, gdouble percentage) { GimpProgressDialog *dialog = GIMP_PROGRESS_DIALOG (progress); if (! dialog->box) return; gimp_progress_set_value (GIMP_PROGRESS (dialog->box), percentage); }
void gimp_progress_update_and_flush (gint min, gint max, gint current, gpointer data) { gimp_progress_set_value (GIMP_PROGRESS (data), (gdouble) (current - min) / (gdouble) (max - min)); while (g_main_context_pending (NULL)) g_main_context_iteration (NULL, TRUE); }
static void gimp_drawable_apply_operation_private (GimpDrawable *drawable, GimpProgress *progress, const gchar *undo_desc, GeglNode *operation, gboolean linear, TileManager *dest_tiles, const GeglRectangle *rect) { GeglNode *gegl; GeglNode *input; GeglNode *output; GeglProcessor *processor; gdouble value; gegl = gegl_node_new (); /* Disable caching on all children of the node unless explicitly re-enabled. */ g_object_set (gegl, "dont-cache", TRUE, NULL); input = gegl_node_new_child (gegl, "operation", "gimp:tilemanager-source", "tile-manager", gimp_drawable_get_tiles (drawable), "linear", linear, NULL); output = gegl_node_new_child (gegl, "operation", "gimp:tilemanager-sink", "tile-manager", dest_tiles, "linear", linear, NULL); gegl_node_add_child (gegl, operation); gegl_node_link_many (input, operation, output, NULL); processor = gegl_node_new_processor (output, rect); if (progress) gimp_progress_start (progress, undo_desc, FALSE); while (gegl_processor_work (processor, &value)) if (progress) gimp_progress_set_value (progress, value); g_object_unref (processor); g_object_unref (gegl); }
void gimp_plug_in_progress_start (GimpPlugIn *plug_in, const gchar *message, GimpObject *display) { GimpPlugInProcFrame *proc_frame; g_return_if_fail (GIMP_IS_PLUG_IN (plug_in)); g_return_if_fail (display == NULL || GIMP_IS_OBJECT (display)); proc_frame = gimp_plug_in_get_proc_frame (plug_in); if (! proc_frame->progress) { proc_frame->progress = gimp_new_progress (plug_in->manager->gimp, display); if (proc_frame->progress) { proc_frame->progress_created = TRUE; g_object_ref (proc_frame->progress); gimp_plug_in_progress_attach (proc_frame->progress); } } if (proc_frame->progress) { if (! proc_frame->progress_cancel_id) proc_frame->progress_cancel_id = g_signal_connect (proc_frame->progress, "cancel", G_CALLBACK (gimp_plug_in_progress_cancel_callback), plug_in); if (gimp_progress_is_active (proc_frame->progress)) { if (message) gimp_progress_set_text (proc_frame->progress, message); if (gimp_progress_get_value (proc_frame->progress) > 0.0) gimp_progress_set_value (proc_frame->progress, 0.0); } else { gimp_progress_start (proc_frame->progress, message ? message : "", TRUE); } } }
static void gimp_tool_progress_set_value (GimpProgress *progress, gdouble percentage) { GimpTool *tool = GIMP_TOOL (progress); if (tool->progress) { GimpDisplayShell *shell = gimp_display_get_shell (tool->progress_display); gimp_progress_set_value (GIMP_PROGRESS (tool->progress), percentage); gimp_widget_flush_expose (shell->canvas); } }
static gboolean file_remote_copy_file (Gimp *gimp, GFile *src_file, GFile *dest_file, RemoteCopyMode mode, GimpProgress *progress, GError **error) { RemoteProgress remote_progress = { 0, }; gboolean success; GError *my_error = NULL; remote_progress.mode = mode; remote_progress.progress = progress; if (progress) { gimp_progress_start (progress, TRUE, _("Opening remote file")); remote_progress.cancellable = g_cancellable_new (); g_signal_connect (progress, "cancel", G_CALLBACK (file_remote_copy_file_cancel), &remote_progress); success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, remote_progress.cancellable, file_remote_progress_callback, &remote_progress, &my_error); g_signal_handlers_disconnect_by_func (progress, file_remote_copy_file_cancel, &remote_progress); g_object_unref (remote_progress.cancellable); gimp_progress_set_value (progress, 1.0); gimp_progress_end (progress); } else { success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &my_error); } return success; }
void gimp_plug_in_progress_set_value (GimpPlugIn *plug_in, gdouble percentage) { GimpPlugInProcFrame *proc_frame; g_return_if_fail (GIMP_IS_PLUG_IN (plug_in)); proc_frame = gimp_plug_in_get_proc_frame (plug_in); if (! proc_frame->progress || ! gimp_progress_is_active (proc_frame->progress) || ! proc_frame->progress_cancel_id) { gimp_plug_in_progress_start (plug_in, NULL, NULL); } if (proc_frame->progress && gimp_progress_is_active (proc_frame->progress)) gimp_progress_set_value (proc_frame->progress, percentage); }
static void gimp_cage_tool_transform_progress (GObject *object, const GParamSpec *pspec, GimpCageTool *ct) { GimpProgress *progress = GIMP_PROGRESS (ct); gdouble value; g_object_get (object, "progress", &value, NULL); if (value == 0.0) { gimp_progress_start (progress, _("Cage Transform"), FALSE); } else if (value == 1.0) { gimp_progress_end (progress); } else { gimp_progress_set_value (progress, value); } }
void gimp_image_convert_precision (GimpImage *image, GimpPrecision precision, gint layer_dither_type, gint text_layer_dither_type, gint mask_dither_type, GimpProgress *progress) { GList *all_drawables; GList *list; const gchar *undo_desc = NULL; gint nth_drawable, n_drawables; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (precision != gimp_image_get_precision (image)); g_return_if_fail (precision == GIMP_PRECISION_U8_GAMMA || gimp_image_get_base_type (image) != GIMP_INDEXED); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); all_drawables = g_list_concat (gimp_image_get_layer_list (image), gimp_image_get_channel_list (image)); n_drawables = g_list_length (all_drawables) + 1 /* + selection */; switch (precision) { case GIMP_PRECISION_U8_LINEAR: undo_desc = C_("undo-type", "Convert Image to 8 bit linear integer"); break; case GIMP_PRECISION_U8_GAMMA: undo_desc = C_("undo-type", "Convert Image to 8 bit gamma integer"); break; case GIMP_PRECISION_U16_LINEAR: undo_desc = C_("undo-type", "Convert Image to 16 bit linear integer"); break; case GIMP_PRECISION_U16_GAMMA: undo_desc = C_("undo-type", "Convert Image to 16 bit gamma integer"); break; case GIMP_PRECISION_U32_LINEAR: undo_desc = C_("undo-type", "Convert Image to 32 bit linear integer"); break; case GIMP_PRECISION_U32_GAMMA: undo_desc = C_("undo-type", "Convert Image to 32 bit gamma integer"); break; case GIMP_PRECISION_HALF_LINEAR: undo_desc = C_("undo-type", "Convert Image to 16 bit linear floating point"); break; case GIMP_PRECISION_HALF_GAMMA: undo_desc = C_("undo-type", "Convert Image to 16 bit gamma floating point"); break; case GIMP_PRECISION_FLOAT_LINEAR: undo_desc = C_("undo-type", "Convert Image to 32 bit linear floating point"); break; case GIMP_PRECISION_FLOAT_GAMMA: undo_desc = C_("undo-type", "Convert Image to 32 bit gamma floating point"); break; case GIMP_PRECISION_DOUBLE_LINEAR: undo_desc = C_("undo-type", "Convert Image to 64 bit linear floating point"); break; case GIMP_PRECISION_DOUBLE_GAMMA: undo_desc = C_("undo-type", "Convert Image to 64 bit gamma floating point"); break; } if (progress) gimp_progress_start (progress, FALSE, "%s", undo_desc); g_object_freeze_notify (G_OBJECT (image)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT, undo_desc); /* Push the image precision to the stack */ gimp_image_undo_push_image_precision (image, NULL); /* Set the new precision */ g_object_set (image, "precision", precision, NULL); for (list = all_drawables, nth_drawable = 0; list; list = g_list_next (list), nth_drawable++) { GimpDrawable *drawable = list->data; gint dither_type; if (gimp_item_is_text_layer (GIMP_ITEM (drawable))) dither_type = text_layer_dither_type; else dither_type = layer_dither_type; gimp_drawable_convert_type (drawable, image, gimp_drawable_get_base_type (drawable), precision, dither_type, mask_dither_type, FALSE, TRUE); if (progress) gimp_progress_set_value (progress, (gdouble) nth_drawable / (gdouble) n_drawables); } g_list_free (all_drawables); /* convert the selection mask */ { GimpChannel *mask = gimp_image_get_mask (image); GeglBuffer *buffer; gimp_image_undo_push_mask_precision (image, NULL, mask); buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_image_get_width (image), gimp_image_get_height (image)), gimp_image_get_mask_format (image)); gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), NULL, GEGL_ABYSS_NONE, buffer, NULL); gimp_drawable_set_buffer (GIMP_DRAWABLE (mask), FALSE, NULL, buffer); g_object_unref (buffer); nth_drawable++; if (progress) gimp_progress_set_value (progress, (gdouble) nth_drawable / (gdouble) n_drawables); } gimp_image_undo_group_end (image); gimp_image_precision_changed (image); g_object_thaw_notify (G_OBJECT (image)); if (progress) gimp_progress_end (progress); }
void gimp_gegl_convert_color_profile (GeglBuffer *src_buffer, const GeglRectangle *src_rect, GimpColorProfile *src_profile, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, GimpColorProfile *dest_profile, GimpColorRenderingIntent intent, gboolean bpc, GimpProgress *progress) { const Babl *src_format; const Babl *dest_format; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; cmsUInt32Number lcms_src_format; cmsUInt32Number lcms_dest_format; cmsUInt32Number flags; cmsHTRANSFORM transform; src_format = gegl_buffer_get_format (src_buffer); dest_format = gegl_buffer_get_format (dest_buffer); if (gimp_color_profile_can_gegl_copy (src_profile, dest_profile)) { gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE, dest_buffer, dest_rect); return; } src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); src_format = gimp_color_profile_get_format (src_format, &lcms_src_format); dest_format = gimp_color_profile_get_format (dest_format, &lcms_dest_format); flags = cmsFLAGS_NOOPTIMIZE; if (bpc) flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; transform = cmsCreateTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, intent, flags); if (transform) { gimp_gegl_convert_color_transform (src_buffer, src_rect, src_format, dest_buffer, dest_rect, dest_format, transform, progress); cmsDeleteTransform (transform); } else { /* FIXME: no idea if this ever happens */ gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE, dest_buffer, dest_rect); if (progress) gimp_progress_set_value (progress, 1.0); } }
void gimp_gegl_convert_color_transform (GeglBuffer *src_buffer, const GeglRectangle *src_rect, const Babl *src_format, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, const Babl *dest_format, GimpColorTransform transform, GimpProgress *progress) { GeglBufferIterator *iter; gboolean has_alpha; gint total_pixels; gint done_pixels = 0; if (src_rect) { total_pixels = src_rect->width * src_rect->height; } else { total_pixels = (gegl_buffer_get_width (src_buffer) * gegl_buffer_get_height (src_buffer)); } has_alpha = babl_format_has_alpha (dest_format); /* make sure the alpha channel is copied too, lcms doesn't copy it */ if (has_alpha) gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE, dest_buffer, dest_rect); iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0, src_format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, dest_format, /* use READWRITE for alpha surfaces * because we must use the alpha channel * that is already copied, see above */ has_alpha ? GEGL_ACCESS_READWRITE: GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { cmsDoTransform (transform, iter->data[0], iter->data[1], iter->length); done_pixels += iter->roi[0].width * iter->roi[0].height; if (progress) gimp_progress_set_value (progress, (gdouble) done_pixels / (gdouble) total_pixels); } if (progress) gimp_progress_set_value (progress, 1.0); }
void gimp_image_flip (GimpImage *image, GimpContext *context, GimpOrientationType flip_type, GimpProgress *progress) { GList *list; gdouble axis; gdouble progress_max; gdouble progress_current = 1.0; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); gimp_set_busy (image->gimp); switch (flip_type) { case GIMP_ORIENTATION_HORIZONTAL: axis = (gdouble) gimp_image_get_width (image) / 2.0; break; case GIMP_ORIENTATION_VERTICAL: axis = (gdouble) gimp_image_get_height (image) / 2.0; break; default: g_warning ("%s: unknown flip_type", G_STRFUNC); return; } progress_max = (image->channels->num_children + image->layers->num_children + image->vectors->num_children + 1 /* selection */); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_FLIP, NULL); /* Flip all channels */ for (list = GIMP_LIST (image->channels)->list; list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_flip (item, context, flip_type, axis, TRUE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Flip all vectors */ for (list = GIMP_LIST (image->vectors)->list; list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_flip (item, context, flip_type, axis, FALSE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Don't forget the selection mask! */ gimp_item_flip (GIMP_ITEM (gimp_image_get_mask (image)), context, flip_type, axis, TRUE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); /* Flip all layers */ for (list = GIMP_LIST (image->layers)->list; list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_flip (item, context, flip_type, axis, FALSE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Flip all Guides */ for (list = gimp_image_get_guides (image); list; list = g_list_next (list)) { GimpGuide *guide = list->data; gint position = gimp_guide_get_position (guide); switch (gimp_guide_get_orientation (guide)) { case GIMP_ORIENTATION_HORIZONTAL: if (flip_type == GIMP_ORIENTATION_VERTICAL) gimp_image_move_guide (image, guide, gimp_image_get_height (image) - position, TRUE); break; case GIMP_ORIENTATION_VERTICAL: if (flip_type == GIMP_ORIENTATION_HORIZONTAL) gimp_image_move_guide (image, guide, gimp_image_get_width (image) - position, TRUE); break; default: break; } } /* Flip all sample points */ for (list = gimp_image_get_sample_points (image); list; list = g_list_next (list)) { GimpSamplePoint *sample_point = list->data; if (flip_type == GIMP_ORIENTATION_VERTICAL) gimp_image_move_sample_point (image, sample_point, sample_point->x, gimp_image_get_height (image) - sample_point->y, TRUE); if (flip_type == GIMP_ORIENTATION_HORIZONTAL) gimp_image_move_sample_point (image, sample_point, gimp_image_get_width (image) - sample_point->x, sample_point->y, TRUE); } gimp_image_undo_group_end (image); gimp_unset_busy (image->gimp); }
static gboolean file_remote_copy_file (Gimp *gimp, GFile *src_file, GFile *dest_file, RemoteCopyMode mode, GimpProgress *progress, GError **error) { RemoteProgress remote_progress = { 0, }; gboolean success; GError *my_error = NULL; remote_progress.mode = mode; remote_progress.progress = progress; if (progress) { remote_progress.cancellable = g_cancellable_new (); gimp_progress_start (progress, TRUE, _("Connecting to server")); g_signal_connect (progress, "cancel", G_CALLBACK (file_remote_copy_file_cancel), &remote_progress); success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, remote_progress.cancellable, file_remote_progress_callback, &remote_progress, &my_error); gimp_progress_set_value (progress, 1.0); } else { success = g_file_copy (src_file, dest_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &my_error); } if (! success && ! gimp->no_interface && my_error && my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_MOUNTED) { g_clear_error (&my_error); if (gimp_mount_enclosing_volume (gimp, mode == DOWNLOAD ? src_file : dest_file, progress, error)) { if (progress) { success = g_file_copy (src_file, dest_file, 0, remote_progress.cancellable, file_remote_progress_callback, &remote_progress, error); } else { success = g_file_copy (src_file, dest_file, 0, NULL, NULL, NULL, error); } } } if (progress) { g_signal_handlers_disconnect_by_func (progress, file_remote_copy_file_cancel, &remote_progress); gimp_progress_end (progress); g_object_unref (remote_progress.cancellable); } return success; }
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); }
void gimp_image_convert_precision (GimpImage *image, GimpPrecision precision, gint layer_dither_type, gint text_layer_dither_type, gint mask_dither_type, GimpProgress *progress) { GimpColorProfile *old_profile; GimpColorProfile *new_profile = NULL; const Babl *old_format; const Babl *new_format; GList *all_drawables; GList *list; const gchar *undo_desc = NULL; GimpProgress *sub_progress = NULL; gint nth_drawable, n_drawables; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (precision != gimp_image_get_precision (image)); g_return_if_fail (precision == GIMP_PRECISION_U8_GAMMA || gimp_image_get_base_type (image) != GIMP_INDEXED); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); all_drawables = g_list_concat (gimp_image_get_layer_list (image), gimp_image_get_channel_list (image)); n_drawables = g_list_length (all_drawables) + 1 /* + selection */; if (progress) sub_progress = gimp_sub_progress_new (progress); switch (precision) { case GIMP_PRECISION_U8_LINEAR: undo_desc = C_("undo-type", "Convert Image to 8 bit linear integer"); break; case GIMP_PRECISION_U8_GAMMA: undo_desc = C_("undo-type", "Convert Image to 8 bit gamma integer"); break; case GIMP_PRECISION_U16_LINEAR: undo_desc = C_("undo-type", "Convert Image to 16 bit linear integer"); break; case GIMP_PRECISION_U16_GAMMA: undo_desc = C_("undo-type", "Convert Image to 16 bit gamma integer"); break; case GIMP_PRECISION_U32_LINEAR: undo_desc = C_("undo-type", "Convert Image to 32 bit linear integer"); break; case GIMP_PRECISION_U32_GAMMA: undo_desc = C_("undo-type", "Convert Image to 32 bit gamma integer"); break; case GIMP_PRECISION_HALF_LINEAR: undo_desc = C_("undo-type", "Convert Image to 16 bit linear floating point"); break; case GIMP_PRECISION_HALF_GAMMA: undo_desc = C_("undo-type", "Convert Image to 16 bit gamma floating point"); break; case GIMP_PRECISION_FLOAT_LINEAR: undo_desc = C_("undo-type", "Convert Image to 32 bit linear floating point"); break; case GIMP_PRECISION_FLOAT_GAMMA: undo_desc = C_("undo-type", "Convert Image to 32 bit gamma floating point"); break; case GIMP_PRECISION_DOUBLE_LINEAR: undo_desc = C_("undo-type", "Convert Image to 64 bit linear floating point"); break; case GIMP_PRECISION_DOUBLE_GAMMA: undo_desc = C_("undo-type", "Convert Image to 64 bit gamma floating point"); break; } if (progress) gimp_progress_start (progress, FALSE, "%s", undo_desc); g_object_freeze_notify (G_OBJECT (image)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT, undo_desc); /* Push the image precision to the stack */ gimp_image_undo_push_image_precision (image, NULL); old_profile = gimp_image_get_color_profile (image); old_format = gimp_image_get_layer_format (image, FALSE); /* Set the new precision */ g_object_set (image, "precision", precision, NULL); new_format = gimp_image_get_layer_format (image, FALSE); if (old_profile && gimp_babl_format_get_linear (old_format) != gimp_babl_format_get_linear (new_format)) { GimpColorProfile *new_profile; /* when converting between linear and gamma, we create a new * profile using the original profile's chromacities and * whitepoint, but a linear/sRGB-gamma TRC. */ if (gimp_babl_format_get_linear (new_format)) { new_profile = gimp_color_profile_new_linear_from_color_profile (old_profile); } else { new_profile = gimp_color_profile_new_srgb_trc_from_color_profile (old_profile); } /* if a new profile cannot be be generated, convert to the * builtin profile, which is better than leaving the user with * broken colors */ if (! new_profile) { new_profile = gimp_image_get_builtin_color_profile (image); g_object_ref (new_profile); } } for (list = all_drawables, nth_drawable = 0; list; list = g_list_next (list), nth_drawable++) { GimpDrawable *drawable = list->data; gint dither_type; if (gimp_item_is_text_layer (GIMP_ITEM (drawable))) dither_type = text_layer_dither_type; else dither_type = layer_dither_type; if (sub_progress) gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress), nth_drawable, n_drawables); gimp_drawable_convert_type (drawable, image, gimp_drawable_get_base_type (drawable), precision, new_profile, dither_type, mask_dither_type, TRUE, sub_progress); } g_list_free (all_drawables); if (old_profile) { gimp_image_set_color_profile (image, new_profile, NULL); g_object_unref (new_profile); } /* convert the selection mask */ { GimpChannel *mask = gimp_image_get_mask (image); GeglBuffer *buffer; if (sub_progress) gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress), nth_drawable, n_drawables); gimp_image_undo_push_mask_precision (image, NULL, mask); buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_image_get_width (image), gimp_image_get_height (image)), gimp_image_get_mask_format (image)); gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), NULL, GEGL_ABYSS_NONE, buffer, NULL); gimp_drawable_set_buffer (GIMP_DRAWABLE (mask), FALSE, NULL, buffer); g_object_unref (buffer); nth_drawable++; } if (sub_progress) gimp_progress_set_value (sub_progress, 1.0); gimp_image_undo_group_end (image); gimp_image_precision_changed (image); g_object_thaw_notify (G_OBJECT (image)); if (sub_progress) g_object_unref (sub_progress); if (progress) gimp_progress_end (progress); }
GeglBuffer * gimp_drawable_foreground_extract (GimpDrawable *drawable, GimpMattingEngine engine, gint global_iterations, gint levin_levels, gint levin_active_levels, GeglBuffer *trimap, GimpProgress *progress) { GeglBuffer *drawable_buffer; GeglNode *gegl; GeglNode *input_node; GeglNode *trimap_node; GeglNode *matting_node; GeglNode *output_node; GeglBuffer *buffer; GeglProcessor *processor; gdouble value; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (GEGL_IS_BUFFER (trimap), NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL); progress = gimp_progress_start (progress, FALSE, _("Computing alpha of unknown pixels")); drawable_buffer = gimp_drawable_get_buffer (drawable); gegl = gegl_node_new (); trimap_node = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", trimap, NULL); input_node = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", drawable_buffer, NULL); output_node = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer, "format", NULL, NULL); if (engine == GIMP_MATTING_ENGINE_GLOBAL) { matting_node = gegl_node_new_child (gegl, "operation", "gegl:matting-global", "iterations", global_iterations, NULL); } else { matting_node = gegl_node_new_child (gegl, "operation", "gegl:matting-levin", "levels", levin_levels, "active_levels", levin_active_levels, NULL); } gegl_node_connect_to (input_node, "output", matting_node, "input"); gegl_node_connect_to (trimap_node, "output", matting_node, "aux"); gegl_node_connect_to (matting_node, "output", output_node, "input"); processor = gegl_node_new_processor (output_node, NULL); while (gegl_processor_work (processor, &value)) { if (progress) gimp_progress_set_value (progress, value); } if (progress) gimp_progress_end (progress); g_object_unref (processor); g_object_unref (gegl); return buffer; }
void gimp_image_rotate (GimpImage *image, GimpContext *context, GimpRotationType rotate_type, GimpProgress *progress) { GList *list; gdouble center_x; gdouble center_y; gdouble progress_max; gdouble progress_current = 1.0; gint new_image_width; gint new_image_height; gint previous_image_width; gint previous_image_height; gint offset_x; gint offset_y; gboolean size_changed; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); gimp_set_busy (image->gimp); previous_image_width = gimp_image_get_width (image); previous_image_height = gimp_image_get_height (image); center_x = previous_image_width / 2.0; center_y = previous_image_height / 2.0; progress_max = (gimp_container_get_n_children (gimp_image_get_channels (image)) + gimp_container_get_n_children (gimp_image_get_layers (image)) + gimp_container_get_n_children (gimp_image_get_vectors (image)) + 1 /* selection */); g_object_freeze_notify (G_OBJECT (image)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ROTATE, NULL); /* Resize the image (if needed) */ switch (rotate_type) { case GIMP_ROTATE_90: case GIMP_ROTATE_270: new_image_width = gimp_image_get_height (image); new_image_height = gimp_image_get_width (image); size_changed = TRUE; offset_x = (gimp_image_get_width (image) - new_image_width) / 2; offset_y = (gimp_image_get_height (image) - new_image_height) / 2; break; case GIMP_ROTATE_180: new_image_width = gimp_image_get_width (image); new_image_height = gimp_image_get_height (image); size_changed = FALSE; offset_x = 0; offset_y = 0; break; default: g_assert_not_reached (); return; } /* Rotate all channels */ for (list = gimp_image_get_channel_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE); gimp_item_set_offset (item, 0, 0); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Rotate all vectors */ for (list = gimp_image_get_vectors_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE); gimp_item_set_offset (item, 0, 0); gimp_item_set_size (item, new_image_width, new_image_height); gimp_item_translate (item, (new_image_width - gimp_image_get_width (image)) / 2, (new_image_height - gimp_image_get_height (image)) / 2, FALSE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Don't forget the selection mask! */ { GimpChannel *mask = gimp_image_get_mask (image); gimp_item_rotate (GIMP_ITEM (mask), context, rotate_type, center_x, center_y, FALSE); gimp_item_set_offset (GIMP_ITEM (mask), 0, 0); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Rotate all layers */ for (list = gimp_image_get_layer_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gint off_x; gint off_y; gimp_item_get_offset (item, &off_x, &off_y); gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE); gimp_image_rotate_item_offset (image, rotate_type, item, off_x, off_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Rotate all Guides */ gimp_image_rotate_guides (image, rotate_type); /* Rotate all sample points */ gimp_image_rotate_sample_points (image, rotate_type); /* Resize the image (if needed) */ if (size_changed) { gdouble xres; gdouble yres; gimp_image_undo_push_image_size (image, NULL, offset_x, offset_y, new_image_width, new_image_height); g_object_set (image, "width", new_image_width, "height", new_image_height, NULL); gimp_image_get_resolution (image, &xres, &yres); if (xres != yres) gimp_image_set_resolution (image, yres, xres); } gimp_image_undo_group_end (image); if (size_changed) gimp_image_size_changed_detailed (image, -offset_x, -offset_y, previous_image_width, previous_image_height); g_object_thaw_notify (G_OBJECT (image)); gimp_unset_busy (image->gimp); }
static void gimp_thumb_box_create_thumbnails (GimpThumbBox *box, gboolean force) { Gimp *gimp = box->imagefile->gimp; GimpProgress *progress = GIMP_PROGRESS (box); GimpFileDialog *dialog = NULL; GtkWidget *toplevel; GSList *list; gint n_uris; gint i; if (gimp->config->thumbnail_size == GIMP_THUMBNAIL_SIZE_NONE) return; toplevel = gtk_widget_get_toplevel (GTK_WIDGET (box)); if (GIMP_IS_FILE_DIALOG (toplevel)) dialog = GIMP_FILE_DIALOG (toplevel); gimp_set_busy (gimp); if (dialog) gimp_file_dialog_set_sensitive (dialog, FALSE); else gtk_widget_set_sensitive (toplevel, FALSE); if (box->uris) { gtk_widget_hide (box->info); gtk_widget_show (box->progress); } n_uris = g_slist_length (box->uris); if (n_uris > 1) { gchar *str; gimp_progress_start (GIMP_PROGRESS (box), "", TRUE); progress = gimp_sub_progress_new (GIMP_PROGRESS (box)); gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (progress), 0, n_uris); for (list = box->uris->next, i = 1; list; list = g_slist_next (list), i++) { str = g_strdup_printf (_("Thumbnail %d of %d"), i, n_uris); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), str); g_free (str); gimp_progress_set_value (progress, 0.0); while (gtk_events_pending ()) gtk_main_iteration (); gimp_thumb_box_create_thumbnail (box, list->data, gimp->config->thumbnail_size, force, progress); if (dialog && dialog->canceled) goto canceled; gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (progress), i, n_uris); } str = g_strdup_printf (_("Thumbnail %d of %d"), n_uris, n_uris); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), str); g_free (str); gimp_progress_set_value (progress, 0.0); while (gtk_events_pending ()) gtk_main_iteration (); } if (box->uris) { gimp_thumb_box_create_thumbnail (box, box->uris->data, gimp->config->thumbnail_size, force, progress); gimp_progress_set_value (progress, 1.0); } canceled: if (n_uris > 1) { g_object_unref (progress); gimp_progress_end (GIMP_PROGRESS (box)); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), ""); } if (box->uris) { gtk_widget_hide (box->progress); gtk_widget_show (box->info); } if (dialog) gimp_file_dialog_set_sensitive (dialog, TRUE); else gtk_widget_set_sensitive (toplevel, TRUE); gimp_unset_busy (gimp); }
void gimp_image_resize_with_layers (GimpImage *image, GimpContext *context, gint new_width, gint new_height, gint offset_x, gint offset_y, GimpItemSet layer_set, gboolean resize_text_layers, GimpProgress *progress) { GList *list; GList *resize_layers; gdouble progress_max; gdouble progress_current = 1.0; gint old_width, old_height; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (new_width > 0 && new_height > 0); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); gimp_set_busy (image->gimp); g_object_freeze_notify (G_OBJECT (image)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_RESIZE, C_("undo-type", "Resize Image")); resize_layers = gimp_image_item_list_get_list (image, NULL, GIMP_ITEM_TYPE_LAYERS, layer_set); progress_max = (gimp_container_get_n_children (gimp_image_get_layers (image)) + gimp_container_get_n_children (gimp_image_get_channels (image)) + gimp_container_get_n_children (gimp_image_get_vectors (image)) + g_list_length (resize_layers) + 1 /* selection */); old_width = gimp_image_get_width (image); old_height = gimp_image_get_height (image); /* Push the image size to the stack */ gimp_image_undo_push_image_size (image, NULL, -offset_x, -offset_y, new_width, new_height); /* Set the new width and height */ g_object_set (image, "width", new_width, "height", new_height, NULL); /* Resize all channels */ for (list = gimp_image_get_channel_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_resize (item, context, new_width, new_height, offset_x, offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Resize all vectors */ for (list = gimp_image_get_vectors_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_resize (item, context, new_width, new_height, offset_x, offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Don't forget the selection mask! */ gimp_item_resize (GIMP_ITEM (gimp_image_get_mask (image)), context, new_width, new_height, offset_x, offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); /* Reposition all layers */ for (list = gimp_image_get_layer_iter (image); list; list = g_list_next (list)) { GimpItem *item = list->data; gimp_item_translate (item, offset_x, offset_y, TRUE); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } /* Resize all resize_layers to image size */ for (list = resize_layers; list; list = g_list_next (list)) { GimpItem *item = list->data; gint old_offset_x; gint old_offset_y; /* group layers can't be resized here */ if (gimp_viewable_get_children (GIMP_VIEWABLE (item))) continue; if (! resize_text_layers && gimp_item_is_text_layer (item)) continue; gimp_item_get_offset (item, &old_offset_x, &old_offset_y); gimp_item_resize (item, context, new_width, new_height, old_offset_x, old_offset_y); if (progress) gimp_progress_set_value (progress, progress_current++ / progress_max); } g_list_free (resize_layers); /* Reposition or remove all guides */ list = gimp_image_get_guides (image); while (list) { GimpGuide *guide = list->data; gboolean remove_guide = FALSE; gint new_position = gimp_guide_get_position (guide); list = g_list_next (list); switch (gimp_guide_get_orientation (guide)) { case GIMP_ORIENTATION_HORIZONTAL: new_position += offset_y; if (new_position < 0 || new_position > new_height) remove_guide = TRUE; break; case GIMP_ORIENTATION_VERTICAL: new_position += offset_x; if (new_position < 0 || new_position > new_width) remove_guide = TRUE; break; default: break; } if (remove_guide) gimp_image_remove_guide (image, guide, TRUE); else if (new_position != gimp_guide_get_position (guide)) gimp_image_move_guide (image, guide, new_position, TRUE); } /* Reposition or remove sample points */ list = gimp_image_get_sample_points (image); while (list) { GimpSamplePoint *sample_point = list->data; gboolean remove_sample_point = FALSE; gint new_x = sample_point->x; gint new_y = sample_point->y; list = g_list_next (list); new_y += offset_y; if ((sample_point->y < 0) || (sample_point->y > new_height)) remove_sample_point = TRUE; new_x += offset_x; if ((sample_point->x < 0) || (sample_point->x > new_width)) remove_sample_point = TRUE; if (remove_sample_point) gimp_image_remove_sample_point (image, sample_point, TRUE); else if (new_x != sample_point->x || new_y != sample_point->y) gimp_image_move_sample_point (image, sample_point, new_x, new_y, TRUE); } gimp_image_undo_group_end (image); gimp_image_size_changed_detailed (image, offset_x, offset_y, old_width, old_height); g_object_thaw_notify (G_OBJECT (image)); gimp_unset_busy (image->gimp); }
static void gimp_image_convert_profile_rgb (GimpImage *image, GimpColorProfile *src_profile, GimpColorProfile *dest_profile, GimpColorRenderingIntent intent, gboolean bpc, GimpProgress *progress) { GList *layers; GList *list; gint n_drawables; gint nth_drawable; layers = gimp_image_get_layer_list (image); n_drawables = g_list_length (layers); for (list = layers, nth_drawable = 0; list; list = g_list_next (list), nth_drawable++) { GimpDrawable *drawable = list->data; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; const Babl *iter_format; cmsUInt32Number lcms_format; cmsUInt32Number flags; cmsHTRANSFORM transform; if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) continue; src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); iter_format = gimp_color_profile_get_format (gimp_drawable_get_format (drawable), &lcms_format); flags = cmsFLAGS_NOOPTIMIZE; if (bpc) flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; transform = cmsCreateTransform (src_lcms, lcms_format, dest_lcms, lcms_format, intent, flags); if (transform) { GeglBuffer *buffer; GeglBufferIterator *iter; buffer = gimp_drawable_get_buffer (drawable); gimp_drawable_push_undo (drawable, NULL, NULL, 0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)); iter = gegl_buffer_iterator_new (buffer, NULL, 0, iter_format, GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { cmsDoTransform (transform, iter->data[0], iter->data[0], iter->length); } gimp_drawable_update (drawable, 0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)); cmsDeleteTransform (transform); } if (progress) gimp_progress_set_value (progress, (gdouble) nth_drawable / (gdouble) n_drawables); } g_list_free (layers); }
static void gimp_seamless_clone_tool_filter_update (GimpSeamlessCloneTool *sc) { GimpTool *tool = GIMP_TOOL (sc); GimpDisplayShell *shell = gimp_display_get_shell (tool->display); GimpItem *item = GIMP_ITEM (tool->drawable); gint x, y; gint w, h; gint off_x, off_y; GeglRectangle visible; GeglOperation *op = NULL; GimpProgress *progress; GeglNode *output; GeglProcessor *processor; gdouble value; progress = gimp_progress_start (GIMP_PROGRESS (sc), FALSE, _("Cloning the foreground object")); /* Find out at which x,y is the top left corner of the currently * displayed part */ gimp_display_shell_untransform_viewport (shell, &x, &y, &w, &h); /* Find out where is our drawable positioned */ gimp_item_get_offset (item, &off_x, &off_y); /* Create a rectangle from the intersection of the currently displayed * part with the drawable */ gimp_rectangle_intersect (x, y, w, h, off_x, off_y, gimp_item_get_width (item), gimp_item_get_height (item), &visible.x, &visible.y, &visible.width, &visible.height); /* Since the filter_apply function receives a rectangle describing * where it should update the preview, and since that rectangle should * be relative to the drawable's location, we now offset back by the * drawable's offsetts. */ visible.x -= off_x; visible.y -= off_y; g_object_get (sc->sc_node, "gegl-operation", &op, NULL); /* If any cache of the visible area was present, clear it! * We need to clear the cache in the sc_node, since that is * where the previous paste was located */ gegl_operation_invalidate (op, &visible, TRUE); g_object_unref (op); /* Now update the image map and show this area */ gimp_drawable_filter_apply (sc->filter, NULL); /* Show update progress. */ output = gegl_node_get_output_proxy (sc->render_node, "output"); processor = gegl_node_new_processor (output, NULL); while (gegl_processor_work (processor, &value)) { if (progress) gimp_progress_set_value (progress, value); } if (progress) gimp_progress_end (progress); g_object_unref (processor); }
static void file_remote_progress_callback (goffset current_num_bytes, goffset total_num_bytes, gpointer user_data) { RemoteProgress *progress = user_data; GTimeVal now; /* update the progress only up to 10 times a second */ g_get_current_time (&now); if (progress->last_time.tv_sec && ((now.tv_sec - progress->last_time.tv_sec) * 1000 + (now.tv_usec - progress->last_time.tv_usec) / 1000) < 100) return; progress->last_time = now; if (total_num_bytes > 0) { const gchar *format; gchar *done = g_format_size (current_num_bytes); gchar *total = g_format_size (total_num_bytes); switch (progress->mode) { case DOWNLOAD: format = _("Downloading image (%s of %s)"); break; case UPLOAD: format = _("Uploading image (%s of %s)"); break; default: g_assert_not_reached (); } gimp_progress_set_text (progress->progress, format, done, total); g_free (total); g_free (done); gimp_progress_set_value (progress->progress, (gdouble) current_num_bytes / (gdouble) total_num_bytes); } else { const gchar *format; gchar *done = g_format_size (current_num_bytes); switch (progress->mode) { case DOWNLOAD: format = _("Downloaded %s of image data"); break; case UPLOAD: format = _("Uploaded %s of image data"); break; default: g_assert_not_reached (); } gimp_progress_set_text (progress->progress, format, done); g_free (done); gimp_progress_pulse (progress->progress); } while (! progress->cancel && g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); }
static void gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select, GimpDisplay *display) { GimpTool *tool = GIMP_TOOL (fg_select); GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool); GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GeglBuffer *trimap_buffer; GeglBuffer *drawable_buffer; GeglNode *gegl; GeglNode *matting_node; GeglNode *input_image; GeglNode *input_trimap; GeglNode *output_mask; GeglBuffer *buffer; GimpProgress *progress; GeglProcessor *processor; gdouble value; if (fg_select->mask) { g_object_unref (fg_select->mask); fg_select->mask = NULL; } progress = gimp_progress_start (GIMP_PROGRESS (fg_select), _("Computing alpha of unknown pixels"), FALSE); trimap_buffer = fg_select->trimap; drawable_buffer = gimp_drawable_get_buffer (drawable); gegl = gegl_node_new (); input_trimap = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", trimap_buffer, NULL); input_image = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", drawable_buffer, NULL); output_mask = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer, "format", NULL, NULL); if (options->engine == GIMP_MATTING_ENGINE_GLOBAL) { matting_node = gegl_node_new_child (gegl, "operation", "gegl:matting-global", "iterations", options->iterations, NULL); } else { matting_node = gegl_node_new_child (gegl, "operation", "gegl:matting-levin", "levels", options->levels, "active_levels", options->active_levels, NULL); } gegl_node_connect_to (input_image, "output", matting_node, "input"); gegl_node_connect_to (input_trimap, "output", matting_node, "aux"); gegl_node_connect_to (matting_node, "output", output_mask, "input"); processor = gegl_node_new_processor (output_mask, NULL); while (gegl_processor_work (processor, &value)) { if (progress) gimp_progress_set_value (progress, value); } if (progress) gimp_progress_end (progress); g_object_unref (processor); fg_select->mask = buffer; gimp_foreground_select_tool_set_preview (fg_select, display); g_object_unref (gegl); }