Example #1
0
static void
gimp_blend_tool_button_release (GimpTool              *tool,
                                const GimpCoords      *coords,
                                guint32                time,
                                GdkModifierType        state,
                                GimpButtonReleaseType  release_type,
                                GimpDisplay           *display)
{
    GimpBlendTool    *blend_tool    = GIMP_BLEND_TOOL (tool);
    GimpBlendOptions *options       = GIMP_BLEND_TOOL_GET_OPTIONS (tool);
    GimpPaintOptions *paint_options = GIMP_PAINT_OPTIONS (options);
    GimpContext      *context       = GIMP_CONTEXT (options);
    GimpImage        *image         = gimp_display_get_image (display);

    gimp_tool_pop_status (tool, display);

    gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));

    gimp_tool_control_halt (tool->control);

    if ((release_type != GIMP_BUTTON_RELEASE_CANCEL) &&
            ((blend_tool->start_x != blend_tool->end_x) ||
             (blend_tool->start_y != blend_tool->end_y)))
    {
        GimpDrawable *drawable = gimp_image_get_active_drawable (image);
        GimpProgress *progress;
        gint          off_x;
        gint          off_y;

        progress = gimp_progress_start (GIMP_PROGRESS (tool),
                                        _("Blending"), FALSE);

        gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);

        gimp_drawable_blend (drawable,
                             context,
                             GIMP_CUSTOM_MODE,
                             gimp_context_get_paint_mode (context),
                             options->gradient_type,
                             gimp_context_get_opacity (context),
                             options->offset,
                             paint_options->gradient_options->gradient_repeat,
                             paint_options->gradient_options->gradient_reverse,
                             options->supersample,
                             options->supersample_depth,
                             options->supersample_threshold,
                             options->dither,
                             blend_tool->start_x - off_x,
                             blend_tool->start_y - off_y,
                             blend_tool->end_x - off_x,
                             blend_tool->end_y - off_y,
                             progress);

        if (progress)
            gimp_progress_end (progress);

        gimp_image_flush (image);
    }

    tool->display  = NULL;
    tool->drawable = NULL;
}
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);
}
Example #3
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam  values[MAX_EXTRACT_IMAGES + 1];
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  gint32            num_images;
  gint32            image_ID_extract[MAX_EXTRACT_IMAGES];
  gint32            layer_ID_extract[MAX_EXTRACT_IMAGES];
  gint              j;
  gint32            layer;
  gint32            num_layers;
  gint32            image_ID;

  INIT_I18N ();
  gegl_init (NULL, NULL);

  run_mode = param[0].data.d_int32;
  image_ID = param[1].data.d_image;
  layer    = param[2].data.d_drawable;

  *nreturn_vals = MAX_EXTRACT_IMAGES + 1;
  *return_vals  = values;

  values[0].type          = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  for (j = 0; j < MAX_EXTRACT_IMAGES; j++)
    {
      values[j+1].type         = GIMP_PDB_IMAGE;
      values[j+1].data.d_int32 = -1;
    }

  switch (run_mode)
    {
    case GIMP_RUN_INTERACTIVE:
      /*  Possibly retrieve data  */
      gimp_get_data (PLUG_IN_PROC, &decovals);

      /*  First acquire information with a dialog  */
      if (! decompose_dialog ())
        return;
      break;

    case GIMP_RUN_NONINTERACTIVE:
      /*  Make sure all the arguments are there!  */
      if (nparams != 4 && nparams != 5 && nparams != 6)
        {
          status = GIMP_PDB_CALLING_ERROR;
        }
      else
        {
          strncpy (decovals.extract_type, param[3].data.d_string,
                   sizeof (decovals.extract_type));
          decovals.extract_type[sizeof (decovals.extract_type) - 1] = '\0';

          decovals.as_layers = nparams > 4 ? param[4].data.d_int32 : FALSE;
          decovals.use_registration = (strcmp (name, PLUG_IN_PROC_REG) == 0);
        }
      break;

    case GIMP_RUN_WITH_LAST_VALS:
      /*  Possibly retrieve data  */
      gimp_get_data (PLUG_IN_PROC, &decovals);
      break;

    default:
      break;
    }

  if (status == GIMP_PDB_SUCCESS)
    {
      gimp_progress_init (_("Decomposing"));

      num_images = decompose (image_ID, layer,
                              decovals.extract_type,
                              image_ID_extract,
                              &num_layers,
                              layer_ID_extract);

      if (num_images <= 0)
        {
          status = GIMP_PDB_EXECUTION_ERROR;
        }
      else
        {
          /* create decompose-data parasite */
          GString *data = g_string_new ("");

          g_string_printf (data, "source=%d type=%s ",
                           layer, decovals.extract_type);

          for (j = 0; j < num_layers; j++)
            g_string_append_printf (data, "%d ", layer_ID_extract[j]);

          for (j = 0; j < num_images; j++)
            {
              GimpParasite *parasite;

              values[j+1].data.d_int32 = image_ID_extract[j];

              gimp_image_undo_enable (image_ID_extract[j]);
              gimp_image_clean_all (image_ID_extract[j]);

              parasite = gimp_parasite_new ("decompose-data",
                                            0, data->len + 1, data->str);
              gimp_image_attach_parasite (image_ID_extract[j], parasite);
              gimp_parasite_free (parasite);

              if (run_mode != GIMP_RUN_NONINTERACTIVE)
                gimp_display_new (image_ID_extract[j]);
            }

          /*  Store data  */
          if (run_mode == GIMP_RUN_INTERACTIVE)
            gimp_set_data (PLUG_IN_PROC, &decovals, sizeof (DecoVals));
        }

      gimp_progress_end ();
    }

  values[0].data.d_status = status;
}
Example #4
0
static GimpValueArray *
transform_2d_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpDrawable *drawable;
  gboolean interpolation;
  gdouble source_x;
  gdouble source_y;
  gdouble scale_x;
  gdouble scale_y;
  gdouble angle;
  gdouble dest_x;
  gdouble dest_y;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  interpolation = g_value_get_boolean (gimp_value_array_index (args, 1));
  source_x = g_value_get_double (gimp_value_array_index (args, 2));
  source_y = g_value_get_double (gimp_value_array_index (args, 3));
  scale_x = g_value_get_double (gimp_value_array_index (args, 4));
  scale_y = g_value_get_double (gimp_value_array_index (args, 5));
  angle = g_value_get_double (gimp_value_array_index (args, 6));
  dest_x = g_value_get_double (gimp_value_array_index (args, 7));
  dest_y = g_value_get_double (gimp_value_array_index (args, 8));

  if (success)
    {
      gint x, y, width, height;

      success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error);

      if (success &&
          gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
        {
          GimpMatrix3           matrix;
          GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;

          /* Assemble the transformation matrix */
          gimp_matrix3_identity  (&matrix);
          gimp_matrix3_translate (&matrix, -source_x, -source_y);
          gimp_matrix3_scale     (&matrix, scale_x, scale_y);
          gimp_matrix3_rotate    (&matrix, angle);
          gimp_matrix3_translate (&matrix, dest_x, dest_y);

          if (interpolation)
            interpolation_type = gimp->config->interpolation_type;

          if (progress)
            gimp_progress_start (progress, _("2D Transform"), FALSE);

          if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
              ! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
            {
              if (! gimp_drawable_transform_affine (drawable, context,
                                                    &matrix, GIMP_TRANSFORM_FORWARD,
                                                    interpolation_type, 3,
                                                    FALSE, progress))
                {
                  success = FALSE;
                }
            }
          else
            {
              gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
                                   GIMP_TRANSFORM_FORWARD,
                                   interpolation, 3,
                                   FALSE, progress);
            }

          if (progress)
            gimp_progress_end (progress);
        }
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_drawable (gimp_value_array_index (return_vals, 1), drawable);

  return return_vals;
}
Example #5
0
gboolean
gimp_image_convert_color_profile (GimpImage                *image,
                                  GimpColorProfile         *dest_profile,
                                  GimpColorRenderingIntent  intent,
                                  gboolean                  bpc,
                                  GimpProgress             *progress,
                                  GError                  **error)
{
  GimpColorProfile *src_profile;
  GimpColorProfile *builtin_profile;
  const Babl       *layer_format;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (dest_profile != NULL, FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (! gimp_image_validate_color_profile (image, dest_profile, error))
    return FALSE;

  src_profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image));

  if (gimp_color_profile_is_equal (src_profile, dest_profile))
    {
      g_object_unref (src_profile);
      return TRUE;
    }

  if (progress)
    gimp_progress_start (progress, FALSE,
                         _("Converting from '%s' to '%s'"),
                         gimp_color_profile_get_label (src_profile),
                         gimp_color_profile_get_label (dest_profile));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               _("Color profile conversion"));

  layer_format = gimp_image_get_layer_format (image, FALSE);

  if (gimp_babl_format_get_linear (layer_format))
    builtin_profile = gimp_color_profile_new_linear_rgb ();
  else
    builtin_profile = gimp_color_profile_new_srgb ();

  if (gimp_color_profile_is_equal (dest_profile, builtin_profile))
    {
      /*  don't tag the image with the built-in profile  */
      gimp_image_set_color_profile (image, NULL, NULL);
    }
  else
    {
      gimp_image_set_color_profile (image, dest_profile, NULL);
    }

  g_object_unref (builtin_profile);

  /*  omg...  */
  gimp_image_parasite_detach (image, "icc-profile-name");

  switch (gimp_image_get_base_type (image))
    {
    case GIMP_RGB:
      gimp_image_convert_profile_rgb (image,
                                      src_profile, dest_profile,
                                      intent, bpc,
                                      progress);
      break;

    case GIMP_GRAY:
      break;

    case GIMP_INDEXED:
      gimp_image_convert_profile_indexed (image,
                                          src_profile, dest_profile,
                                          intent, bpc,
                                          progress);
      break;
    }

  gimp_image_undo_group_end (image);

  if (progress)
    gimp_progress_end (progress);

  g_object_unref (src_profile);

  return TRUE;
}
Example #6
0
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, undo_desc, FALSE);

  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,
                                  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,
                      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);
}
Example #7
0
File: xcf.c Project: alfanak/gimp
static GimpValueArray *
xcf_save_invoker (GimpProcedure         *procedure,
                  Gimp                  *gimp,
                  GimpContext           *context,
                  GimpProgress          *progress,
                  const GimpValueArray  *args,
                  GError               **error)
{
  XcfInfo         info = { 0, };
  GimpValueArray *return_vals;
  GimpImage      *image;
  const gchar    *uri;
  gchar          *filename;
  GFile          *file;
  gboolean        success  = FALSE;
  GError         *my_error = NULL;

  gimp_set_busy (gimp);

  image    = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  uri      = g_value_get_string (gimp_value_array_index (args, 3));
#ifdef GIO_IS_FIXED
  file     = g_file_new_for_uri (uri);
#else
  file     = g_file_new_for_path (uri);
#endif
  filename = g_file_get_parse_name (file);

  info.output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, 0, NULL,
                                                 &my_error));

  if (info.output)
    {
      info.gimp        = gimp;
      info.seekable    = G_SEEKABLE (info.output);
      info.progress    = progress;
      info.filename    = filename;
      info.compression = COMPRESS_RLE;

      if (progress)
        {
          gchar *name = g_filename_display_name (filename);
          gchar *msg  = g_strdup_printf (_("Saving '%s'"), name);

          gimp_progress_start (progress, msg, FALSE);

          g_free (msg);
          g_free (name);
        }

      xcf_save_choose_format (&info, image);

      success = xcf_save_image (&info, image, error);

      g_object_unref (info.output);

      if (progress)
        gimp_progress_end (progress);
    }
  else
    {
      g_propagate_prefixed_error (error, my_error,
                                  _("Could not open '%s' for writing: "),
                                  filename);
    }

  g_free (filename);
  g_object_unref (file);

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  gimp_unset_busy (gimp);

  return return_vals;
}
Example #8
0
static void
load_help_progress_end (gpointer user_data)
{
  gimp_progress_end ();
}
static void
color_profile_dialog_response (GtkWidget     *widget,
                               gint           response_id,
                               ProfileDialog *dialog)
{
  gboolean  success = TRUE;
  GError   *error   = NULL;

  if (response_id == GTK_RESPONSE_OK)
    {
      GimpColorProfile *dest_profile = NULL;
      GFile            *file;

      file = gimp_color_profile_combo_box_get_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (dialog->combo));

      if (file)
        {
          dest_profile = gimp_color_profile_new_from_file (file, &error);

          if (! dest_profile)
            success = FALSE;

          g_object_unref (file);
        }
      else
        {
          dest_profile = gimp_image_get_builtin_color_profile (dialog->image);
          g_object_ref (dest_profile);
        }

      if (success)
        {
          if (dialog->convert)
            {
              GimpProgress *progress;
              const gchar  *label;

              label = gimp_color_profile_get_label (dest_profile);

              progress = gimp_progress_start (dialog->progress, FALSE,
                                              _("Converting to '%s'"), label);

              success = gimp_image_convert_color_profile (dialog->image,
                                                          dest_profile,
                                                          dialog->intent,
                                                          dialog->bpc,
                                                          progress,
                                                          &error);

              if (progress)
                gimp_progress_end (progress);

              if (success)
                {
                  saved_intent = dialog->intent;
                  saved_bpc    = dialog->bpc;
                }
            }
          else
            {
              gimp_image_undo_group_start (dialog->image,
                                           GIMP_UNDO_GROUP_PARASITE_ATTACH,
                                           _("Assign color profile"));

              success = gimp_image_set_color_profile (dialog->image,
                                                      dest_profile,
                                                      &error);

              /*  omg...  */
              if (success)
                gimp_image_parasite_detach (dialog->image, "icc-profile-name");

              gimp_image_undo_group_end (dialog->image);

              if (! success)
                gimp_image_undo (dialog->image);
            }

          if (success)
            gimp_image_flush (dialog->image);

          g_object_unref (dest_profile);
        }
    }

  if (success)
    {
      gtk_widget_destroy (dialog->dialog);
    }
  else
    {
      gimp_message (dialog->image->gimp, G_OBJECT (dialog->dialog),
                    GIMP_MESSAGE_ERROR,
                    "%s", error->message);
      g_clear_error (&error);
    }
}
Example #10
0
static void
gimp_seamless_clone_tool_image_map_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),
                                  _("Cloning the foreground object..."),
                                  FALSE);

  /* 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 image_map_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_image_map_apply (sc->image_map, 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);
}
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;
}
Example #12
0
static void
gimp_warp_tool_animate (GimpWarpTool *wt)
{
  GimpTool        *tool    = GIMP_TOOL (wt);
  GimpWarpOptions *options = GIMP_WARP_TOOL_GET_OPTIONS (wt);
  GimpImage       *orig_image;
  GimpImage       *image;
  GimpLayer       *layer;
  GimpLayer       *first_layer;
  GeglNode        *scale_node;
  GimpProgress    *progress;
  GtkWidget       *widget;
  gint             i;

  if (! gimp_warp_tool_get_undo_desc (tool, tool->display))
    {
      gimp_tool_message_literal (tool, tool->display,
                                 _("Please add some warp strokes first."));
      return;
    }

  /*  get rid of the image map so we can use wt->graph  */
  if (wt->image_map)
    {
      gimp_image_map_abort (wt->image_map);
      g_object_unref (wt->image_map);
      wt->image_map = NULL;
    }

  gimp_progress_start (GIMP_PROGRESS (tool), FALSE,
                       _("Rendering Frame %d"), 1);

  orig_image = gimp_item_get_image (GIMP_ITEM (tool->drawable));

  image = gimp_create_image (orig_image->gimp,
                             gimp_item_get_width  (GIMP_ITEM (tool->drawable)),
                             gimp_item_get_height (GIMP_ITEM (tool->drawable)),
                             gimp_drawable_get_base_type (tool->drawable),
                             gimp_drawable_get_precision (tool->drawable),
                             TRUE);

  /*  the first frame is always the unwarped image  */
  layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (tool->drawable), image,
                                         GIMP_TYPE_LAYER));
  gimp_object_take_name (GIMP_OBJECT (layer),
                         g_strdup_printf (_("Frame %d"), 1));

  gimp_item_set_offset (GIMP_ITEM (layer), 0, 0);
  gimp_item_set_visible (GIMP_ITEM (layer), TRUE, FALSE);
  gimp_layer_set_mode (layer, GIMP_NORMAL_MODE, FALSE);
  gimp_layer_set_opacity (layer, GIMP_OPACITY_OPAQUE, FALSE);
  gimp_image_add_layer (image, layer, NULL, 0, FALSE);

  first_layer = layer;

  scale_node = gegl_node_new_child (NULL,
                                    "operation",    "gimp:scalar-multiply",
                                    "n-components", 2,
                                    NULL);
  gimp_warp_tool_add_op (wt, scale_node);

  progress = gimp_sub_progress_new (GIMP_PROGRESS (tool));

  for (i = 1; i < options->n_animation_frames; i++)
    {
      gimp_progress_set_text (GIMP_PROGRESS (tool),
                              _("Rendering Frame %d"), i + 1);

      gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (progress),
                                  i, options->n_animation_frames);

      layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (first_layer),
                                               GIMP_TYPE_LAYER));
      gimp_object_take_name (GIMP_OBJECT (layer),
                             g_strdup_printf (_("Frame %d"), i + 1));

      gegl_node_set (scale_node,
                     "factor", (gdouble) i /
                               (gdouble) (options->n_animation_frames - 1),
                     NULL);

      gimp_gegl_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (first_layer)),
                                 progress,
                                 _("Frame"),
                                 wt->graph,
                                 gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
                                 NULL);

      gimp_image_add_layer (image, layer, NULL, 0, FALSE);
    }

  g_object_unref (progress);

  gimp_warp_tool_remove_op (wt, scale_node);

  gimp_progress_end (GIMP_PROGRESS (tool));

  /*  recreate the image map  */
  gimp_warp_tool_create_image_map (wt, tool->drawable);
  gimp_image_map_apply (wt->image_map, NULL);

  widget = GTK_WIDGET (gimp_display_get_shell (tool->display));
  gimp_create_display (orig_image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                       G_OBJECT (gtk_widget_get_screen (widget)),
                       gimp_widget_get_monitor (widget));
  g_object_unref (image);
}
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;
}
Example #14
0
gboolean
file_remote_mount_file (Gimp          *gimp,
                        GFile         *file,
                        GimpProgress  *progress,
                        GError       **error)
{
  GMountOperation *operation;
  RemoteMount      mount = { 0, };

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  mount.progress  = progress;
  mount.main_loop = g_main_loop_new (NULL, FALSE);

  operation = gimp_get_mount_operation (gimp, progress);

  if (progress)
    {
      gimp_progress_start (progress, TRUE, _("Mounting remote volume"));

      mount.cancellable = g_cancellable_new ();

      g_signal_connect (progress, "cancel",
                        G_CALLBACK (file_remote_mount_file_cancel),
                        &mount);
    }

  g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
                                 operation, mount.cancellable,
                                 (GAsyncReadyCallback) file_remote_mount_volume_ready,
                                 &mount);

  g_main_loop_run (mount.main_loop);
  g_main_loop_unref (mount.main_loop);

  if (progress)
    {
      g_signal_handlers_disconnect_by_func (progress,
                                            file_remote_mount_file_cancel,
                                            &mount);

      g_object_unref (mount.cancellable);

      gimp_progress_end (progress);
    }

  g_object_unref (operation);

  if (mount.error)
    {
      if (mount.error->domain != G_IO_ERROR ||
          mount.error->code   != G_IO_ERROR_ALREADY_MOUNTED)
        {
          g_propagate_error (error, mount.error);
          return FALSE;
        }
      else
        {
          g_clear_error (&mount.error);
        }
    }

  return TRUE;
}
Example #15
0
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);
}
Example #16
0
static GimpValueArray *
xcf_save_invoker (GimpProcedure         *procedure,
                  Gimp                  *gimp,
                  GimpContext           *context,
                  GimpProgress          *progress,
                  const GimpValueArray  *args,
                  GError               **error)
{
  XcfInfo         info = { 0, };
  GimpValueArray *return_vals;
  GimpImage      *image;
  const gchar    *uri;
  GFile          *file;
  gboolean        success  = FALSE;
  GError         *my_error = NULL;

  gimp_set_busy (gimp);

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  uri   = g_value_get_string (gimp_value_array_index (args, 3));
  file  = g_file_new_for_uri (uri);

  info.output = G_OUTPUT_STREAM (g_file_replace (file,
                                                 NULL, FALSE, G_FILE_CREATE_NONE,
                                                 NULL, &my_error));

  if (info.output)
    {
      gboolean compat_mode = gimp_image_get_xcf_compat_mode (image);

      info.gimp     = gimp;
      info.seekable = G_SEEKABLE (info.output);
      info.progress = progress;
      info.file     = file;

      if (compat_mode)
        info.compression = COMPRESS_RLE;
      else
        info.compression = COMPRESS_ZLIB;

      info.file_version = gimp_image_get_xcf_version (image,
                                                      info.compression ==
                                                      COMPRESS_ZLIB,
                                                      NULL, NULL);

      if (progress)
        gimp_progress_start (progress, FALSE, _("Saving '%s'"),
                             gimp_file_get_utf8_name (file));

      success = xcf_save_image (&info, image, &my_error);

      if (success)
        {
          if (progress)
            gimp_progress_set_text (progress, _("Closing '%s'"),
                                    gimp_file_get_utf8_name (file));

          success = g_output_stream_close (info.output, NULL, &my_error);
        }

      if (! success)
        g_propagate_prefixed_error (error, my_error,
                                    _("Error writing '%s': "),
                                    gimp_file_get_utf8_name (file));

      g_object_unref (info.output);

      if (progress)
        gimp_progress_end (progress);
    }
  else
    {
      g_propagate_prefixed_error (error, my_error,
                                  _("Error creating '%s': "),
                                  gimp_file_get_utf8_name (file));
    }

  g_object_unref (file);

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  gimp_unset_busy (gimp);

  return return_vals;
}
Example #17
0
gboolean
gimp_image_convert_color_profile (GimpImage                *image,
                                  GimpColorProfile         *dest_profile,
                                  GimpColorRenderingIntent  intent,
                                  gboolean                  bpc,
                                  GimpProgress             *progress,
                                  GError                  **error)
{
  GimpColorProfile *src_profile;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (! gimp_image_validate_color_profile (image, dest_profile, NULL, error))
    return FALSE;

  src_profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image));

  if (! src_profile || gimp_color_profile_is_equal (src_profile, dest_profile))
    return TRUE;

  if (progress)
    gimp_progress_start (progress, FALSE,
                         _("Converting from '%s' to '%s'"),
                         gimp_color_profile_get_label (src_profile),
                         gimp_color_profile_get_label (dest_profile));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               _("Color profile conversion"));

  switch (gimp_image_get_base_type (image))
    {
    case GIMP_RGB:
      gimp_image_convert_profile_rgb (image,
                                      src_profile, dest_profile,
                                      intent, bpc,
                                      progress);
      break;

    case GIMP_GRAY:
      break;

    case GIMP_INDEXED:
      gimp_image_convert_profile_indexed (image,
                                          src_profile, dest_profile,
                                          intent, bpc,
                                          progress);
      break;
    }

  gimp_image_set_color_profile (image, dest_profile, NULL);
  /*  omg...  */
  gimp_image_parasite_detach (image, "icc-profile-name");

  gimp_image_undo_group_end (image);

  if (progress)
    gimp_progress_end (progress);

  return TRUE;
}
static void run(
  const gchar *     name,
  gint              nparams,
	const GimpParam * param,
	gint *            nreturn_vals,
	GimpParam **      return_vals)
{
  static GimpParam values[2];   /* Gimp return values. !!! Allow 2: status and error message. */
  TGimpAdapterParameters pluginParameters;
  TImageSynthParameters engineParameters;
  
  GimpDrawable *drawable = NULL;
  GimpDrawable *corpus_drawable = NULL; 
  GimpDrawable *map_in_drawable= NULL; 
  GimpDrawable *map_out_drawable= NULL; 
  gboolean ok, with_map;
  
  /* 
  Local copies of pixmaps (not using gimp regions.) 
  2-D arrays of Pixel, addressable by Coordinates (Point).
  c++: static Bitmap<Pixelel>
  */
  Map targetMap;
  Map corpusMap;
  Map targetMaskMap;
  Map corpusMaskMap;
  
  int cancelFlag = 0;
  
  #ifdef SYNTH_THREADED
  // This is as early as it can be called.  Not sure it needs to be called.  See later call to it.
  // Call it early since calls to gdk, gtk might require this?
  g_thread_init(NULL);
  #endif

  #ifdef DEBUG
  gimp_message_set_handler(1); // To console instead of GUI
  start_time = clock();
  #endif
  
  // internationalization i18n
  // Note these constants are defined in the build environment.
  /*  Initialize i18n support  */
#if defined(G_OS_WIN32)
  bindtextdomain (GETTEXT_PACKAGE, gimp_locale_directory());
#else
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif
  textdomain (GETTEXT_PACKAGE);

  *nreturn_vals = 1;
  *return_vals = values;
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; /* Unless everything succeeds. */
  
  drawable = gimp_drawable_get(param[2].data.d_drawable);

  /* Check image type (could be called non-interactive) */
  if (!gimp_drawable_is_rgb(drawable->drawable_id) &&
      !gimp_drawable_is_gray(drawable->drawable_id)) 
  {
    ERROR_RETURN(_("Incompatible image mode."));
  }


  /* Deal with run mode */
  ok = FALSE;
  switch(param[0].data.d_int32) 
  {
    case GIMP_RUN_INTERACTIVE :
      ok = get_last_parameters(&pluginParameters,drawable->drawable_id, RESYNTH_ENGINE_PDB_NAME);
      gimp_message("Resynthesizer engine should not be called interactively");
      /* But keep going with last (or default) parameters, really no harm. */
      break;
    case GIMP_RUN_NONINTERACTIVE :
      ok = get_parameters_from_list(&pluginParameters, nparams, param); 
      break;
    case GIMP_RUN_WITH_LAST_VALS :
      ok = get_last_parameters(&pluginParameters,drawable->drawable_id, RESYNTH_ENGINE_PDB_NAME); 
      break;
  }

  if (!ok) 
  {
    ERROR_RETURN(_("Resynthesizer failed to get parameters."));
  }
  
  /* Limit neighbours parameter to size allocated. */
  if (pluginParameters.neighbours > IMAGE_SYNTH_MAX_NEIGHBORS )
    pluginParameters.neighbours = IMAGE_SYNTH_MAX_NEIGHBORS;
  
  corpus_drawable = gimp_drawable_get(pluginParameters.corpus_id);
  
  /* The target and corpus must have the same base type.
  In earlier version, they must have the same bpp.
  But now we don't compare the alphas, so they can differ in presence of alpha.
  */
  if (! equal_basetypes(drawable, corpus_drawable) )
  {
    ERROR_RETURN(_("The input texture and output image must have the same number of color channels."));
  }
  
  
  with_map = (pluginParameters.input_map_id != -1 && pluginParameters.output_map_id != -1);
  /* If only one map is passed, it is ignored quietly. */
  map_in_drawable=0;
  map_out_drawable=0;

  if (with_map) 
  {
    map_in_drawable = gimp_drawable_get(pluginParameters.input_map_id);
    map_out_drawable = gimp_drawable_get(pluginParameters.output_map_id);
    /* All these can be wrong at the same time.  
    Forego userfriendliness for ease of programming: abort on first error
    */
    if ( ! equal_basetypes(map_in_drawable, map_out_drawable) )
    {
      /* Maps need the same base type. Formerly needed the same bpp. */
      ERROR_RETURN(_("The input and output maps must have the same mode"));
    } 
    if (map_in_drawable->width != corpus_drawable->width || 
               map_in_drawable->height != corpus_drawable->height) 
    {
      ERROR_RETURN(_("The input map should be the same size as the input texture image"));
    } 
    if (map_out_drawable->width != drawable->width || 
               map_out_drawable->height != drawable->height) 
    {
      ERROR_RETURN(_("The output map should be the same size as the output image"));
    }
  }

  /* 
  The engine should not be run interactively so no need to store last values. 
  I.E. the meaning of "last" is "last values set by user interaction".
  */
  
  #ifdef ANIMATE
  // Copy local pointer vars to globals
  targetDrawableCopy = drawable;
  targetMapCopy = &targetMap;
  #endif
  
  /* Error checks done, initialization work begins.  So start progress callbacks. */
  progressStart("Initializing...");
  
  /* 
  Set flags for presence of alpha channels. 
  The flag is an optimization.  Alternatives:
  - a function
  - OR standardize the internal pixmap to ALWAYS have an alpha pixelel
  initialized to VISIBLE and set from any alpha pixelel.
  */
  gboolean is_alpha_image = gimp_drawable_has_alpha(drawable->drawable_id);
  gboolean is_alpha_corpus = gimp_drawable_has_alpha(corpus_drawable->drawable_id);
  
  // Image adaption requires format indices
  // WAS  prepareImageFormatIndices(drawable, corpus_drawable, with_map, map_in_drawable);
  TFormatIndices formatIndices;
  
  guint map_count = (with_map? count_color_channels(map_in_drawable) : 0 );
    
  prepareImageFormatIndices(
    &formatIndices,
    count_color_channels(drawable),
    map_count,
    is_alpha_image,
    is_alpha_corpus,
    with_map
    );
  
  #ifdef ADAPT_SIMPLE
    /* Adapt Gimp to an engine with a simpler interface. */
    setDefaultParams(&parameters);
    ImageBuffer imageBuffer;
    ImageBuffer maskBuffer;
    
    // TODO change to new signature
    adaptGimpToSimple(drawable, &imageBuffer, &maskBuffer);  // From Gimp to simple
    g_printf("Here3\n");
    adaptSimpleAPI(&imageBuffer, &maskBuffer);        // From simple to existing engine API
    
  #else
    g_printf("Gimp adaption\n");
    /* target/context adaption */
    fetch_image_mask_map(drawable, &targetMap, formatIndices.total_bpp, 
      &targetMaskMap, 
      MASK_TOTALLY_SELECTED, 
      map_out_drawable, formatIndices.map_start_bip);
    
      #ifdef ANIMATE
      clear_target_pixels(formatIndices.colorEndBip);  // For debugging, blacken so new colors sparkle
      #endif
  
    /*  corpus adaption */
    fetch_image_mask_map(corpus_drawable, &corpusMap, formatIndices.total_bpp, 
      &corpusMaskMap,
      MASK_TOTALLY_SELECTED, 
      map_in_drawable, formatIndices.map_start_bip);
      
    // TODO These are artifacts of earlier design, not used.
    free_map(&corpusMaskMap);
    free_map(&targetMaskMap);
    
    adaptParameters(&pluginParameters, &engineParameters);
    
  #endif
  
  // After possible adaption, check size again
  g_assert(targetMap.width * targetMap.height); // Image is not empty
  g_assert(corpusMap.width * corpusMap.height); // Corpus is not empty
  
  // Done with adaption: now main image data in canonical pixmaps, etc.
  // Begin real work
  progressStart("synthesizing...");
  
  int result = engine(
    engineParameters, 
    &formatIndices, 
    &targetMap, 
    &corpusMap,
    progressUpdate,
    (void *) 0,
    &cancelFlag
    );
  
  if (result == IMAGE_SYNTH_ERROR_EMPTY_CORPUS)
  {
    ERROR_RETURN(_("The texture source is empty. Does any selection include non-transparent pixels?"));
  }
  else if  (result == IMAGE_SYNTH_ERROR_EMPTY_TARGET )
  {
    ERROR_RETURN(_("The output layer is empty. Does any selection have visible pixels in the active layer?"));
  }
  
  // Normal post-process adaption follows

  /* dump_target_points(); */ /* detailed debugging. */
  // print_post_stats();
  
  // Update Gimp image from local pixmap
  // Note this works even for test harness where ADAPT_SIMPLE
  // but then it does NOT test returning results in buffer.
  
  /* 
  We could test antiAdaptImage() here.
  But antiAdaptImage() has already been tested once on the incoming side.
  So no compelling need to test it again here.
  */
  post_results_to_gimp(drawable, targetMap); 
  
  /* Clean up */
  // Adapted
  free_map(&targetMap);
  free_map(&corpusMap);
  // GIMP
  detach_drawables(drawable, corpus_drawable, map_in_drawable, map_out_drawable);
  gimp_progress_end();
  values[0].data.d_status = GIMP_PDB_SUCCESS;
} 
Example #19
0
File: xcf.c Project: alfanak/gimp
static GimpValueArray *
xcf_load_invoker (GimpProcedure         *procedure,
                  Gimp                  *gimp,
                  GimpContext           *context,
                  GimpProgress          *progress,
                  const GimpValueArray  *args,
                  GError               **error)
{
  XcfInfo         info = { 0, };
  GimpValueArray *return_vals;
  GimpImage      *image   = NULL;
  const gchar    *uri;
  gchar          *filename;
  GFile          *file;
  gboolean        success = FALSE;
  gchar           id[14];
  GError         *my_error = NULL;

  gimp_set_busy (gimp);

  uri      = g_value_get_string (gimp_value_array_index (args, 1));
#ifdef GIO_IS_FIXED
  file     = g_file_new_for_uri (uri);
#else
  file     = g_file_new_for_path (uri);
#endif
  filename = g_file_get_parse_name (file);

  info.input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error));

  if (info.input)
    {
      info.gimp        = gimp;
      info.seekable    = G_SEEKABLE (info.input);
      info.progress    = progress;
      info.filename    = filename;
      info.compression = COMPRESS_NONE;

      if (progress)
        {
          gchar *name = g_filename_display_name (filename);
          gchar *msg  = g_strdup_printf (_("Opening '%s'"), name);

          gimp_progress_start (progress, msg, FALSE);

          g_free (msg);
          g_free (name);
        }

      success = TRUE;

      info.cp += xcf_read_int8 (info.input, (guint8 *) id, 14);

      if (! g_str_has_prefix (id, "gimp xcf "))
        {
          success = FALSE;
        }
      else if (strcmp (id + 9, "file") == 0)
        {
          info.file_version = 0;
        }
      else if (id[9] == 'v')
        {
          info.file_version = atoi (id + 10);
        }
      else
        {
          success = FALSE;
        }

      if (success)
        {
          if (info.file_version >= 0 &&
              info.file_version < G_N_ELEMENTS (xcf_loaders))
            {
              image = (*(xcf_loaders[info.file_version])) (gimp, &info, error);

              if (! image)
                success = FALSE;
            }
          else
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("XCF error: unsupported XCF file version %d "
                             "encountered"), info.file_version);
              success = FALSE;
            }
        }

      g_object_unref (info.input);

      if (progress)
        gimp_progress_end (progress);
    }
  else
    {
      g_propagate_prefixed_error (error, my_error,
                                  _("Could not open '%s' for reading: "),
                                  filename);
    }

  g_free (filename);
  g_object_unref (file);

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_image (gimp_value_array_index (return_vals, 1), image);

  gimp_unset_busy (gimp);

  return return_vals;
}
Example #20
0
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)
    {
      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);
}
Example #22
0
static GimpValueArray *
shear_invoker (GimpProcedure         *procedure,
               Gimp                  *gimp,
               GimpContext           *context,
               GimpProgress          *progress,
               const GimpValueArray  *args,
               GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpDrawable *drawable;
  gboolean interpolation;
  gint32 shear_type;
  gdouble magnitude;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
  interpolation = g_value_get_boolean (gimp_value_array_index (args, 1));
  shear_type = g_value_get_enum (gimp_value_array_index (args, 2));
  magnitude = g_value_get_double (gimp_value_array_index (args, 3));

  if (success)
    {
      gint x, y, width, height;

      success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, TRUE, error);

      if (success &&
          gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
        {
          GimpMatrix3           matrix;
          GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
          gint                  off_x, off_y;

          gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);

          x += off_x;
          y += off_y;

          /* Assemble the transformation matrix */
          gimp_matrix3_identity (&matrix);
          gimp_transform_matrix_shear (&matrix,
                                       x, y, width, height,
                                       shear_type, magnitude);

          if (interpolation)
            interpolation_type = gimp->config->interpolation_type;

          if (progress)
            gimp_progress_start (progress, _("Shearing"), FALSE);

          if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
              ! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
            {
              if (! gimp_drawable_transform_affine (drawable, context,
                                                    &matrix,
                                                    GIMP_TRANSFORM_FORWARD,
                                                    interpolation_type, 3,
                                                    FALSE, progress))
                {
                  success = FALSE;
                }
            }
          else
            {
              gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
                                   GIMP_TRANSFORM_FORWARD,
                                   interpolation, 3,
                                   FALSE, progress);
            }

          if (progress)
            gimp_progress_end (progress);
        }
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    gimp_value_set_drawable (gimp_value_array_index (return_vals, 1), drawable);

  return return_vals;
}