예제 #1
0
gboolean
gimp_image_validate_color_profile (GimpImage        *image,
                                   GimpColorProfile *profile,
                                   GError          **error)
{
  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("ICC profile validation failed: "
                             "Cannot attach a color profile to a GRAY image"));
      return FALSE;
    }

  if (! gimp_color_profile_is_rgb (profile))
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("ICC profile validation failed: "
                             "Color profile is not for RGB color space"));
      return FALSE;
    }

  return TRUE;
}
예제 #2
0
gboolean
gimp_image_validate_icc_profile (GimpImage           *image,
                                 const GimpParasite  *icc_profile,
                                 GError             **error)
{
  GimpColorProfile *profile;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (icc_profile != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (strcmp (gimp_parasite_name (icc_profile),
              GIMP_ICC_PROFILE_PARASITE_NAME) != 0)
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("ICC profile validation failed: "
                             "Parasite's name is not 'icc-profile'"));
      return FALSE;
    }

  if (gimp_parasite_flags (icc_profile) != (GIMP_PARASITE_PERSISTENT |
                                            GIMP_PARASITE_UNDOABLE))
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("ICC profile validation failed: "
                             "Parasite's flags are not (PERSISTENT | UNDOABLE)"));
      return FALSE;
    }

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("ICC profile validation failed: "
                             "Cannot attach a color profile to a GRAY image"));
      return FALSE;
    }

  profile = gimp_lcms_profile_open_from_data (gimp_parasite_data (icc_profile),
                                              gimp_parasite_data_size (icc_profile),
                                              error);

  if (! profile)
    {
      g_prefix_error (error, _("ICC profile validation failed: "));
      return FALSE;
    }

  if (! gimp_lcms_profile_is_rgb (profile))
    {
      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                           _("ICC profile validation failed: "
                             "Color profile is not for RGB color space"));
      cmsCloseProfile (profile);
      return FALSE;
    }

  cmsCloseProfile (profile);

  return TRUE;
}
예제 #3
0
static void
gimp_image_undo_constructed (GObject *object)
{
  GimpImageUndo *image_undo = GIMP_IMAGE_UNDO (object);
  GimpImage     *image;

  G_OBJECT_CLASS (parent_class)->constructed (object);

  image = GIMP_UNDO (object)->image;

  switch (GIMP_UNDO (object)->undo_type)
    {
    case GIMP_UNDO_IMAGE_TYPE:
      image_undo->base_type = gimp_image_get_base_type (image);
      break;

    case GIMP_UNDO_IMAGE_PRECISION:
      image_undo->precision = gimp_image_get_precision (image);
      break;

    case GIMP_UNDO_IMAGE_SIZE:
      image_undo->width  = gimp_image_get_width  (image);
      image_undo->height = gimp_image_get_height (image);
      break;

    case GIMP_UNDO_IMAGE_RESOLUTION:
      gimp_image_get_resolution (image,
                                 &image_undo->xresolution,
                                 &image_undo->yresolution);
      image_undo->resolution_unit = gimp_image_get_unit (image);
      break;

    case GIMP_UNDO_IMAGE_GRID:
      g_assert (GIMP_IS_GRID (image_undo->grid));
      break;

    case GIMP_UNDO_IMAGE_COLORMAP:
      image_undo->num_colors = gimp_image_get_colormap_size (image);
      image_undo->colormap   = g_memdup (gimp_image_get_colormap (image),
                                         GIMP_IMAGE_COLORMAP_SIZE);
      break;

    case GIMP_UNDO_IMAGE_METADATA:
      image_undo->metadata =
        gimp_metadata_duplicate (gimp_image_get_metadata (image));
      break;

    case GIMP_UNDO_PARASITE_ATTACH:
    case GIMP_UNDO_PARASITE_REMOVE:
      g_assert (image_undo->parasite_name != NULL);

      image_undo->parasite = gimp_parasite_copy
        (gimp_image_parasite_find (image, image_undo->parasite_name));
      break;

    default:
      g_assert_not_reached ();
    }
}
static void
palette_import_image_changed (GimpContext  *context,
                              GimpImage    *image,
                              ImportDialog *dialog)
{
  if (dialog->image)
    {
      g_signal_handlers_disconnect_by_func (dialog->image,
                                            palette_import_layer_changed,
                                            dialog);
      g_signal_handlers_disconnect_by_func (dialog->image,
                                            palette_import_mask_changed,
                                            dialog);
    }

  dialog->image = image;

  if (dialog->import_type == IMAGE_IMPORT)
    {
      gboolean sensitive = FALSE;

      if (image)
        {
          gchar *label;

          label = g_strdup_printf ("%s-%d",
				   gimp_image_get_display_name (image),
				   gimp_image_get_ID (image));

          gtk_entry_set_text (GTK_ENTRY (dialog->entry), label);
          g_free (label);

          palette_import_make_palette (dialog);

          if (gimp_image_get_base_type (image) != GIMP_INDEXED)
            sensitive = TRUE;
        }

      gtk_widget_set_sensitive (dialog->sample_merged_toggle, sensitive);
      gtk_widget_set_sensitive (dialog->selection_only_toggle, sensitive);
      gimp_scale_entry_set_sensitive (GTK_OBJECT (dialog->threshold),
                                      sensitive);
      gimp_scale_entry_set_sensitive (GTK_OBJECT (dialog->num_colors),
                                      sensitive);
    }

  if (dialog->image)
    {
      g_signal_connect (dialog->image, "active-layer-changed",
                        G_CALLBACK (palette_import_layer_changed),
                        dialog);
      g_signal_connect (dialog->image, "mask-changed",
                        G_CALLBACK (palette_import_mask_changed),
                        dialog);
    }
}
예제 #5
0
static const gchar *
gimp_display_shell_title_image_type (GimpImage *image)
{
  const gchar *name = "";

  gimp_enum_get_value (GIMP_TYPE_IMAGE_BASE_TYPE,
                       gimp_image_get_base_type (image), NULL, NULL, &name, NULL);

  return name;
}
예제 #6
0
static void
gimp_image_duplicate_colormap (GimpImage *image,
                               GimpImage *new_image)
{
  if (gimp_image_get_base_type (new_image) == GIMP_INDEXED)
    gimp_image_set_colormap (new_image,
                             gimp_image_get_colormap (image),
                             gimp_image_get_colormap_size (image),
                             FALSE);
}
예제 #7
0
gboolean
gimp_pdb_image_is_base_type (GimpImage          *image,
                             GimpImageBaseType   type,
                             GError            **error)
{
  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (gimp_image_get_base_type (image) == type)
    return TRUE;

  g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
               _("Image '%s' (%d) is of type '%s', "
                 "but an image of type '%s' is expected"),
               gimp_image_get_display_name (image),
               gimp_image_get_ID (image),
               gimp_pdb_enum_value_get_nick (GIMP_TYPE_IMAGE_BASE_TYPE,
                                             gimp_image_get_base_type (image)),
               gimp_pdb_enum_value_get_nick (GIMP_TYPE_IMAGE_BASE_TYPE, type));

  return FALSE;
}
예제 #8
0
gboolean
gimp_image_validate_color_profile (GimpImage        *image,
                                   GimpColorProfile *profile,
                                   gboolean         *is_builtin,
                                   GError          **error)
{
  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (profile), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      if (! gimp_color_profile_is_gray (profile))
        {
          g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                               _("ICC profile validation failed: "
                                 "Color profile is not for GRAY color space"));
          return FALSE;
        }
    }
  else
    {
      if (! gimp_color_profile_is_rgb (profile))
        {
          g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
                               _("ICC profile validation failed: "
                                 "Color profile is not for RGB color space"));
          return FALSE;
        }
    }

  if (is_builtin)
    {
      GimpColorProfile *builtin;

      builtin = gimp_image_get_builtin_color_profile (image);

      *is_builtin = gimp_color_profile_is_equal (profile, builtin);
    }

  return TRUE;
}
예제 #9
0
파일: file-open.c 프로젝트: Distrotech/gimp
static void
file_open_profile_apply_rgb (GimpImage    *image,
                             GimpContext  *context,
                             GimpProgress *progress,
                             GimpRunMode   run_mode)
{
  GimpColorConfig *config = image->gimp->config->color_management;
  GError          *error  = NULL;

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    return;

  if (config->mode == GIMP_COLOR_MANAGEMENT_OFF)
    return;

  if (! plug_in_icc_profile_apply_rgb (image, context, progress, run_mode,
                                       &error))
    {
      if (error->domain == GIMP_PLUG_IN_ERROR &&
          error->code   == GIMP_PLUG_IN_NOT_FOUND)
        {
          gchar *msg = g_strdup_printf ("%s\n\n%s",
                                        error->message,
                                        _("Color management has been disabled. "
                                          "It can be enabled again in the "
                                          "Preferences dialog."));

          g_object_set (config, "mode", GIMP_COLOR_MANAGEMENT_OFF, NULL);

          gimp_message_literal (image->gimp, G_OBJECT (progress),
                                GIMP_MESSAGE_WARNING, msg);
          g_free (msg);
        }
      else
        {
          gimp_message_literal (image->gimp, G_OBJECT (progress),
                                GIMP_MESSAGE_ERROR, error->message);
        }

      g_error_free (error);
    }
}
예제 #10
0
void
colormap_actions_update (GimpActionGroup *group,
                         gpointer         data)
{
  GimpImage   *image      = action_data_get_image (data);
  GimpContext *context    = action_data_get_context (data);
  gboolean     indexed    = FALSE;
  gint         num_colors = 0;
  GimpRGB      fg;
  GimpRGB      bg;

  if (image)
    {
      indexed    = (gimp_image_get_base_type (image) == GIMP_INDEXED);
      num_colors = gimp_image_get_colormap_size (image);
    }

  if (context)
    {
      gimp_context_get_foreground (context, &fg);
      gimp_context_get_background (context, &bg);
    }

#define SET_SENSITIVE(action,condition) \
        gimp_action_group_set_action_sensitive (group, action, (condition) != 0)
#define SET_COLOR(action,color) \
        gimp_action_group_set_action_color (group, action, color, FALSE);

  SET_SENSITIVE ("colormap-edit-color",
                 image && indexed && num_colors > 0);
  SET_SENSITIVE ("colormap-add-color-from-fg",
                 image && indexed && num_colors < 256);
  SET_SENSITIVE ("colormap-add-color-from-bg",
                 image && indexed && num_colors < 256);

  SET_COLOR ("colormap-add-color-from-fg", context ? &fg : NULL);
  SET_COLOR ("colormap-add-color-from-bg", context ? &bg : NULL);

#undef SET_SENSITIVE
#undef SET_COLOR
}
예제 #11
0
GimpColorProfile *
gimp_image_get_builtin_color_profile (GimpImage *image)
{
  static GimpColorProfile *srgb_profile        = NULL;
  static GimpColorProfile *linear_rgb_profile  = NULL;
  static GimpColorProfile *gray_profile        = NULL;
  static GimpColorProfile *linear_gray_profile = NULL;
  const  Babl             *format;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  format = gimp_image_get_layer_format (image, FALSE);

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      if (gimp_babl_format_get_linear (format))
        {
          if (! linear_gray_profile)
            {
              linear_gray_profile = gimp_color_profile_new_gray_srgb_linear ();
              g_object_add_weak_pointer (G_OBJECT (linear_gray_profile),
                                         (gpointer) &linear_gray_profile);
            }

          return linear_gray_profile;
        }
      else
        {
          if (! gray_profile)
            {
              gray_profile = gimp_color_profile_new_gray_srgb ();
              g_object_add_weak_pointer (G_OBJECT (gray_profile),
                                         (gpointer) &gray_profile);
            }

          return gray_profile;
        }
    }
  else
    {
      if (gimp_babl_format_get_linear (format))
        {
          if (! linear_rgb_profile)
            {
              linear_rgb_profile = gimp_color_profile_new_rgb_srgb_linear ();
              g_object_add_weak_pointer (G_OBJECT (linear_rgb_profile),
                                         (gpointer) &linear_rgb_profile);
            }

          return linear_rgb_profile;
        }
      else
        {
          if (! srgb_profile)
            {
              srgb_profile = gimp_color_profile_new_rgb_srgb ();
              g_object_add_weak_pointer (G_OBJECT (srgb_profile),
                                         (gpointer) &srgb_profile);
            }

          return srgb_profile;
        }
    }
}
예제 #12
0
void
file_import_image (GimpImage    *image,
                   GimpContext  *context,
                   GFile        *file,
                   gboolean      interactive,
                   GimpProgress *progress)
{
  GimpCoreConfig *config;

  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (GIMP_IS_CONTEXT (context));
  g_return_if_fail (G_IS_FILE (file));
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  config = image->gimp->config;

  if (interactive && gimp_image_get_base_type (image) != GIMP_INDEXED)
    {
      if (config->import_promote_float)
        {
          GimpPrecision old_precision = gimp_image_get_precision (image);

          if (old_precision != GIMP_PRECISION_FLOAT_LINEAR)
            {
              gimp_image_convert_precision (image,
                                            GIMP_PRECISION_FLOAT_LINEAR,
                                            GEGL_DITHER_NONE,
                                            GEGL_DITHER_NONE,
                                            GEGL_DITHER_NONE,
                                            progress);

              if (config->import_promote_dither &&
                  old_precision == GIMP_PRECISION_U8_NON_LINEAR)
                {
                  gimp_image_convert_dither_u8 (image, progress);
                }
            }
        }

      if (config->import_add_alpha)
        {
          GList *layers = gimp_image_get_layer_list (image);
          GList *list;

          for (list = layers; list; list = g_list_next (list))
            {
              if (! gimp_viewable_get_children (list->data) &&
                  ! gimp_item_is_text_layer (list->data)    &&
                  ! gimp_drawable_has_alpha (list->data))
                {
                  gimp_layer_add_alpha (list->data);
                }
            }

          g_list_free (layers);
        }
    }

  gimp_image_import_color_profile (image, context, progress, interactive);

  /* Remember the import source */
  gimp_image_set_imported_file (image, file);

  /* We shall treat this file as an Untitled file */
  gimp_image_set_file (image, NULL);
}
예제 #13
0
static void
gimp_image_prop_view_update (GimpImagePropView *view)
{
  GimpImage         *image = view->image;
  GimpImageBaseType  type;
  GimpPrecision      precision;
  GimpUnit           unit;
  gdouble            unit_factor;
  gint               unit_digits;
  const gchar       *desc;
  gchar              format_buf[32];
  gchar              buf[256];
  gdouble            xres;
  gdouble            yres;

  gimp_image_get_resolution (image, &xres, &yres);

  /*  pixel size  */
  g_snprintf (buf, sizeof (buf), ngettext ("%d × %d pixel",
                                           "%d × %d pixels",
                                           gimp_image_get_height (image)),
              gimp_image_get_width  (image),
              gimp_image_get_height (image));
  gtk_label_set_text (GTK_LABEL (view->pixel_size_label), buf);

  /*  print size  */
  unit = gimp_get_default_unit ();

  unit_digits = gimp_unit_get_digits (unit);

  g_snprintf (format_buf, sizeof (format_buf), "%%.%df × %%.%df %s",
              unit_digits + 1, unit_digits + 1,
              gimp_unit_get_plural (unit));
  g_snprintf (buf, sizeof (buf), format_buf,
              gimp_pixels_to_units (gimp_image_get_width  (image), unit, xres),
              gimp_pixels_to_units (gimp_image_get_height (image), unit, yres));
  gtk_label_set_text (GTK_LABEL (view->print_size_label), buf);

  /*  resolution  */
  unit        = gimp_image_get_unit (image);
  unit_factor = gimp_unit_get_factor (unit);

  g_snprintf (format_buf, sizeof (format_buf), _("pixels/%s"),
              gimp_unit_get_abbreviation (unit));
  g_snprintf (buf, sizeof (buf), _("%g × %g %s"),
              xres / unit_factor,
              yres / unit_factor,
              unit == GIMP_UNIT_INCH ? _("ppi") : format_buf);
  gtk_label_set_text (GTK_LABEL (view->resolution_label), buf);

  /*  color type  */
  type = gimp_image_get_base_type (image);

  gimp_enum_get_value (GIMP_TYPE_IMAGE_BASE_TYPE, type,
                       NULL, NULL, &desc, NULL);

  switch (type)
    {
    case GIMP_RGB:
    case GIMP_GRAY:
      g_snprintf (buf, sizeof (buf), "%s", desc);
      break;
    case GIMP_INDEXED:
      g_snprintf (buf, sizeof (buf),
                  "%s (%d %s)", desc, gimp_image_get_colormap_size (image),
                  _("colors"));
      break;
    }

  gtk_label_set_text (GTK_LABEL (view->colorspace_label), buf);

  /*  precision  */
  precision = gimp_image_get_precision (image);

  gimp_enum_get_value (GIMP_TYPE_PRECISION, precision,
                       NULL, NULL, &desc, NULL);

  gtk_label_set_text (GTK_LABEL (view->precision_label), desc);

  /*  size in memory  */
  gimp_image_prop_view_label_set_memsize (view->memsize_label,
                                          GIMP_OBJECT (image));

  /*  undo / redo  */
  gimp_image_prop_view_label_set_undo (view->undo_label,
                                       gimp_image_get_undo_stack (image));
  gimp_image_prop_view_label_set_undo (view->redo_label,
                                       gimp_image_get_redo_stack (image));

  /*  number of layers  */
  g_snprintf (buf, sizeof (buf), "%d",
              gimp_image_get_width  (image) *
              gimp_image_get_height (image));
  gtk_label_set_text (GTK_LABEL (view->pixels_label), buf);

  /*  number of layers  */
  g_snprintf (buf, sizeof (buf), "%d",
              gimp_image_get_n_layers (image));
  gtk_label_set_text (GTK_LABEL (view->layers_label), buf);

  /*  number of channels  */
  g_snprintf (buf, sizeof (buf), "%d",
              gimp_image_get_n_channels (image));
  gtk_label_set_text (GTK_LABEL (view->channels_label), buf);

  /*  number of vectors  */
  g_snprintf (buf, sizeof (buf), "%d",
              gimp_image_get_n_vectors (image));
  gtk_label_set_text (GTK_LABEL (view->vectors_label), buf);
}
예제 #14
0
static void
palette_import_make_palette (ImportDialog *dialog)
{
  GimpPalette  *palette = NULL;
  const gchar  *palette_name;
  gint          n_colors;
  gint          n_columns;
  gint          threshold;

  palette_name = gtk_entry_get_text (GTK_ENTRY (dialog->entry));

  if (! palette_name || ! strlen (palette_name))
    palette_name = _("Untitled");

  n_colors  = ROUND (gtk_adjustment_get_value (dialog->num_colors));
  n_columns = ROUND (gtk_adjustment_get_value (dialog->columns));
  threshold = ROUND (gtk_adjustment_get_value (dialog->threshold));

  switch (dialog->import_type)
    {
    case GRADIENT_IMPORT:
      {
        GimpGradient *gradient;

        gradient = gimp_context_get_gradient (dialog->context);

        palette = gimp_palette_import_from_gradient (gradient,
                                                     dialog->context,
                                                     FALSE,
                                                     palette_name,
                                                     n_colors);
      }
      break;

    case IMAGE_IMPORT:
      {
        GimpImage *image = gimp_context_get_image (dialog->context);
        gboolean   sample_merged;
        gboolean   selection_only;

        sample_merged =
          gtk_toggle_button_get_active
          (GTK_TOGGLE_BUTTON (dialog->sample_merged_toggle));

        selection_only =
          gtk_toggle_button_get_active
          (GTK_TOGGLE_BUTTON (dialog->selection_only_toggle));

        if (gimp_image_get_base_type (image) == GIMP_INDEXED)
          {
            palette = gimp_palette_import_from_indexed_image (image,
                                                              dialog->context,
                                                              palette_name);
          }
        else if (sample_merged)
          {
            palette = gimp_palette_import_from_image (image,
                                                      dialog->context,
                                                      palette_name,
                                                      n_colors,
                                                      threshold,
                                                      selection_only);
          }
        else
          {
            GimpDrawable *drawable;

            drawable = GIMP_DRAWABLE (gimp_image_get_active_layer (image));

            palette = gimp_palette_import_from_drawable (drawable,
                                                         dialog->context,
                                                         palette_name,
                                                         n_colors,
                                                         threshold,
                                                         selection_only);
          }
      }
      break;

    case FILE_IMPORT:
      {
        GFile  *file;
        GError *error = NULL;

        file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog->file_chooser));

        palette = gimp_palette_import_from_file (dialog->context,
                                                 file,
                                                 palette_name, &error);
        g_object_unref (file);

        if (! palette)
          {
            gimp_message_literal (dialog->context->gimp,
                                  G_OBJECT (dialog->dialog), GIMP_MESSAGE_ERROR,
                                  error->message);
            g_error_free (error);
          }
      }
      break;
    }

  if (palette)
    {
      if (dialog->palette)
        g_object_unref (dialog->palette);

      gimp_palette_set_columns (palette, n_columns);

      gimp_view_set_viewable (GIMP_VIEW (dialog->preview),
                              GIMP_VIEWABLE (palette));

      dialog->palette = palette;
    }

  gtk_widget_set_visible (dialog->no_colors_label,
                          dialog->palette &&
                          gimp_palette_get_n_colors (dialog->palette) > 0);
}
예제 #15
0
static GtkWidget *
color_profile_combo_box_new (ProfileDialog *dialog)
{
  GtkWidget        *combo;
  GtkWidget        *chooser;
  gchar            *history;
  GimpColorProfile *profile;
  gboolean          to_gray;
  gchar            *label;
  GError           *error = NULL;

  chooser =
    gimp_color_profile_chooser_dialog_new (_("Select Destination Profile"),
                                           NULL,
                                           GTK_FILE_CHOOSER_ACTION_OPEN);

  history = gimp_personal_rc_file ("profilerc");
  combo = gimp_color_profile_combo_box_new (chooser, history);
  g_free (history);

  switch (dialog->dialog_type)
    {
    case COLOR_PROFILE_DIALOG_ASSIGN_PROFILE:
    case COLOR_PROFILE_DIALOG_CONVERT_TO_PROFILE:
      to_gray = (gimp_image_get_base_type (dialog->image) == GIMP_GRAY);
      break;

    case COLOR_PROFILE_DIALOG_CONVERT_TO_RGB:
      to_gray = FALSE;
      break;

    case COLOR_PROFILE_DIALOG_CONVERT_TO_GRAY:
      to_gray = TRUE;
      break;

    default:
      g_return_val_if_reached (NULL);
    }

  profile = dialog->builtin_profile;

  if (to_gray)
    {
      label = g_strdup_printf (_("Built-in grayscale (%s)"),
                               gimp_color_profile_get_label (profile));

      profile = gimp_color_config_get_gray_color_profile (dialog->config, &error);
    }
  else
    {
      label = g_strdup_printf (_("Built-in RGB (%s)"),
                               gimp_color_profile_get_label (profile));

      profile = gimp_color_config_get_rgb_color_profile (dialog->config, &error);
    }

  gimp_color_profile_combo_box_add_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                         NULL, label);
  g_free (label);

  if (profile)
    {
      GFile *file;

      if (to_gray)
        {
          file = g_file_new_for_path (dialog->config->gray_profile);

          label = g_strdup_printf (_("Preferred grayscale (%s)"),
                                   gimp_color_profile_get_label (profile));
        }
      else
        {
          file = g_file_new_for_path (dialog->config->rgb_profile);

          label = g_strdup_printf (_("Preferred RGB (%s)"),
                                   gimp_color_profile_get_label (profile));
        }

      g_object_unref (profile);

      gimp_color_profile_combo_box_add_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                             file, label);
      g_object_unref (file);
      g_free (label);
    }
  else if (error)
    {
      gimp_message (dialog->image->gimp, G_OBJECT (dialog->dialog),
                    GIMP_MESSAGE_ERROR,
                    "%s", error->message);
      g_clear_error (&error);
    }

  gimp_color_profile_combo_box_set_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                                NULL, NULL);

  return combo;
}
예제 #16
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, 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);
}
예제 #17
0
void
image_actions_update (GimpActionGroup *group,
                      gpointer         data)
{
  GimpImage *image       = action_data_get_image (data);
  gboolean   is_indexed  = FALSE;
  gboolean   is_u8_gamma = FALSE;
  gboolean   aux         = FALSE;
  gboolean   lp          = FALSE;
  gboolean   sel         = FALSE;
  gboolean   groups      = FALSE;
  gboolean   profile     = FALSE;

  if (image)
    {
      GimpContainer *layers;
      const gchar   *action = NULL;

      switch (gimp_image_get_base_type (image))
        {
        case GIMP_RGB:     action = "image-convert-rgb";       break;
        case GIMP_GRAY:    action = "image-convert-grayscale"; break;
        case GIMP_INDEXED: action = "image-convert-indexed";   break;
        }

      gimp_action_group_set_action_active (group, action, TRUE);

      switch (gimp_image_get_precision (image))
        {
        case GIMP_PRECISION_U8_LINEAR:
          action = "image-convert-u8-linear";
          break;
        case GIMP_PRECISION_U8_GAMMA:
          action = "image-convert-u8-gamma";
          break;
        case GIMP_PRECISION_U16_LINEAR:
          action = "image-convert-u16-linear";
          break;
        case GIMP_PRECISION_U16_GAMMA:
          action = "image-convert-u16-gamma";
          break;
        case GIMP_PRECISION_U32_LINEAR:
          action = "image-convert-u32-linear";
          break;
        case GIMP_PRECISION_U32_GAMMA:
          action = "image-convert-u32-gamma";
          break;
        case GIMP_PRECISION_HALF_LINEAR:
          action = "image-convert-half-linear";
          break;
        case GIMP_PRECISION_HALF_GAMMA:
          action = "image-convert-half-gamma";
          break;
        case GIMP_PRECISION_FLOAT_LINEAR:
          action = "image-convert-float-linear";
          break;
        case GIMP_PRECISION_FLOAT_GAMMA:
          action = "image-convert-float-gamma";
          break;
        case GIMP_PRECISION_DOUBLE_LINEAR:
          action = "image-convert-double-linear";
          break;
        case GIMP_PRECISION_DOUBLE_GAMMA:
          action = "image-convert-double-gamma";
          break;
        }

      gimp_action_group_set_action_active (group, action, TRUE);

      is_indexed  = (gimp_image_get_base_type (image) == GIMP_INDEXED);
      is_u8_gamma = (gimp_image_get_precision (image) ==
                     GIMP_PRECISION_U8_GAMMA);
      aux         = (gimp_image_get_active_channel (image) != NULL);
      lp          = ! gimp_image_is_empty (image);
      sel         = ! gimp_channel_is_empty (gimp_image_get_mask (image));

      layers = gimp_image_get_layers (image);

      groups = ! gimp_item_stack_is_flat (GIMP_ITEM_STACK (layers));

      profile = (gimp_image_get_icc_parasite (image) != NULL);
    }

#define SET_SENSITIVE(action,condition) \
        gimp_action_group_set_action_sensitive (group, action, (condition) != 0)

  SET_SENSITIVE ("image-convert-rgb",       image);
  SET_SENSITIVE ("image-convert-grayscale", image);
  SET_SENSITIVE ("image-convert-indexed",   image && !groups && is_u8_gamma);

  SET_SENSITIVE ("image-convert-u8-gamma",      image);
  SET_SENSITIVE ("image-convert-u8-linear",     image && !is_indexed);
  SET_SENSITIVE ("image-convert-u16-gamma",     image && !is_indexed);
  SET_SENSITIVE ("image-convert-u16-linear",    image && !is_indexed);
  SET_SENSITIVE ("image-convert-u32-gamma",     image && !is_indexed);
  SET_SENSITIVE ("image-convert-u32-linear",    image && !is_indexed);
  SET_SENSITIVE ("image-convert-half-gamma",    image && !is_indexed);
  SET_SENSITIVE ("image-convert-half-linear",   image && !is_indexed);
  SET_SENSITIVE ("image-convert-float-gamma",   image && !is_indexed);
  SET_SENSITIVE ("image-convert-float-linear",  image && !is_indexed);
  SET_SENSITIVE ("image-convert-double-gamma",  image && !is_indexed);
  SET_SENSITIVE ("image-convert-double-linear", image && !is_indexed);

  SET_SENSITIVE ("image-color-profile-assign",  image);
  SET_SENSITIVE ("image-color-profile-convert", image);
  SET_SENSITIVE ("image-color-profile-discard", image && profile);

  SET_SENSITIVE ("image-flip-horizontal", image);
  SET_SENSITIVE ("image-flip-vertical",   image);
  SET_SENSITIVE ("image-rotate-90",       image);
  SET_SENSITIVE ("image-rotate-180",      image);
  SET_SENSITIVE ("image-rotate-270",      image);

  SET_SENSITIVE ("image-resize",              image);
  SET_SENSITIVE ("image-resize-to-layers",    image);
  SET_SENSITIVE ("image-resize-to-selection", image && sel);
  SET_SENSITIVE ("image-print-size",          image);
  SET_SENSITIVE ("image-scale",               image);
  SET_SENSITIVE ("image-crop-to-selection",   image && sel);
  SET_SENSITIVE ("image-crop-to-content",     image);
  SET_SENSITIVE ("image-duplicate",           image);
  SET_SENSITIVE ("image-merge-layers",        image && !aux && lp);
  SET_SENSITIVE ("image-flatten",             image && !aux && lp);
  SET_SENSITIVE ("image-configure-grid",      image);
  SET_SENSITIVE ("image-properties",          image);

#undef SET_SENSITIVE
}
예제 #18
0
/**
 * gimp_image_scale_check:
 * @image:      A #GimpImage.
 * @new_width:   The new width.
 * @new_height:  The new height.
 * @max_memsize: The maximum new memory size.
 * @new_memsize: The new memory size.
 *
 * Inventory the layer list in image and check that it may be
 * scaled to @new_height and @new_width without problems.
 *
 * Return value: #GIMP_IMAGE_SCALE_OK if scaling the image will shrink none
 *               of its layers completely away, and the new image size
 *               is smaller than @max_memsize.
 *               #GIMP_IMAGE_SCALE_TOO_SMALL if scaling would remove some
 *               existing layers.
 *               #GIMP_IMAGE_SCALE_TOO_BIG if the new image size would
 *               exceed the maximum specified in the preferences.
 **/
