[gimp] app: make replacing a drawable's format use almost no undo memory
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: make replacing a drawable's format use almost no undo memory
- Date: Tue, 24 Jul 2018 11:50:56 +0000 (UTC)
commit 248199e997666e8498da5fe052461fb615b20f9d
Author: Michael Natterer <mitch gimp org>
Date: Tue Jul 24 12:20:17 2018 +0200
app: make replacing a drawable's format use almost no undo memory
Add gimp_drawable_set_format() as low-level part of
gimp_layer_fix_format_space(), and add a special undo type for it that
only remembers the format and not the entire drawable buffer, because
all pixels stay the same.
app/core/Makefile.am | 2 +
app/core/core-enums.c | 2 +
app/core/core-enums.h | 1 +
app/core/gimpdrawable.c | 49 +++++++++++++
app/core/gimpdrawable.h | 5 ++
app/core/gimpdrawablepropundo.c | 158 ++++++++++++++++++++++++++++++++++++++++
app/core/gimpdrawablepropundo.h | 52 +++++++++++++
app/core/gimpimage-undo-push.c | 17 +++++
app/core/gimpimage-undo-push.h | 3 +
app/core/gimplayer.c | 22 +-----
10 files changed, 290 insertions(+), 21 deletions(-)
---
diff --git a/app/core/Makefile.am b/app/core/Makefile.am
index ff45c4d5dd..9d2aa11b27 100644
--- a/app/core/Makefile.am
+++ b/app/core/Makefile.am
@@ -206,6 +206,8 @@ libappcore_a_sources = \
gimpdrawablefilter.h \
gimpdrawablemodundo.c \
gimpdrawablemodundo.h \
+ gimpdrawablepropundo.c \
+ gimpdrawablepropundo.h \
gimpdrawablestack.c \
gimpdrawablestack.h \
gimpdrawableundo.c \
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 993670f3a2..3561f06531 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -1080,6 +1080,7 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_SAMPLE_POINT, "GIMP_UNDO_SAMPLE_POINT", "sample-point" },
{ GIMP_UNDO_DRAWABLE, "GIMP_UNDO_DRAWABLE", "drawable" },
{ GIMP_UNDO_DRAWABLE_MOD, "GIMP_UNDO_DRAWABLE_MOD", "drawable-mod" },
+ { GIMP_UNDO_DRAWABLE_FORMAT, "GIMP_UNDO_DRAWABLE_FORMAT", "drawable-format" },
{ GIMP_UNDO_MASK, "GIMP_UNDO_MASK", "mask" },
{ GIMP_UNDO_ITEM_REORDER, "GIMP_UNDO_ITEM_REORDER", "item-reorder" },
{ GIMP_UNDO_ITEM_RENAME, "GIMP_UNDO_ITEM_RENAME", "item-rename" },
@@ -1178,6 +1179,7 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_SAMPLE_POINT, NC_("undo-type", "Sample Point"), NULL },
{ GIMP_UNDO_DRAWABLE, NC_("undo-type", "Layer/Channel"), NULL },
{ GIMP_UNDO_DRAWABLE_MOD, NC_("undo-type", "Layer/Channel modification"), NULL },
+ { GIMP_UNDO_DRAWABLE_FORMAT, NC_("undo-type", "Layer/Channel format"), NULL },
{ GIMP_UNDO_MASK, NC_("undo-type", "Selection mask"), NULL },
{ GIMP_UNDO_ITEM_REORDER, NC_("undo-type", "Reorder item"), NULL },
{ GIMP_UNDO_ITEM_RENAME, NC_("undo-type", "Rename item"), NULL },
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 90a690643a..8a53014198 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -515,6 +515,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_SAMPLE_POINT, /*< desc="Sample Point" >*/
GIMP_UNDO_DRAWABLE, /*< desc="Layer/Channel" >*/
GIMP_UNDO_DRAWABLE_MOD, /*< desc="Layer/Channel modification" >*/
+ GIMP_UNDO_DRAWABLE_FORMAT, /*< desc="Layer/Channel format" >*/
GIMP_UNDO_MASK, /*< desc="Selection mask" >*/
GIMP_UNDO_ITEM_REORDER, /*< desc="Reorder item" >*/
GIMP_UNDO_ITEM_RENAME, /*< desc="Rename item" >*/
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index ce8302e24e..e0c21214d3 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -1314,6 +1314,55 @@ gimp_drawable_steal_buffer (GimpDrawable *drawable,
g_object_unref (buffer);
}
+void
+gimp_drawable_set_format (GimpDrawable *drawable,
+ const Babl *format,
+ gboolean copy_buffer,
+ gboolean push_undo)
+{
+ GimpItem *item;
+ GeglBuffer *buffer;
+
+ g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+ g_return_if_fail (format != NULL);
+ g_return_if_fail (format != gimp_drawable_get_format (drawable));
+ g_return_if_fail (gimp_babl_format_get_base_type (format) ==
+ gimp_drawable_get_base_type (drawable));
+ g_return_if_fail (gimp_babl_format_get_component_type (format) ==
+ gimp_drawable_get_component_type (drawable));
+ g_return_if_fail (babl_format_has_alpha (format) ==
+ gimp_drawable_has_alpha (drawable));
+ g_return_if_fail (push_undo == FALSE || copy_buffer == TRUE);
+
+ item = GIMP_ITEM (drawable);
+
+ if (! gimp_item_is_attached (item))
+ push_undo = FALSE;
+
+ if (push_undo)
+ gimp_image_undo_push_drawable_format (gimp_item_get_image (item),
+ NULL, drawable);
+
+ buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ gimp_item_get_width (item),
+ gimp_item_get_height (item)),
+ format);
+
+ if (copy_buffer)
+ {
+ gegl_buffer_set_format (buffer, gimp_drawable_get_format (drawable));
+
+ gimp_gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
+ NULL, GEGL_ABYSS_NONE,
+ buffer, NULL);
+
+ gegl_buffer_set_format (buffer, NULL);
+ }
+
+ gimp_drawable_set_buffer (drawable, FALSE, NULL, buffer);
+ g_object_unref (buffer);
+}
+
GeglNode *
gimp_drawable_get_source_node (GimpDrawable *drawable)
{
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index 659139ff1b..0ebd5ca875 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -192,6 +192,11 @@ void gimp_drawable_set_buffer_full (GimpDrawable *drawable,
void gimp_drawable_steal_buffer (GimpDrawable *drawable,
GimpDrawable *src_drawable);
+void gimp_drawable_set_format (GimpDrawable *drawable,
+ const Babl *format,
+ gboolean copy_buffer,
+ gboolean push_undo);
+
GeglNode * gimp_drawable_get_source_node (GimpDrawable *drawable);
GeglNode * gimp_drawable_get_mode_node (GimpDrawable *drawable);
diff --git a/app/core/gimpdrawablepropundo.c b/app/core/gimpdrawablepropundo.c
new file mode 100644
index 0000000000..159892fce3
--- /dev/null
+++ b/app/core/gimpdrawablepropundo.c
@@ -0,0 +1,158 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gegl.h>
+
+#include "core-types.h"
+
+#include "gegl/gimp-gegl-utils.h"
+
+#include "gimp-memsize.h"
+#include "gimpimage.h"
+#include "gimpdrawable.h"
+#include "gimpdrawablepropundo.h"
+
+
+enum
+{
+ PROP_0
+};
+
+
+static void gimp_drawable_prop_undo_constructed (GObject *object);
+static void gimp_drawable_prop_undo_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_drawable_prop_undo_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_drawable_prop_undo_pop (GimpUndo *undo,
+ GimpUndoMode undo_mode,
+ GimpUndoAccumulator *accum);
+
+
+G_DEFINE_TYPE (GimpDrawablePropUndo, gimp_drawable_prop_undo,
+ GIMP_TYPE_ITEM_UNDO)
+
+#define parent_class gimp_drawable_prop_undo_parent_class
+
+
+static void
+gimp_drawable_prop_undo_class_init (GimpDrawablePropUndoClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
+
+ object_class->constructed = gimp_drawable_prop_undo_constructed;
+ object_class->set_property = gimp_drawable_prop_undo_set_property;
+ object_class->get_property = gimp_drawable_prop_undo_get_property;
+
+ undo_class->pop = gimp_drawable_prop_undo_pop;
+}
+
+static void
+gimp_drawable_prop_undo_init (GimpDrawablePropUndo *undo)
+{
+}
+
+static void
+gimp_drawable_prop_undo_constructed (GObject *object)
+{
+ GimpDrawablePropUndo *drawable_prop_undo = GIMP_DRAWABLE_PROP_UNDO (object);
+ GimpDrawable *drawable;
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ gimp_assert (GIMP_IS_DRAWABLE (GIMP_ITEM_UNDO (object)->item));
+
+ drawable = GIMP_DRAWABLE (GIMP_ITEM_UNDO (object)->item);
+
+ switch (GIMP_UNDO (object)->undo_type)
+ {
+ case GIMP_UNDO_DRAWABLE_FORMAT:
+ drawable_prop_undo->format = gimp_drawable_get_format (drawable);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
+
+static void
+gimp_drawable_prop_undo_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_drawable_prop_undo_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_drawable_prop_undo_pop (GimpUndo *undo,
+ GimpUndoMode undo_mode,
+ GimpUndoAccumulator *accum)
+{
+ GimpDrawablePropUndo *drawable_prop_undo = GIMP_DRAWABLE_PROP_UNDO (undo);
+ GimpDrawable *drawable;
+
+ drawable = GIMP_DRAWABLE (GIMP_ITEM_UNDO (undo)->item);
+
+ GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
+
+ switch (undo->undo_type)
+ {
+ case GIMP_UNDO_DRAWABLE_FORMAT:
+ {
+ const Babl *format = gimp_drawable_get_format (drawable);
+
+ gimp_drawable_set_format (drawable,
+ drawable_prop_undo->format,
+ TRUE, FALSE);
+
+ drawable_prop_undo->format = format;
+ }
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
diff --git a/app/core/gimpdrawablepropundo.h b/app/core/gimpdrawablepropundo.h
new file mode 100644
index 0000000000..4cb9fb56bf
--- /dev/null
+++ b/app/core/gimpdrawablepropundo.h
@@ -0,0 +1,52 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_DRAWABLE_PROP_UNDO_H__
+#define __GIMP_DRAWABLE_PROP_UNDO_H__
+
+
+#include "gimpitemundo.h"
+
+
+#define GIMP_TYPE_DRAWABLE_PROP_UNDO (gimp_drawable_prop_undo_get_type ())
+#define GIMP_DRAWABLE_PROP_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GIMP_TYPE_DRAWABLE_PROP_UNDO, GimpDrawablePropUndo))
+#define GIMP_DRAWABLE_PROP_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GIMP_TYPE_DRAWABLE_PROP_UNDO, GimpDrawablePropUndoClass))
+#define GIMP_IS_DRAWABLE_PROP_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GIMP_TYPE_DRAWABLE_PROP_UNDO))
+#define GIMP_IS_DRAWABLE_PROP_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GIMP_TYPE_DRAWABLE_PROP_UNDO))
+#define GIMP_DRAWABLE_PROP_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GIMP_TYPE_DRAWABLE_PROP_UNDO, GimpDrawablePropUndoClass))
+
+
+typedef struct _GimpDrawablePropUndo GimpDrawablePropUndo;
+typedef struct _GimpDrawablePropUndoClass GimpDrawablePropUndoClass;
+
+struct _GimpDrawablePropUndo
+{
+ GimpItemUndo parent_instance;
+
+ const Babl *format;
+};
+
+struct _GimpDrawablePropUndoClass
+{
+ GimpItemUndoClass parent_class;
+};
+
+
+GType gimp_drawable_prop_undo_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_DRAWABLE_PROP_UNDO_H__ */
diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c
index b96c4b45b8..18880586de 100644
--- a/app/core/gimpimage-undo-push.c
+++ b/app/core/gimpimage-undo-push.c
@@ -28,6 +28,7 @@
#include "gimpchannelpropundo.h"
#include "gimpchannelundo.h"
#include "gimpdrawablemodundo.h"
+#include "gimpdrawablepropundo.h"
#include "gimpdrawableundo.h"
#include "gimpfloatingselectionundo.h"
#include "gimpgrid.h"
@@ -288,6 +289,22 @@ gimp_image_undo_push_drawable_mod (GimpImage *image,
NULL);
}
+GimpUndo *
+gimp_image_undo_push_drawable_format (GimpImage *image,
+ const gchar *undo_desc,
+ GimpDrawable *drawable)
+{
+ g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
+ g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
+
+ return gimp_image_undo_push (image, GIMP_TYPE_DRAWABLE_PROP_UNDO,
+ GIMP_UNDO_DRAWABLE_FORMAT, undo_desc,
+ GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
+ "item", drawable,
+ NULL);
+}
+
/****************/
/* Mask Undos */
diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h
index f06fcd873e..0cbd19a357 100644
--- a/app/core/gimpimage-undo-push.h
+++ b/app/core/gimpimage-undo-push.h
@@ -72,6 +72,9 @@ GimpUndo * gimp_image_undo_push_drawable_mod (GimpImage *image,
const gchar *undo_desc,
GimpDrawable *drawable,
gboolean copy_buffer);
+GimpUndo * gimp_image_undo_push_drawable_format (GimpImage *image,
+ const gchar *undo_desc,
+ GimpDrawable *drawable);
/* mask undos */
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index b1fdd4d361..616c9ca2d3 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -1807,27 +1807,7 @@ gimp_layer_fix_format_space (GimpLayer *layer,
if (format != gimp_drawable_get_format (drawable))
{
- GeglBuffer *buffer;
-
- buffer = gegl_buffer_new
- (GEGL_RECTANGLE (0, 0,
- gimp_item_get_width (GIMP_ITEM (layer)),
- gimp_item_get_height (GIMP_ITEM (layer))),
- format);
-
- if (copy_buffer)
- {
- gegl_buffer_set_format (buffer, gimp_drawable_get_format (drawable));
-
- gimp_gegl_buffer_copy (gimp_drawable_get_buffer (drawable),
- NULL, GEGL_ABYSS_NONE,
- buffer, NULL);
-
- gegl_buffer_set_format (buffer, NULL);
- }
-
- gimp_drawable_set_buffer (drawable, push_undo, NULL, buffer);
- g_object_unref (buffer);
+ gimp_drawable_set_format (drawable, format, copy_buffer, push_undo);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]