[gimp] plugins: Port compose.c to gegl
- From: Téo Mazars <teom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plugins: Port compose.c to gegl
- Date: Sun, 7 Jul 2013 14:08:56 +0000 (UTC)
commit 409cb44e6febfe42f80c51063cfccd483a53c06a
Author: Téo Mazars <teo mazars ensimag fr>
Date: Sun Jul 7 15:55:42 2013 +0200
plugins: Port compose.c to gegl
plug-ins/common/Makefile.am | 1 +
plug-ins/common/compose.c | 1193 +++++++++++++---------------------------
plug-ins/common/plugin-defs.pl | 2 +-
3 files changed, 385 insertions(+), 811 deletions(-)
---
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index b0bd927..ce6fd8e 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -576,6 +576,7 @@ compose_LDADD = \
$(libgimpcolor) \
$(libgimpbase) \
$(GTK_LIBS) \
+ $(GEGL_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(compose_RC)
diff --git a/plug-ins/common/compose.c b/plug-ins/common/compose.c
index 2c9cc65..1c16194 100644
--- a/plug-ins/common/compose.c
+++ b/plug-ins/common/compose.c
@@ -29,6 +29,11 @@
* added by Sylvain FORET.
*/
+/*
+ * All redundant _256 versions of YCbCr* are here only for compatibility .
+ * They can be dropped for GIMP 3.0
+ */
+
#include "config.h"
#include <string.h>
@@ -45,6 +50,8 @@
#define PLUG_IN_BINARY "compose"
#define PLUG_IN_ROLE "gimp-compose"
+/* Maximum number of images to compose */
+#define MAX_COMPOSE_IMAGES 4
typedef struct
{
@@ -56,229 +63,208 @@ typedef struct
gboolean is_ID;
} ComposeInput;
+/* Description of a component */
+typedef struct
+{
+ const gchar *babl_name;
+ const gchar *name;
+ const gchar *icon;
+ const float range_min; /* val min of the component */
+ const float range_max; /* val max of the component */
+ const gboolean is_perceptual; /* Take the componenent from an Y' or Y buffer */
+} COMPONENT_DSC;
+
+/* Description of a composition */
+typedef struct
+{
+ const gchar *babl_model;
+ const gchar *compose_type; /* Type of composition ("RGB", "RGBA",...) */
+ gint num_images; /* Number of input images needed */
+ /* Channel informations */
+ const COMPONENT_DSC components[MAX_COMPOSE_IMAGES];
+ const gchar *filename; /* Name of new image */
+
+} COMPOSE_DSC;
+
/* Declare local functions
*/
-static void query (void);
-static void run (const gchar *name,
- gint nparams,
- const GimpParam *param,
- gint *nreturn_vals,
- GimpParam **return_vals);
-
-static gint32 compose (const gchar *compose_type,
- ComposeInput *inputs,
- gboolean compose_by_drawable);
-
-static gint32 create_new_image (const gchar *filename,
- guint width,
- guint height,
- GimpImageType gdtype,
- gint32 *layer_ID,
- GimpDrawable **drawable,
- GimpPixelRgn *pixel_rgn);
-
-static void compose_rgb (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_rgba (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_hsv (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_hsl (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_cmy (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_cmyk (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_lab (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_ycbcr470 (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_ycbcr709 (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_ycbcr470f (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-static void compose_ycbcr709f (guchar **src,
- gint *incr,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-
-static gboolean compose_dialog (const gchar *compose_type,
- gint32 drawable_ID);
-
-static gboolean check_gray (gint32 image_id,
- gint32 drawable_id,
- gpointer data);
-
-static void combo_callback (GimpIntComboBox *cbox,
- gpointer data);
-
-static void scale_callback (GtkAdjustment *adj,
- ComposeInput *input);
-
-static void check_response (GtkWidget *dialog,
- gint response,
- gpointer data);
-
-static void type_combo_callback (GimpIntComboBox *combo,
- gpointer data);
-
-
-/* LAB colorspace constants */
-static const double Xn = 0.951;
-static const double Yn = 1.0;
-static const double Zn = 1.089;
+static void query (void);
+static void run (const gchar *name,
+ gint nparams,
+ const GimpParam *param,
+ gint *nreturn_vals,
+ GimpParam **return_vals);
-/* Maximum number of images to compose */
-#define MAX_COMPOSE_IMAGES 4
+static void cpn_affine_transform (GeglBuffer *buffer,
+ gdouble min,
+ gdouble max);
+static void fill_buffer_from_components (GeglBuffer *temp[MAX_COMPOSE_IMAGES],
+ GeglBuffer *dst,
+ gint num_cpn,
+ ComposeInput *inputs,
+ gdouble mask_vals[MAX_COMPOSE_IMAGES]);
-/* Description of a composition */
-typedef struct
-{
- const gchar *compose_type; /* Type of composition ("RGB", "RGBA",...) */
- gint num_images; /* Number of input images needed */
- /* Channel names and stock ids for dialog */
- const gchar *channel_name[MAX_COMPOSE_IMAGES];
- const gchar *channel_icon[MAX_COMPOSE_IMAGES];
- const gchar *filename; /* Name of new image */
-
- /* Compose functon */
- void (* compose_fun) (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha);
-} COMPOSE_DSC;
+static void perform_composition (COMPOSE_DSC curr_compose_dsc,
+ GeglBuffer *buffer_src[MAX_COMPOSE_IMAGES],
+ GeglBuffer *buffer_dst,
+ ComposeInput *inputs,
+ gint num_images);
+
+static gint32 compose (const gchar *compose_type,
+ ComposeInput *inputs,
+ gboolean compose_by_drawable);
+
+static gint32 create_new_image (const gchar *filename,
+ guint width,
+ guint height,
+ GimpImageType gdtype,
+ GimpPrecision precision,
+ gint32 *layer_ID,
+ GeglBuffer **drawable);
+
+static gboolean compose_dialog (const gchar *compose_type,
+ gint32 drawable_ID);
+
+static gboolean check_gray (gint32 image_id,
+ gint32 drawable_id,
+ gpointer data);
+
+static void combo_callback (GimpIntComboBox *cbox,
+ gpointer data);
+
+static void scale_callback (GtkAdjustment *adj,
+ ComposeInput *input);
+
+static void check_response (GtkWidget *dialog,
+ gint response,
+ gpointer data);
+
+static void type_combo_callback (GimpIntComboBox *combo,
+ gpointer data);
+
+
+
+/* Decompositions availables.
+ * All the following values have to be kept in sync with those of decompose.c
+ */
+
+#define CPN_RGBA_R {"R", N_("_Red:"), GIMP_STOCK_CHANNEL_RED, 0.0, 1.0, FALSE}
+#define CPN_RGBA_G {"G", N_("_Green:"), GIMP_STOCK_CHANNEL_GREEN, 0.0, 1.0, FALSE}
+#define CPN_RGBA_B {"B", N_("_Blue:"), GIMP_STOCK_CHANNEL_BLUE, 0.0, 1.0, FALSE}
+#define CPN_RGBA_A {"A", N_("_Alpha:"), GIMP_STOCK_CHANNEL_ALPHA, 0.0, 1.0, TRUE}
+
+#define CPN_HSV_H {"hue", N_("_Hue:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_HSV_S {"saturation", N_("_Saturation:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_HSV_V {"value", N_("_Value:"), NULL, 0.0, 1.0, TRUE}
+
+#define CPN_HSL_H {"hue", N_("_Hue:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_HSL_S {"saturation", N_("_Saturation:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_HSL_L {"lightness", N_("_Lightness:"), NULL, 0.0, 1.0, TRUE}
+
+#define CPN_CMYK_C {"cyan", N_("_Cyan:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_CMYK_M {"magenta", N_("_Magenta:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_CMYK_Y {"yellow", N_("_Yellow:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_CMYK_K {"key", N_("_Black:"), NULL, 0.0, 1.0, TRUE}
+
+#define CPN_CMY_C {"cyan", N_("_Cyan:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_CMY_M {"magenta", N_("_Magenta:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_CMY_Y {"yellow", N_("_Yellow:"), NULL, 0.0, 1.0, TRUE}
+
+#define CPN_LAB_L {"CIE L", N_("_L:"), NULL, 0.0, 100.0, TRUE}
+#define CPN_LAB_A {"CIE a", N_("_A:"), NULL, -128.0, 127.0, TRUE}
+#define CPN_LAB_B {"CIE b", N_("_B:"), NULL, -128.0, 127.0, TRUE}
+
+#define CPN_YCBCR_Y {"Y'", N_("_Luma y470:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_YCBCR_CB {"Cb", N_("_Blueness cb470:"), NULL, -0.5, 0.5, TRUE}
+#define CPN_YCBCR_CR {"Cr", N_("_Redness cr470:"), NULL, -0.5, 0.5, TRUE}
+
+#define CPN_YCBCR709_Y {"Y'", N_("_Luma y709:"), NULL, 0.0, 1.0, TRUE}
+#define CPN_YCBCR709_CB {"Cb", N_("_Blueness cb709:"), NULL, -0.5, 0.5, TRUE}
+#define CPN_YCBCR709_CR {"Cr", N_("_Redness cr709:"), NULL, -0.5, 0.5, TRUE}
-/* Array of available compositions. */
static COMPOSE_DSC compose_dsc[] =
{
- { N_("RGB"), 3,
- { N_("_Red:"),
- N_("_Green:"),
- N_("_Blue:"),
- NULL },
- { GIMP_STOCK_CHANNEL_RED,
- GIMP_STOCK_CHANNEL_GREEN,
- GIMP_STOCK_CHANNEL_BLUE,
- NULL },
- "rgb-compose", compose_rgb },
-
- { N_("RGBA"), 4,
- { N_("_Red:"),
- N_("_Green:"),
- N_("_Blue:"),
- N_("_Alpha:") },
- { GIMP_STOCK_CHANNEL_RED,
- GIMP_STOCK_CHANNEL_GREEN,
- GIMP_STOCK_CHANNEL_BLUE,
- GIMP_STOCK_CHANNEL_ALPHA },
- "rgba-compose", compose_rgba },
-
- { N_("HSV"), 3,
- { N_("_Hue:"),
- N_("_Saturation:"),
- N_("_Value:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "hsv-compose", compose_hsv },
-
- { N_("HSL"), 3,
- { N_("_Hue:"),
- N_("_Saturation:"),
- N_("_Lightness:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "hsl-compose", compose_hsl },
-
- { N_("CMY"), 3,
- { N_("_Cyan:"),
- N_("_Magenta:"),
- N_("_Yellow:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "cmy-compose", compose_cmy },
-
- { N_("CMYK"), 4,
- { N_("_Cyan:"),
- N_("_Magenta:"),
- N_("_Yellow:"),
- N_("_Black:") },
- { NULL, NULL, NULL, NULL },
- "cmyk-compose", compose_cmyk },
-
- { N_("LAB"), 3,
- { "_L:",
- "_A:",
- "_B:",
- NULL },
- { NULL, NULL, NULL, NULL },
- "lab-compose", compose_lab },
-
- { "YCbCr_ITU_R470", 3,
- { N_("_Luma y470:"),
- N_("_Blueness cb470:"),
- N_("_Redness cr470:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "ycbcr470-compose", compose_ycbcr470 },
-
- { "YCbCr_ITU_R709", 3,
- { N_("_Luma y709:"),
- N_("_Blueness cb709:"),
- N_("_Redness cr709:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "ycbcr709-compose", compose_ycbcr709 },
-
- { "YCbCr_ITU_R470_256", 3,
- { N_("_Luma y470f:"),
- N_("_Blueness cb470f:"),
- N_("_Redness cr470f:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "ycbcr470F-compose", compose_ycbcr470f },
-
- { "YCbCr_ITU_R709_256", 3,
- { N_("_Luma y709f:"),
- N_("_Blueness cb709f:"),
- N_("_Redness cr709f:"),
- NULL },
- { NULL, NULL, NULL, NULL },
- "ycbcr709F-compose", compose_ycbcr709f },
+ { "RGB",
+ N_("RGB"), 3,
+ { CPN_RGBA_R,
+ CPN_RGBA_G,
+ CPN_RGBA_B },
+ "rgb-compose" },
+
+ { "RGBA",
+ N_("RGBA"), 4,
+ { CPN_RGBA_R,
+ CPN_RGBA_G,
+ CPN_RGBA_B,
+ CPN_RGBA_A },
+ "rgba-compose" },
+
+ { "HSV",
+ N_("HSV"), 3,
+ { CPN_HSV_H,
+ CPN_HSV_S,
+ CPN_HSV_V },
+ "hsv-compose" },
+
+ { "HSL",
+ N_("HSL"), 3,
+ { CPN_HSL_H,
+ CPN_HSL_S,
+ CPN_HSL_L },
+ "hsl-compose" },
+
+ { "CMY",
+ N_("CMY"), 3,
+ { CPN_CMY_C,
+ CPN_CMY_M,
+ CPN_CMY_Y },
+ "cmy-compose" },
+
+ { "CMYK",
+ N_("CMYK"), 4,
+ { CPN_CMYK_C,
+ CPN_CMYK_M,
+ CPN_CMYK_Y,
+ CPN_CMYK_K },
+ "cmyk-compose" },
+
+ { "CIE Lab",
+ N_("LAB"), 3,
+ { CPN_LAB_L,
+ CPN_LAB_A,
+ CPN_LAB_B },
+ "lab-compose" },
+
+ { "Y'CbCr",
+ N_("YCbCr_ITU_R470"), 3,
+ { CPN_YCBCR_Y,
+ CPN_YCBCR_CB,
+ CPN_YCBCR_CR },
+ "ycbcr470-compose" },
+
+ { "Y'CbCr709",
+ N_("YCbCr_ITU_R709"), 3,
+ { CPN_YCBCR709_Y,
+ CPN_YCBCR709_CB,
+ CPN_YCBCR709_CR },
+ "ycbcr709-compose" },
+
+ { "Y'CbCr",
+ N_("YCbCr_ITU_R470_256"), 3,
+ { CPN_YCBCR_Y,
+ CPN_YCBCR_CB,
+ CPN_YCBCR_CR },
+ "ycbcr470F-compose" },
+
+ { "Y'CbCr709",
+ N_("YCbCr_ITU_R709_256"), 3,
+ { CPN_YCBCR709_Y,
+ CPN_YCBCR709_CB,
+ CPN_YCBCR709_CR },
+ "ycbcr709F-compose" },
};
@@ -466,6 +452,7 @@ run (const gchar *name,
gint i;
INIT_I18N ();
+ gegl_init (NULL, NULL);
run_mode = param[0].data.d_int32;
compose_by_drawable = (strcmp (name, DRAWABLE_COMPOSE_PROC) == 0);
@@ -647,6 +634,159 @@ run (const gchar *name,
values[0].data.d_status = status;
}
+static void
+cpn_affine_transform (GeglBuffer *buffer,
+ gdouble min,
+ gdouble max)
+{
+ GeglBufferIterator *gi;
+
+ const gdouble scale = max - min;
+ const gdouble offset = min;
+
+ /* We want to scale values linearly, regardless of the format of the buffer */
+ gegl_buffer_set_format (buffer, babl_format ("Y double"));
+
+ gi = gegl_buffer_iterator_new (buffer, NULL, 0, NULL,
+ GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (gi))
+ {
+ guint k;
+ double *data;
+
+ data = (double*) gi->data[0];
+
+ for (k = 0; k < gi->length; k++)
+ {
+ data[k] = data[k] * scale + offset;
+ }
+ }
+}
+
+static void
+fill_buffer_from_components (GeglBuffer *temp[MAX_COMPOSE_IMAGES],
+ GeglBuffer *dst,
+ gint num_cpn,
+ ComposeInput *inputs,
+ gdouble mask_vals[MAX_COMPOSE_IMAGES])
+{
+ GeglBufferIterator *gi;
+ gint j;
+
+ gi = gegl_buffer_iterator_new (dst, NULL, 0, NULL,
+ GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+
+ for (j = 0; j < num_cpn; j++)
+ {
+ if (inputs[j].is_ID)
+ gegl_buffer_iterator_add (gi, temp[j], NULL, 0, NULL,
+ GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+ }
+
+ while (gegl_buffer_iterator_next (gi))
+ {
+ gulong k, count;
+ gdouble *src_data[MAX_COMPOSE_IMAGES], *dst_data;
+
+ dst_data = (gdouble*) gi->data[0];
+
+ count = 1;
+ for (j = 0; j < num_cpn; j++)
+ if (inputs[j].is_ID)
+ src_data[j] = (gdouble*) gi->data[count++];
+
+ for (k = 0; k < gi->length; k++)
+ {
+ gulong pos = k * num_cpn;
+
+ for (j = 0; j < num_cpn; j++)
+ if (inputs[j].is_ID)
+ dst_data[pos+j] = src_data[j][k];
+ else
+ dst_data[pos+j] = mask_vals[j];
+ }
+ }
+}
+
+static void
+perform_composition (COMPOSE_DSC curr_compose_dsc,
+ GeglBuffer *buffer_src[MAX_COMPOSE_IMAGES],
+ GeglBuffer *buffer_dst,
+ ComposeInput *inputs,
+ gint num_images)
+{
+ const Babl *dst_format;
+ GeglBuffer *temp[MAX_COMPOSE_IMAGES];
+ GeglBuffer *dst_temp;
+ const GeglRectangle *extent = NULL;
+
+ const COMPONENT_DSC *components;
+ gdouble mask_vals[MAX_COMPOSE_IMAGES];
+ gint i;
+
+ components = curr_compose_dsc.components;
+
+ /* Get all individual components in gray buffers */
+ for (i = 0; i < num_images; i++)
+ {
+ COMPONENT_DSC cpn_dsc = components[i];
+ const Babl *gray_format;
+
+ if (cpn_dsc.is_perceptual)
+ gray_format = babl_format ("Y' double");
+ else
+ gray_format = babl_format ("Y double");
+
+ if (! inputs[i].is_ID)
+ {
+ const Babl *fish = babl_fish (babl_format ("Y' u8"), gray_format);
+
+ babl_process (fish, &inputs[i].comp.val, &mask_vals[i], 1);
+
+ mask_vals[i] = mask_vals[i] * (cpn_dsc.range_max - cpn_dsc.range_min) + cpn_dsc.range_min;
+ }
+ else
+ {
+ extent = gegl_buffer_get_extent (buffer_src[i]);
+
+ temp[i] = gegl_buffer_new (extent, gray_format);
+
+ gegl_buffer_copy (buffer_src[i], NULL, temp[i], NULL);
+
+ if (cpn_dsc.range_min != 0.0 || cpn_dsc.range_max != 1.0)
+ cpn_affine_transform (temp[i], cpn_dsc.range_min, cpn_dsc.range_max);
+
+ }
+
+ gimp_progress_update ((gdouble) i / (gdouble) (num_images + 1.0));
+ }
+
+ dst_format = babl_format_new (babl_model (curr_compose_dsc.babl_model),
+ babl_type ("double"),
+ babl_component (components[0].babl_name),
+ num_images > 1 ? babl_component (components[1].babl_name) : NULL,
+ num_images > 2 ? babl_component (components[2].babl_name) : NULL,
+ num_images > 3 ? babl_component (components[3].babl_name) : NULL,
+ NULL);
+
+ /* extent is not NULL because there is at least one drawable */
+ dst_temp = gegl_buffer_new (extent, dst_format);
+
+ /* Gather all individual components in the dst_format buffer */
+ fill_buffer_from_components (temp, dst_temp, num_images, inputs, mask_vals);
+
+ gimp_progress_update ((gdouble) num_images / (gdouble) (num_images + 1.0));
+
+ /* Copy back to the format GIMP wants (and perform the conversion in itself) */
+ gegl_buffer_copy (dst_temp, NULL, buffer_dst, NULL);
+
+ for (i = 0; i< num_images; i++)
+ if( inputs[i].is_ID)
+ g_object_unref (temp[i]);
+
+ g_object_unref (dst_temp);
+}
/* Compose an image from several gray-images */
static gint32
@@ -654,18 +794,15 @@ compose (const gchar *compose_type,
ComposeInput *inputs,
gboolean compose_by_drawable)
{
- gint width, height, tile_height, scan_lines;
- gint num_images, compose_idx, incr_src[MAX_COMPOSE_IMAGES];
+ gint width, height;
+ gint num_images, compose_idx;
gint i, j;
gint num_layers;
gint32 layer_ID_dst, image_ID_dst;
- guchar *src[MAX_COMPOSE_IMAGES];
- guchar *dst;
gint first_ID;
GimpImageType gdtype_dst;
- GimpDrawable *drawable_src[MAX_COMPOSE_IMAGES], *drawable_dst;
- GimpPixelRgn pixel_rgn_src[MAX_COMPOSE_IMAGES], pixel_rgn_dst;
- GimpPixelRgn pixel_rgn_dst_read;
+ GeglBuffer *buffer_src[MAX_COMPOSE_IMAGES], *buffer_dst;
+ GimpPrecision precision;
/* Search type of composing */
compose_idx = -1;
@@ -698,11 +835,11 @@ compose (const gchar *compose_type,
return -1;
}
- tile_height = gimp_tile_height ();
-
/* Check image sizes */
if (compose_by_drawable)
{
+ gint32 first_image = gimp_item_get_image (inputs[first_ID].comp.ID);
+
if (! gimp_item_is_valid (inputs[first_ID].comp.ID))
{
g_message (_("Specified layer %d not found"),
@@ -712,6 +849,7 @@ compose (const gchar *compose_type,
width = gimp_drawable_width (inputs[first_ID].comp.ID);
height = gimp_drawable_height (inputs[first_ID].comp.ID);
+ precision = gimp_image_get_precision (first_image);
for (j = first_ID + 1; j < num_images; j++)
{
@@ -735,15 +873,16 @@ compose (const gchar *compose_type,
for (j = 0; j < num_images; j++)
{
if (inputs[j].is_ID)
- drawable_src[j] = gimp_drawable_get (inputs[j].comp.ID);
+ buffer_src[j] = gimp_drawable_get_buffer (inputs[j].comp.ID);
else
- drawable_src[j] = NULL;
+ buffer_src[j] = NULL;
}
}
else /* Compose by image ID */
{
width = gimp_image_width (inputs[first_ID].comp.ID);
height = gimp_image_height (inputs[first_ID].comp.ID);
+ precision = gimp_image_get_precision (inputs[first_ID].comp.ID);
for (j = first_ID + 1; j < num_images; j++)
{
@@ -775,45 +914,12 @@ compose (const gchar *compose_type,
}
/* Get drawable for layer */
- drawable_src[j] = gimp_drawable_get (layers[0]);
+ buffer_src[j] = gimp_drawable_get_buffer (layers[0]);
g_free (layers);
}
}
}
- /* Get pixel region for all input drawables */
- for (j = 0; j < num_images; j++)
- {
- gsize s;
-
- /* Check bytes per pixel */
- if (inputs[j].is_ID)
- {
- incr_src[j] = drawable_src[j]->bpp;
-
- if ((incr_src[j] != 1) && (incr_src[j] != 2))
- {
- g_message (_("Image is not a gray image (bpp=%d)"),
- incr_src[j]);
- return -1;
- }
-
- /* Get pixel region */
- gimp_pixel_rgn_init (&pixel_rgn_src[j], drawable_src[j], 0, 0,
- width, height, FALSE, FALSE);
- }
- else
- {
- incr_src[j] = 1;
- }
-
- /* Get memory for retrieving information */
- s = tile_height * width * incr_src[j];
- src[j] = g_new (guchar, s);
- if (! inputs[j].is_ID)
- memset (src[j], inputs[j].comp.val, s);
- }
-
/* Unless recomposing, create new image */
if (composevals.do_recompose)
{
@@ -825,24 +931,18 @@ compose (const gchar *compose_type,
return -1;
}
- drawable_dst = gimp_drawable_get (layer_ID_dst);
- gimp_pixel_rgn_init (&pixel_rgn_dst, drawable_dst,
- 0, 0, drawable_dst->width, drawable_dst->height,
- TRUE, TRUE);
- gimp_pixel_rgn_init (&pixel_rgn_dst_read, drawable_dst,
- 0, 0, drawable_dst->width, drawable_dst->height,
- FALSE, FALSE);
image_ID_dst = gimp_item_get_image (layer_ID_dst);
+
+ buffer_dst = gimp_drawable_get_shadow_buffer (layer_ID_dst);
}
else
{
- gdtype_dst = ((compose_dsc[compose_idx].compose_fun == compose_rgba) ?
+ gdtype_dst = ((babl_model (compose_dsc[compose_idx].babl_model) == babl_model ("RGBA")) ?
GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE);
image_ID_dst = create_new_image (compose_dsc[compose_idx].filename,
- width, height, gdtype_dst,
- &layer_ID_dst, &drawable_dst,
- &pixel_rgn_dst);
+ width, height, gdtype_dst, precision,
+ &layer_ID_dst, &buffer_dst);
}
if (! compose_by_drawable)
@@ -853,49 +953,21 @@ compose (const gchar *compose_type,
gimp_image_set_resolution (image_ID_dst, xres, yres);
}
- dst = g_new (guchar, tile_height * width * drawable_dst->bpp);
-
- /* Do the composition */
- i = 0;
- while (i < height)
- {
- scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i);
-
- /* Get source pixel regions */
- for (j = 0; j < num_images; j++)
- if (inputs[j].is_ID)
- gimp_pixel_rgn_get_rect (&(pixel_rgn_src[j]), src[j], 0, i,
- width, scan_lines);
-
- if (composevals.do_recompose)
- gimp_pixel_rgn_get_rect (&pixel_rgn_dst_read, dst, 0, i,
- width, scan_lines);
-
- /* Do the composition */
- compose_dsc[compose_idx].compose_fun (src,
- incr_src,
- width * tile_height,
- dst,
- gimp_drawable_has_alpha (layer_ID_dst));
+ perform_composition (compose_dsc[compose_idx],
+ buffer_src,
+ buffer_dst,
+ inputs,
+ num_images);
- /* Set destination pixel region */
- gimp_pixel_rgn_set_rect (&pixel_rgn_dst, dst, 0, i, width, scan_lines);
-
- i += scan_lines;
-
- gimp_progress_update ((gdouble) i / (gdouble) height);
- }
gimp_progress_update (1.0);
for (j = 0; j < num_images; j++)
{
- g_free (src[j]);
if (inputs[j].is_ID)
- gimp_drawable_detach (drawable_src[j]);
+ g_object_unref (buffer_src[j]);
}
- g_free (dst);
- gimp_drawable_detach (drawable_dst);
+ g_object_unref (buffer_dst);
if (composevals.do_recompose)
gimp_drawable_merge_shadow (layer_ID_dst, TRUE);
@@ -914,9 +986,9 @@ create_new_image (const gchar *filename,
guint width,
guint height,
GimpImageType gdtype,
+ GimpPrecision precision,
gint32 *layer_ID,
- GimpDrawable **drawable,
- GimpPixelRgn *pixel_rgn)
+ GeglBuffer **buffer)
{
gint32 image_ID;
GimpImageBaseType gitype;
@@ -928,7 +1000,7 @@ create_new_image (const gchar *filename,
else
gitype = GIMP_RGB;
- image_ID = gimp_image_new (width, height, gitype);
+ image_ID = gimp_image_new_with_precision (width, height, gitype, precision);
gimp_image_undo_disable (image_ID);
gimp_image_set_filename (image_ID, filename);
@@ -937,510 +1009,11 @@ create_new_image (const gchar *filename,
gdtype, 100, GIMP_NORMAL_MODE);
gimp_image_insert_layer (image_ID, *layer_ID, -1, 0);
- *drawable = gimp_drawable_get (*layer_ID);
- gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
- (*drawable)->height, TRUE, FALSE);
+ *buffer = gimp_drawable_get_buffer (*layer_ID);
return image_ID;
}
-static void
-compose_rgb (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *red_src = src[0];
- register const guchar *green_src = src[1];
- register const guchar *blue_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint red_incr = incr_src[0];
- gint green_incr = incr_src[1];
- gint blue_incr = incr_src[2];
-
- if ((red_incr == 1) && (green_incr == 1) && (blue_incr == 1))
- {
- while (count-- > 0)
- {
- *(rgb_dst++) = *(red_src++);
- *(rgb_dst++) = *(green_src++);
- *(rgb_dst++) = *(blue_src++);
- if (dst_has_alpha)
- rgb_dst++;
- }
- }
- else
- {
- while (count-- > 0)
- {
- *(rgb_dst++) = *red_src; red_src += red_incr;
- *(rgb_dst++) = *green_src; green_src += green_incr;
- *(rgb_dst++) = *blue_src; blue_src += blue_incr;
- if (dst_has_alpha)
- rgb_dst++;
- }
- }
-}
-
-
-static void
-compose_rgba (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *red_src = src[0];
- register const guchar *green_src = src[1];
- register const guchar *blue_src = src[2];
- register const guchar *alpha_src = src[3];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint red_incr = incr_src[0];
- gint green_incr = incr_src[1];
- gint blue_incr = incr_src[2];
- gint alpha_incr = incr_src[3];
-
- if ((red_incr == 1) && (green_incr == 1) && (blue_incr == 1) &&
- (alpha_incr == 1))
- {
- while (count-- > 0)
- {
- *(rgb_dst++) = *(red_src++);
- *(rgb_dst++) = *(green_src++);
- *(rgb_dst++) = *(blue_src++);
- *(rgb_dst++) = *(alpha_src++);
- }
- }
- else
- {
- while (count-- > 0)
- {
- *(rgb_dst++) = *red_src; red_src += red_incr;
- *(rgb_dst++) = *green_src; green_src += green_incr;
- *(rgb_dst++) = *blue_src; blue_src += blue_incr;
- *(rgb_dst++) = *alpha_src; alpha_src += alpha_incr;
- }
- }
-}
-
-
-static void
-compose_hsv (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *hue_src = src[0];
- register const guchar *sat_src = src[1];
- register const guchar *val_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint hue_incr = incr_src[0];
- gint sat_incr = incr_src[1];
- gint val_incr = incr_src[2];
-
- while (count-- > 0)
- {
- gimp_hsv_to_rgb4 (rgb_dst, (gdouble) *hue_src / 255.0,
- (gdouble) *sat_src / 255.0,
- (gdouble) *val_src / 255.0);
- rgb_dst += 3;
- hue_src += hue_incr;
- sat_src += sat_incr;
- val_src += val_incr;
-
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-
-static void
-compose_hsl (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *hue_src = src[0];
- register const guchar *sat_src = src[1];
- register const guchar *lum_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint hue_incr = incr_src[0];
- gint sat_incr = incr_src[1];
- gint lum_incr = incr_src[2];
- GimpHSL hsl;
- GimpRGB rgb;
-
- while (count-- > 0)
- {
- hsl.h = (gdouble) *hue_src / 255.0;
- hsl.s = (gdouble) *sat_src / 255.0;
- hsl.l = (gdouble) *lum_src / 255.0;
-
- gimp_hsl_to_rgb (&hsl, &rgb);
- gimp_rgb_get_uchar (&rgb, &(rgb_dst[0]), &(rgb_dst[1]), &(rgb_dst[2]));
-
- rgb_dst += 3;
- hue_src += hue_incr;
- sat_src += sat_incr;
- lum_src += lum_incr;
-
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-
-static void
-compose_cmy (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *cyan_src = src[0];
- register const guchar *magenta_src = src[1];
- register const guchar *yellow_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint cyan_incr = incr_src[0];
- gint magenta_incr = incr_src[1];
- gint yellow_incr = incr_src[2];
-
- if ((cyan_incr == 1) && (magenta_incr == 1) && (yellow_incr == 1))
- {
- while (count-- > 0)
- {
- *(rgb_dst++) = 255 - *(cyan_src++);
- *(rgb_dst++) = 255 - *(magenta_src++);
- *(rgb_dst++) = 255 - *(yellow_src++);
- if (dst_has_alpha)
- rgb_dst++;
- }
- }
- else
- {
- while (count-- > 0)
- {
- *(rgb_dst++) = 255 - *cyan_src;
- *(rgb_dst++) = 255 - *magenta_src;
- *(rgb_dst++) = 255 - *yellow_src;
- cyan_src += cyan_incr;
- magenta_src += magenta_incr;
- yellow_src += yellow_incr;
- if (dst_has_alpha)
- rgb_dst++;
- }
- }
-}
-
-
-static void
-compose_cmyk (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *cyan_src = src[0];
- register const guchar *magenta_src = src[1];
- register const guchar *yellow_src = src[2];
- register const guchar *black_src = src[3];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint cyan_incr = incr_src[0];
- gint magenta_incr = incr_src[1];
- gint yellow_incr = incr_src[2];
- gint black_incr = incr_src[3];
- GimpRGB grgb;
-
- gimp_rgb_set(&grgb, 0, 0, 0);
-
- while (count-- > 0)
- {
- GimpCMYK gcmyk;
- guchar r, g, b;
-
- gimp_cmyk_set_uchar (&gcmyk,
- *cyan_src, *magenta_src, *yellow_src,
- *black_src);
- gimp_cmyk_to_rgb (&gcmyk, &grgb);
- gimp_rgb_get_uchar (&grgb, &r, &g, &b);
-
- *rgb_dst++ = r;
- *rgb_dst++ = g;
- *rgb_dst++ = b;
-
- cyan_src += cyan_incr;
- magenta_src += magenta_incr;
- yellow_src += yellow_incr;
- black_src += black_incr;
-
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-static void
-compose_lab (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register guchar *l_src = src[0];
- register guchar *a_src = src[1];
- register guchar *b_src = src[2];
- register guchar *rgb_dst = dst;
-
- register gint count = numpix;
- gint l_incr = incr_src[0], a_incr = incr_src[1], b_incr = incr_src[2];
-
- gdouble red, green, blue;
- gdouble x, y, z;
- gdouble l, a, b;
-
- gdouble p, yyn;
- gdouble ha, hb, sqyyn;
-
- while (count-- > 0)
- {
- l = *l_src / 2.550;
- a = ( *a_src - 128.0 ) / 1.27;
- b = ( *b_src - 128.0 ) / 1.27;
-
- p = (l + 16.) / 116.;
- yyn = p*p*p;
-
- if (yyn > 0.008856)
- {
- y = Yn * yyn;
- ha = (p + a/500.);
- x = Xn * ha*ha*ha;
- hb = (p - b/200.);
- z = Zn * hb*hb*hb;
- }
- else
- {
- y = Yn * l/903.3;
- sqyyn = pow(l/903.3,1./3.);
- ha = a/500./7.787 + sqyyn;
- x = Xn * ha*ha*ha;
- hb = sqyyn - b/200./7.787;
- z = Zn * hb*hb*hb;
- };
-
- red = 3.063 * x - 1.393 * y - 0.476 * z;
- green = -0.969 * x + 1.876 * y + 0.042 * z;
- blue = 0.068 * x - 0.229 * y + 1.069 * z;
-
- red = ( red > 0 ) ? red : 0;
- green = ( green > 0 ) ? green : 0;
- blue = ( blue > 0 ) ? blue : 0;
-
- red = ( red < 1.0 ) ? red : 1.0;
- green = ( green < 1.0 ) ? green : 1.0;
- blue = ( blue < 1.0 ) ? blue : 1.0;
-
- rgb_dst[0] = (guchar) ( red * 255.999 );
- rgb_dst[1] = (guchar) ( green * 255.999 );
- rgb_dst[2] = (guchar) ( blue * 255.999 );
-
- rgb_dst += 3;
- l_src += l_incr;
- a_src += a_incr;
- b_src += b_incr;
-
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-
-/* these are here so the code is more readable and we can use
- the standart values instead of some scaled and rounded fixpoint values */
-#define FIX(a) ((int)((a)*256.0*256.0 + 0.5))
-#define FIXY(a) ((int)((a)*256.0*256.0*255.0/219.0 + 0.5))
-#define FIXC(a) ((int)((a)*256.0*256.0*255.0/224.0 + 0.5))
-
-
-static void
-compose_ycbcr470 (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *y_src = src[0];
- register const guchar *cb_src = src[1];
- register const guchar *cr_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint y_incr = incr_src[0];
- gint cb_incr = incr_src[1];
- gint cr_incr = incr_src[2];
-
- while (count-- > 0)
- {
- int r,g,b,y,cb,cr;
- y = *y_src - 16;
- cb= *cb_src - 128;
- cr= *cr_src - 128;
- y_src += y_incr;
- cb_src += cb_incr;
- cr_src += cr_incr;
-
- r = (FIXY(1.0)*y + FIXC(1.4022)*cr + FIX(0.5))>>16;
- g = (FIXY(1.0)*y - FIXC(0.3456)*cb - FIXC(0.7145)*cr + FIX(0.5))>>16;
- b = (FIXY(1.0)*y + FIXC(1.7710)*cb + FIX(0.5))>>16;
-
- if(((unsigned)r) > 255) r = ((r>>10)&255)^255;
- if(((unsigned)g) > 255) g = ((g>>10)&255)^255;
- if(((unsigned)b) > 255) b = ((b>>10)&255)^255;
-
- *(rgb_dst++) = r;
- *(rgb_dst++) = g;
- *(rgb_dst++) = b;
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-
-static void
-compose_ycbcr709 (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *y_src = src[0];
- register const guchar *cb_src = src[1];
- register const guchar *cr_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint y_incr = incr_src[0];
- gint cb_incr = incr_src[1];
- gint cr_incr = incr_src[2];
-
- while (count-- > 0)
- {
- int r,g,b,y,cb,cr;
- y = *y_src - 16;
- cb= *cb_src - 128;
- cr= *cr_src - 128;
- y_src += y_incr;
- cb_src += cb_incr;
- cr_src += cr_incr;
-
- r = (FIXY(1.0)*y + FIXC(1.5748)*cr + FIX(0.5))>>16;
- g = (FIXY(1.0)*y - FIXC(0.1873)*cb - FIXC(0.4681)*cr + FIX(0.5))>>16;
- b = (FIXY(1.0)*y + FIXC(1.8556)*cb + FIX(0.5))>>16;
-
- if(((unsigned)r) > 255) r = ((r>>10)&255)^255;
- if(((unsigned)g) > 255) g = ((g>>10)&255)^255;
- if(((unsigned)b) > 255) b = ((b>>10)&255)^255;
-
- *(rgb_dst++) = r;
- *(rgb_dst++) = g;
- *(rgb_dst++) = b;
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-
-static void
-compose_ycbcr470f (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *y_src = src[0];
- register const guchar *cb_src = src[1];
- register const guchar *cr_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint y_incr = incr_src[0];
- gint cb_incr = incr_src[1];
- gint cr_incr = incr_src[2];
-
- while (count-- > 0)
- {
- int r,g,b,y,cb,cr;
- y = *y_src;
- cb= *cb_src - 128;
- cr= *cr_src - 128;
- y_src += y_incr;
- cb_src += cb_incr;
- cr_src += cr_incr;
-
- r = (FIX(1.0)*y + FIX(1.4022)*cr + FIX(0.5))>>16;
- g = (FIX(1.0)*y - FIX(0.3456)*cb - FIX(0.7145)*cr + FIX(0.5))>>16;
- b = (FIX(1.0)*y + FIX(1.7710)*cb + FIX(0.5))>>16;
-
- if(((unsigned)r) > 255) r = ((r>>10)&255)^255;
- if(((unsigned)g) > 255) g = ((g>>10)&255)^255;
- if(((unsigned)b) > 255) b = ((b>>10)&255)^255;
-
- *(rgb_dst++) = r;
- *(rgb_dst++) = g;
- *(rgb_dst++) = b;
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
-
-static void
-compose_ycbcr709f (guchar **src,
- gint *incr_src,
- gint numpix,
- guchar *dst,
- gboolean dst_has_alpha)
-{
- register const guchar *y_src = src[0];
- register const guchar *cb_src = src[1];
- register const guchar *cr_src = src[2];
- register guchar *rgb_dst = dst;
- register gint count = numpix;
- gint y_incr = incr_src[0];
- gint cb_incr = incr_src[1];
- gint cr_incr = incr_src[2];
-
- while (count-- > 0)
- {
- int r,g,b,y,cb,cr;
- y = *y_src;
- cb= *cb_src - 128;
- cr= *cr_src - 128;
- y_src += y_incr;
- cb_src += cb_incr;
- cr_src += cr_incr;
-
- r = (FIX(1.0)*y + FIX(1.5748)*cr + FIX(0.5))>>16;
- g = (FIX(1.0)*y - FIX(0.1873)*cb - FIX(0.4681)*cr + FIX(0.5))>>16;
- b = (FIX(1.0)*y + FIX(1.8556)*cb + FIX(0.5))>>16;
-
- if(((unsigned)r) > 255) r = ((r>>10)&255)^255;
- if(((unsigned)g) > 255) g = ((g>>10)&255)^255;
- if(((unsigned)b) > 255) b = ((b>>10)&255)^255;
-
- *(rgb_dst++) = r;
- *(rgb_dst++) = g;
- *(rgb_dst++) = b;
- if (dst_has_alpha)
- rgb_dst++;
- }
-}
-
static gboolean
compose_dialog (const gchar *compose_type,
@@ -1794,8 +1367,8 @@ type_combo_callback (GimpIntComboBox *combo,
{
GtkWidget *label = composeint.channel_label[j];
GtkWidget *image = composeint.channel_icon[j];
- const gchar *text = compose_dsc[compose_idx].channel_name[j];
- const gchar *icon = compose_dsc[compose_idx].channel_icon[j];
+ const gchar *text = compose_dsc[compose_idx].components[j].name;
+ const gchar *icon = compose_dsc[compose_idx].components[j].icon;
gtk_label_set_text_with_mnemonic (GTK_LABEL (label),
text ? gettext (text) : "");
@@ -1814,7 +1387,7 @@ type_combo_callback (GimpIntComboBox *combo,
}
/* Set sensitivity of last menu */
- combo4 = (compose_dsc[compose_idx].channel_name[3] != NULL);
+ combo4 = (compose_dsc[compose_idx].num_images == 4);
gtk_widget_set_sensitive (composeint.channel_menu[3], combo4);
scale4 = combo4 && !composeint.selected[3].is_ID;
diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl
index a1cd75a..7a9229a 100644
--- a/plug-ins/common/plugin-defs.pl
+++ b/plug-ins/common/plugin-defs.pl
@@ -20,7 +20,7 @@
'color-exchange' => { ui => 1 },
'colorify' => { ui => 1 },
'colormap-remap' => { ui => 1 },
- 'compose' => { ui => 1 },
+ 'compose' => { ui => 1, gegl => 1 },
'contrast-normalize' => {},
'contrast-retinex' => { ui => 1 },
'contrast-stretch' => {},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]