GimpImageScaleCheckType
gimp_image_scale_check (const GimpImage *image,
                        gint             new_width,
                        gint             new_height,
                        gint64           max_memsize,
                        gint64          *new_memsize)
{
    GList  *drawables;
    GList  *all_layers;
    GList  *list;
    gint64  current_size;
    gint64  scalable_size;
    gint64  scaled_size;
    gint64  undo_size;
    gint64  redo_size;
    gint64  fixed_size;
    gint64  new_size;

    g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_IMAGE_SCALE_TOO_SMALL);
    g_return_val_if_fail (new_memsize != NULL, GIMP_IMAGE_SCALE_TOO_SMALL);

    current_size = gimp_object_get_memsize (GIMP_OBJECT (image), NULL);

    /*  the part of the image's memsize that scales linearly with the image  */
    drawables = gimp_image_item_list_get_list (image, NULL,
                GIMP_ITEM_TYPE_LAYERS |
                GIMP_ITEM_TYPE_CHANNELS,
                GIMP_ITEM_SET_ALL);

    gimp_image_item_list_filter (NULL, drawables, TRUE, FALSE);

    drawables = g_list_prepend (drawables, gimp_image_get_mask (image));

    scalable_size = 0;
    scaled_size   = 0;

    for (list = drawables; list; list = g_list_next (list))
    {
        GimpDrawable *drawable = list->data;
        gdouble       width    = gimp_item_get_width  (GIMP_ITEM (drawable));
        gdouble       height   = gimp_item_get_height (GIMP_ITEM (drawable));

        scalable_size +=
            gimp_drawable_estimate_memsize (drawable,
                                            width, height);

        scaled_size +=
            gimp_drawable_estimate_memsize (drawable,
                                            width * new_width /
                                            gimp_image_get_width (image),
                                            height * new_height /
                                            gimp_image_get_height (image));
    }

    g_list_free (drawables);

    scalable_size +=
        gimp_projection_estimate_memsize (gimp_image_get_base_type (image),
                                          gimp_image_get_precision (image),
                                          gimp_image_get_width (image),
                                          gimp_image_get_height (image));

    scaled_size +=
        gimp_projection_estimate_memsize (gimp_image_get_base_type (image),
                                          gimp_image_get_precision (image),
                                          new_width, new_height);

    GIMP_LOG (IMAGE_SCALE,
              "scalable_size = %"G_GINT64_FORMAT"  scaled_size = %"G_GINT64_FORMAT,
              scalable_size, scaled_size);

    undo_size = gimp_object_get_memsize (GIMP_OBJECT (gimp_image_get_undo_stack (image)), NULL);
    redo_size = gimp_object_get_memsize (GIMP_OBJECT (gimp_image_get_redo_stack (image)), NULL);

    /*  the fixed part of the image's memsize w/o any undo information  */
    fixed_size = current_size - undo_size - redo_size - scalable_size;

    /*  calculate the new size, which is:  */
    new_size = (fixed_size +   /*  the fixed part                */
                scaled_size);  /*  plus the part that scales...  */

    GIMP_LOG (IMAGE_SCALE,
              "old_size = %"G_GINT64_FORMAT"  new_size = %"G_GINT64_FORMAT,
              current_size - undo_size - redo_size, new_size);

    *new_memsize = new_size;

    if (new_size > current_size && new_size > max_memsize)
        return GIMP_IMAGE_SCALE_TOO_BIG;

    all_layers = gimp_image_get_layer_list (image);

    for (list = all_layers; list; list = g_list_next (list))
    {
        GimpItem *item = list->data;

        /*  group layers are updated automatically  */
        if (gimp_viewable_get_children (GIMP_VIEWABLE (item)))
            continue;

        if (! gimp_item_check_scaling (item, new_width, new_height))
        {
            g_list_free (all_layers);

            return GIMP_IMAGE_SCALE_TOO_SMALL;
        }
    }

    g_list_free (all_layers);

    return GIMP_IMAGE_SCALE_OK;
}
예제 #19
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 (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, 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"));

  gimp_image_set_color_profile (image, dest_profile, NULL);
  /*  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);

  return TRUE;
}
예제 #20
0
static GtkWidget *
color_profile_combo_box_new (ProfileDialog *dialog)
{
  GtkWidget        *combo;
  GtkWidget        *chooser;
  gchar            *history;
  GimpColorProfile *profile;
  gchar            *label;
  GError           *error = NULL;

  chooser = gimp_color_profile_chooser_dialog_new (_("Select destination profile"));

  history = gimp_personal_rc_file ("profilerc");
  combo = gimp_color_profile_combo_box_new (chooser, history);
  g_free (history);

  profile = gimp_image_get_builtin_color_profile (dialog->image);

  if (gimp_image_get_base_type (dialog->image) == GIMP_GRAY)
    {
      label = g_strdup_printf (_("Built-in grayscale (%s)"),
                               gimp_color_profile_get_label (profile));

      profile = gimp_color_config_get_gray_color_profile (dialog->config, &error);
    }
  else
    {
      label = g_strdup_printf (_("Built-in RGB (%s)"),
                               gimp_color_profile_get_label (profile));

      profile = gimp_color_config_get_rgb_color_profile (dialog->config, &error);
    }

  gimp_color_profile_combo_box_add_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                         NULL, label);
  g_free (label);

  if (profile)
    {
      GFile *file = g_file_new_for_path (dialog->config->rgb_profile);

      if (gimp_image_get_base_type (dialog->image) == GIMP_GRAY)
        {
          label = g_strdup_printf (_("Preferred grayscale (%s)"),
                                   gimp_color_profile_get_label (profile));
        }
      else
        {
          label = g_strdup_printf (_("Preferred RGB (%s)"),
                                   gimp_color_profile_get_label (profile));
        }

      g_object_unref (profile);

      gimp_color_profile_combo_box_add_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                             file, label);
      g_object_unref (file);
      g_free (label);
    }
  else if (error)
    {
      gimp_message (dialog->image->gimp, G_OBJECT (dialog->dialog),
                    GIMP_MESSAGE_ERROR,
                    "%s", error->message);
      g_clear_error (&error);
    }

  gimp_color_profile_combo_box_set_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                                NULL, NULL);

  return combo;
}
예제 #21
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;
}
예제 #22
0
static void
gimp_image_undo_pop (GimpUndo            *undo,
                     GimpUndoMode         undo_mode,
                     GimpUndoAccumulator *accum)
{
  GimpImageUndo    *image_undo = GIMP_IMAGE_UNDO (undo);
  GimpImage        *image      = undo->image;
  GimpImagePrivate *private    = GIMP_IMAGE_GET_PRIVATE (image);

  GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);

  switch (undo->undo_type)
    {
    case GIMP_UNDO_IMAGE_TYPE:
      {
        GimpImageBaseType base_type;

        base_type = image_undo->base_type;
        image_undo->base_type = gimp_image_get_base_type (image);
        g_object_set (image, "base-type", base_type, NULL);

        gimp_image_colormap_changed (image, -1);

        if (image_undo->base_type != gimp_image_get_base_type (image))
          accum->mode_changed = TRUE;
      }
      break;

    case GIMP_UNDO_IMAGE_PRECISION:
      {
        GimpPrecision precision;

        precision = image_undo->precision;
        image_undo->precision = gimp_image_get_precision (image);
        g_object_set (image, "precision", precision, NULL);

        if (image_undo->precision != gimp_image_get_precision (image))
          accum->precision_changed = TRUE;
      }
      break;

    case GIMP_UNDO_IMAGE_SIZE:
      {
        gint width;
        gint height;
        gint previous_origin_x;
        gint previous_origin_y;
        gint previous_width;
        gint previous_height;

        width             = image_undo->width;
        height            = image_undo->height;
        previous_origin_x = image_undo->previous_origin_x;
        previous_origin_y = image_undo->previous_origin_y;
        previous_width    = image_undo->previous_width;
        previous_height   = image_undo->previous_height;

        /* Transform to a redo */
        image_undo->width             = gimp_image_get_width  (image);
        image_undo->height            = gimp_image_get_height (image);
        image_undo->previous_origin_x = -previous_origin_x;
        image_undo->previous_origin_y = -previous_origin_y;
        image_undo->previous_width    = width;
        image_undo->previous_height   = height;

        g_object_set (image,
                      "width",  width,
                      "height", height,
                      NULL);

        gimp_drawable_invalidate_boundary
          (GIMP_DRAWABLE (gimp_image_get_mask (image)));

        if (gimp_image_get_width  (image) != image_undo->width ||
            gimp_image_get_height (image) != image_undo->height)
          {
            accum->size_changed      = TRUE;
            accum->previous_origin_x = previous_origin_x;
            accum->previous_origin_y = previous_origin_y;
            accum->previous_width    = previous_width;
            accum->previous_height   = previous_height;
          }
      }
      break;

    case GIMP_UNDO_IMAGE_RESOLUTION:
      {
        gdouble xres;
        gdouble yres;

        gimp_image_get_resolution (image, &xres, &yres);

        if (ABS (image_undo->xresolution - xres) >= 1e-5 ||
            ABS (image_undo->yresolution - yres) >= 1e-5)
          {
            private->xresolution = image_undo->xresolution;
            private->yresolution = image_undo->yresolution;

            image_undo->xresolution = xres;
            image_undo->yresolution = yres;

            accum->resolution_changed = TRUE;
          }
      }
예제 #23
0
gboolean
plug_in_icc_profile_apply_rgb (GimpImage     *image,
                               GimpContext   *context,
                               GimpProgress  *progress,
                               GimpRunMode    run_mode,
                               GError       **error)
{
  Gimp          *gimp;
  GimpProcedure *procedure;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  gimp = image->gimp;

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      g_set_error (error, GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED,
                   _("Can't apply color profile to grayscale image (%s)"),
                   ICC_PROFILE_APPLY_RGB_PROC);
      return FALSE;
    }

  procedure = gimp_pdb_lookup_procedure (gimp->pdb, ICC_PROFILE_APPLY_RGB_PROC);

  if (procedure &&
      procedure->num_args >= 2 &&
      GIMP_IS_PARAM_SPEC_INT32 (procedure->args[0]) &&
      GIMP_IS_PARAM_SPEC_IMAGE_ID (procedure->args[1]))
    {
      GimpValueArray         *return_vals;
      GimpPDBStatusType       status;
      GimpColorProfilePolicy  policy = GIMP_COLOR_PROFILE_POLICY_ASK;
      gboolean                success;

      return_vals =
        gimp_pdb_execute_procedure_by_name (gimp->pdb, context, progress, error,
                                            ICC_PROFILE_APPLY_RGB_PROC,
                                            GIMP_TYPE_INT32, run_mode,
                                            GIMP_TYPE_IMAGE_ID,
                                            gimp_image_get_ID (image),
                                            G_TYPE_NONE);

      status = g_value_get_enum (gimp_value_array_index (return_vals, 0));

      switch (status)
        {
        case GIMP_PDB_SUCCESS:
          policy = GIMP_COLOR_PROFILE_POLICY_CONVERT;
          success = TRUE;
          break;

        case GIMP_PDB_CANCEL:
          policy = GIMP_COLOR_PROFILE_POLICY_KEEP;
          success = TRUE;
          break;

        default:
          if (error && *error == NULL)
            g_set_error (error,
                         GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_EXECUTION_FAILED,
                         _("Error running '%s'"), ICC_PROFILE_APPLY_RGB_PROC);
          success = FALSE;
          break;
        }

      if (success && gimp_value_array_length (return_vals) > 1)
        {
          GValue *value = gimp_value_array_index (return_vals, 1);

          if (GIMP_VALUE_HOLDS_INT32 (value) && g_value_get_int (value))
            {
              g_object_set (G_OBJECT (gimp->config),
                            "color-profile-policy", policy,
                            NULL);
            }
        }

      gimp_value_array_unref (return_vals);

      return success;
    }

  g_set_error (error,
               GIMP_PLUG_IN_ERROR, GIMP_PLUG_IN_NOT_FOUND,
               _("Plug-In missing (%s)"), ICC_PROFILE_APPLY_RGB_PROC);

  return FALSE;
}
예제 #24
0
GimpImage *
gimp_image_duplicate (GimpImage *image)
{
  GimpImage    *new_image;
  GimpLayer    *active_layer;
  GimpChannel  *active_channel;
  GimpVectors  *active_vectors;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  gimp_set_busy_until_idle (image->gimp);

  /*  Create a new image  */
  new_image = gimp_create_image (image->gimp,
                                 gimp_image_get_width  (image),
                                 gimp_image_get_height (image),
                                 gimp_image_get_base_type (image),
                                 gimp_image_get_precision (image),
                                 FALSE);
  gimp_image_undo_disable (new_image);

  /*  Store the source uri to be used by the save dialog  */
  gimp_image_duplicate_save_source_uri (image, new_image);


  /*  Copy the colormap if necessary  */
  gimp_image_duplicate_colormap (image, new_image);

  /*  Copy resolution information  */
  gimp_image_duplicate_resolution (image, new_image);

  /*  Copy the layers  */
  active_layer = gimp_image_duplicate_layers (image, new_image);

  /*  Copy the channels  */
  active_channel = gimp_image_duplicate_channels (image, new_image);

  /*  Copy any vectors  */
  active_vectors = gimp_image_duplicate_vectors (image, new_image);

  /*  Copy floating layer  */
  gimp_image_duplicate_floating_sel (image, new_image);

  /*  Copy the selection mask  */
  gimp_image_duplicate_mask (image, new_image);

  /*  Set active layer, active channel, active vectors  */
  if (active_layer)
    gimp_image_set_active_layer (new_image, active_layer);

  if (active_channel)
    gimp_image_set_active_channel (new_image, active_channel);

  if (active_vectors)
    gimp_image_set_active_vectors (new_image, active_vectors);

  /*  Copy state of all color components  */
  gimp_image_duplicate_components (image, new_image);

  /*  Copy any guides  */
  gimp_image_duplicate_guides (image, new_image);

  /*  Copy any sample points  */
  gimp_image_duplicate_sample_points (image, new_image);

  /*  Copy the grid  */
  gimp_image_duplicate_grid (image, new_image);

  /*  Copy the quick mask info  */
  gimp_image_duplicate_quick_mask (image, new_image);

  /*  Copy parasites  */
  gimp_image_duplicate_parasites (image, new_image);

  gimp_image_undo_enable (new_image);

  return new_image;
}
예제 #25
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)
{
  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);
}
예제 #26
0
void
gimp_image_import_color_profile (GimpImage    *image,
                                 GimpContext  *context,
                                 GimpProgress *progress,
                                 gboolean      interactive)
{
  GimpColorConfig *config = image->gimp->config->color_management;

  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));

  config = image->gimp->config->color_management;

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    return;

  if (config->mode == GIMP_COLOR_MANAGEMENT_OFF)
    return;

  if (gimp_image_get_color_profile (image))
    {
      GimpColorProfilePolicy  policy;
      GimpColorProfile       *dest_profile = NULL;

      policy = image->gimp->config->color_profile_policy;

      if (policy == GIMP_COLOR_PROFILE_POLICY_ASK)
        {
          if (interactive)
            {
              gboolean dont_ask = FALSE;

              policy = gimp_query_profile_policy (image->gimp, image, context,
                                                  &dest_profile, &dont_ask);

              if (dont_ask)
                {
                  g_object_set (G_OBJECT (image->gimp->config),
                                "color-profile-policy", policy,
                                NULL);
                }
            }
          else
            {
              policy = GIMP_COLOR_PROFILE_POLICY_KEEP;
            }
        }

      if (policy == GIMP_COLOR_PROFILE_POLICY_CONVERT)
        {
          GimpColorRenderingIntent  intent;
          gboolean                  bpc;

          if (! dest_profile)
            {
              dest_profile = gimp_image_get_builtin_color_profile (image);
              g_object_ref (dest_profile);
            }

          intent = config->display_intent;
          bpc    = (intent == GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC);

          gimp_image_undo_disable (image);

          gimp_image_convert_color_profile (image, dest_profile,
                                            intent, bpc,
                                            progress, NULL);

          gimp_image_clean_all (image);
          gimp_image_undo_enable (image);

          g_object_unref (dest_profile);
        }
    }
}
GimpColorProfilePolicy
color_profile_import_dialog_run (GimpImage         *image,
                                 GimpContext       *context,
                                 GtkWidget         *parent,
                                 GimpColorProfile **dest_profile,
                                 gboolean          *dont_ask)
{
  GtkWidget              *dialog;
  GtkWidget              *main_vbox;
  GtkWidget              *frame;
  GtkWidget              *label;
  GtkWidget              *toggle;
  GimpColorProfile       *src_profile;
  GimpColorProfilePolicy  policy;
  const gchar            *title;
  const gchar            *frame_title;
  gchar                  *text;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), GIMP_COLOR_PROFILE_POLICY_KEEP);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_COLOR_PROFILE_POLICY_KEEP);
  g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent),
                        GIMP_COLOR_PROFILE_POLICY_KEEP);
  g_return_val_if_fail (dest_profile != NULL, GIMP_COLOR_PROFILE_POLICY_KEEP);

  src_profile   = gimp_image_get_color_profile (image);
  *dest_profile = gimp_image_get_builtin_color_profile (image);

  if (gimp_image_get_base_type (image) == GIMP_GRAY)
    {
      title       = _("Convert to Grayscale Working Space?");
      frame_title = _("Convert the image to the grayscale working space?");
    }
  else
    {
      title       = _("Convert to RGB Working Space?");
      frame_title = _("Convert the image to the RGB working space?");
    }

  dialog =
    gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context,
                              title,
                              "gimp-image-color-profile-import",
                              NULL,
                              _("Import the image from a color profile"),
                              parent,
                              gimp_standard_help_func,
                              GIMP_HELP_IMAGE_COLOR_PROFILE_IMPORT,

                              _("Keep"),    GTK_RESPONSE_CANCEL,
                              _("Convert"), GTK_RESPONSE_OK,

                              NULL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);

  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
                      main_vbox, TRUE, TRUE, 0);
  gtk_widget_show (main_vbox);

  text = g_strdup_printf (_("The image '%s' has an embedded color profile"),
                          gimp_image_get_display_name (image));
  frame = gimp_frame_new (text);
  g_free (text);
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  label = gimp_color_profile_label_new (src_profile);
  gtk_container_add (GTK_CONTAINER (frame), label);
  gtk_widget_show (label);

  frame = gimp_frame_new (frame_title);
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  label = gimp_color_profile_label_new (*dest_profile);
  gtk_container_add (GTK_CONTAINER (frame), label);
  gtk_widget_show (label);

  if (dont_ask)
    {
      toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again"));
      gtk_box_pack_end (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 0);
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
      gtk_widget_show (toggle);
    }

  switch (gtk_dialog_run (GTK_DIALOG (dialog)))
    {
    case GTK_RESPONSE_OK:
      policy = GIMP_COLOR_PROFILE_POLICY_CONVERT;
      g_object_ref (*dest_profile);
      break;

    default:
      policy = GIMP_COLOR_PROFILE_POLICY_KEEP;
      break;
    }

  if (dont_ask)
    {
      *dont_ask = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
    }

  gtk_widget_destroy (dialog);

  return policy;
}