[gimp] plugins: port decompose to GEGL
- From: Téo Mazars <teom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plugins: port decompose to GEGL
- Date: Sun, 9 Jun 2013 21:23:15 +0000 (UTC)
commit cd7f4e61a88693ca69f1dd1ce3f547ae41d529af
Author: Martijn van Beers <mail_dev martijn at>
Date: Sun Jun 9 23:19:47 2013 +0200
plugins: port decompose to GEGL
Only RGB(A) decompositions are availables right now, others
decompositions need more thinking.
plug-ins/common/decompose.c | 1276 +++++++++----------------------------------
1 files changed, 266 insertions(+), 1010 deletions(-)
---
diff --git a/plug-ins/common/decompose.c b/plug-ins/common/decompose.c
index de1cd34..f67412f 100644
--- a/plug-ins/common/decompose.c
+++ b/plug-ins/common/decompose.c
@@ -36,12 +36,6 @@
#include "libgimp/stdplugins-intl.h"
-/* cbrt() is a GNU extension, which C99 accepted */
-#if !defined (__GLIBC__) && !(defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
-#define cbrt(x) (pow(x, 1.0/3.0))
-#endif
-
-
#define PLUG_IN_PROC "plug-in-decompose"
#define PLUG_IN_PROC_REG "plug-in-decompose-registered"
#define PLUG_IN_BINARY "decompose"
@@ -50,199 +44,102 @@
/* 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 decompose (gint32 image_id,
- gint32 drawable_ID,
- const gchar *extract_type,
- gint32 *image_ID_dst,
- gint32 *num_layers,
- gint32 *layer_ID_dst);
-static gint32 create_new_image (const gchar *filename,
- const gchar *layername,
- guint width,
- guint height,
- GimpImageBaseType type,
- gdouble xres,
- gdouble yres,
- gint32 *layer_ID,
- GimpDrawable **drawable,
- GimpPixelRgn *pixel_rgn);
-static gint32 create_new_layer (gint32 image_ID,
- gint position,
- const gchar *layername,
- guint width,
- guint height,
- GimpImageBaseType type,
- GimpDrawable **drawable,
- GimpPixelRgn *pixel_rgn);
-
-static void transfer_registration_color (const guchar *src,
- gint bpp, gint numpix, guchar **dst,
- gint num_channels);
-
-static void extract_rgb (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_red (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_green (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_blue (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_rgba (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_alpha (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_hsv (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_hsl (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_hue (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_sat (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_val (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_huel (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_satl (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_lightness (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_cmy (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_cyan (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_magenta (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_yellow (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_cmyk (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_cyank (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_magentak (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_yellowk (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_lab (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_ycbcr470 (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_ycbcr709 (const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_ycbcr470f(const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-static void extract_ycbcr709f(const guchar *src,
- gint bpp, gint numpix, guchar **dst);
-
-static gboolean decompose_dialog (void);
+static void query (void);
+static void run (const gchar *name,
+ gint nparams,
+ const GimpParam *param,
+ gint *nreturn_vals,
+ GimpParam **return_vals);
+static gint32 decompose (gint32 image_id,
+ gint32 drawable_ID,
+ const gchar *extract_type,
+ gint32 *image_ID_dst,
+ gint32 *num_layers,
+ gint32 *layer_ID_dst);
+static gint32 create_new_image (const gchar *filename,
+ const gchar *layername,
+ guint width,
+ guint height,
+ GimpImageBaseType type,
+ GimpPrecision precision,
+ gdouble xres,
+ gdouble yres,
+ gint32 *layer_ID);
+static gint32 create_new_layer (gint32 image_ID,
+ gint position,
+ const gchar *layername,
+ guint width,
+ guint height,
+ GimpImageBaseType type);
+static void transfer_registration_color (GeglBuffer *src,
+ GeglBuffer **dst,
+ gint count);
+static void copy_n_components (GeglBuffer *src,
+ GeglBuffer **dst,
+ const gchar *model,
+ guint n,
+ const gchar **components);
+static void copy_one_component (GeglBuffer *src,
+ GeglBuffer *dst,
+ const char *model,
+ const char *component);
+static gboolean decompose_dialog (void);
+static gchar * generate_filename (guint32 image_ID,
+ guint colorspace,
+ guint channel);
/* Maximum number of images/layers generated by an extraction */
#define MAX_EXTRACT_IMAGES 4
/* Description of an extraction */
+
typedef struct
{
const gchar *type; /* What to extract */
+ const gchar *model ; /* the babl_model string to use */
gboolean dialog; /* Dialog-Flag. Set it to TRUE if you want to appear
* this extract function within the dialog */
gint num_images; /* Number of images to create */
+ /* the babl_component names of the channels */
+ const gchar *component[MAX_EXTRACT_IMAGES];
+
/* Names of channels to extract */
const gchar *channel_name[MAX_EXTRACT_IMAGES];
- /* Function that performs the extraction */
- void (* extract_fun) (const guchar *src,
- int bpp,
- gint numpix,
- guchar **dst);
} EXTRACT;
+/* FIXME: lots of missing conversions here */
static EXTRACT extract[] =
-{
- { N_("RGB"), TRUE, 3, { N_("red"),
- N_("green"),
- N_("blue") }, extract_rgb },
-
- { N_("Red"), FALSE, 1, { N_("red") }, extract_red },
- { N_("Green"), FALSE, 1, { N_("green") }, extract_green },
- { N_("Blue"), FALSE, 1, { N_("blue") }, extract_blue },
-
- { N_("RGBA"), TRUE, 4, { N_("red"),
- N_("green"),
- N_("blue"),
- N_("alpha") }, extract_rgba },
-
-
- { N_("HSV"), TRUE, 3, { N_("hue"),
- N_("saturation"),
- N_("value") }, extract_hsv },
-
- { N_("Hue"), FALSE, 1, { N_("hue") }, extract_hue },
- { N_("Saturation"), FALSE, 1, { N_("saturation") }, extract_sat },
- { N_("Value"), FALSE, 1, { N_("value") }, extract_val },
-
-
- { N_("HSL"), TRUE, 3, { N_("hue_l"),
- N_("saturation_l"),
- N_("lightness") }, extract_hsl },
-
- { N_("Hue (HSL)"), FALSE, 1, { N_("hue_l") }, extract_huel },
- { N_("Saturation (HSL)"), FALSE, 1, { N_("saturation_l") }, extract_satl },
- { N_("Lightness"), FALSE, 1, { N_("lightness")}, extract_lightness },
-
-
- { N_("CMY"), TRUE, 3, { N_("cyan"),
- N_("magenta"),
- N_("yellow") }, extract_cmy },
-
- { N_("Cyan"), FALSE, 1, { N_("cyan") }, extract_cyan },
- { N_("Magenta"), FALSE, 1, { N_("magenta") }, extract_magenta },
- { N_("Yellow"), FALSE, 1, { N_("yellow") }, extract_yellow },
-
-
- { N_("CMYK"), TRUE, 4, { N_("cyan-k"),
- N_("magenta-k"),
- N_("yellow-k"),
- N_("black") }, extract_cmyk },
-
- { N_("Cyan_K"), FALSE, 1, { N_("cyan-k") }, extract_cyank },
- { N_("Magenta_K"), FALSE, 1, { N_("magenta-k") }, extract_magentak },
- { N_("Yellow_K"), FALSE, 1, { N_("yellow-k") }, extract_yellowk },
-
-
- { N_("Alpha"), TRUE, 1, { N_("alpha") }, extract_alpha },
-
-
- { N_("LAB"), TRUE, 3, { "L",
- "A",
- "B" }, extract_lab },
-
-
- { "YCbCr_ITU_R470", TRUE, 3, { N_("luma-y470"),
- N_("blueness-cb470"),
- N_("redness-cr470") }, extract_ycbcr470 },
-
- { "YCbCr_ITU_R709", TRUE, 3, { N_("luma-y709"),
- N_("blueness-cb709"),
- N_("redness-cr709") }, extract_ycbcr709 },
-
- { "YCbCr ITU R470 256", TRUE, 3, { N_("luma-y470f"),
- N_("blueness-cb470f"),
- N_("redness-cr470f") }, extract_ycbcr470f },
-
- { "YCbCr ITU R709 256", TRUE, 3, { N_("luma-y709f"),
- N_("blueness-cb709f"),
- N_("redness-cr709f") }, extract_ycbcr709f }
-};
-
+ {
+ { N_("RGB"), "RGB", TRUE, 3, {"R", "G", "B"}, { N_("red"),
+ N_("green"),
+ N_("blue") } },
+
+ { N_("Red"), "RGB", FALSE, 1, { "R" }, { N_("red") } },
+ { N_("Green"), "RGB", FALSE, 1, { "G" }, { N_("green") } },
+ { N_("Blue"), "RGB", FALSE, 1, { "B" }, { N_("blue") } },
+ { N_("Alpha"), "RGBA", TRUE , 1, { "A" }, { N_("alpha") } },
+
+ { N_("RGBA"), "RGBA", TRUE, 4, { "R", "G", "B", "A" }, { N_("red"),
+ N_("green"),
+ N_("blue"),
+ N_("alpha") } },
+
+ { N_("LAB"), "CIE Lab", FALSE, 3, {"CIE L", "CIE a", "CIE b"}, { N_("L"),
+ N_("A"),
+ N_("B") } },
+
+ { N_("CMYK"), "CMYK", FALSE, 4, {"cyan", "magenta", "yellow", "key"}, { N_("cyan-k"),
+ N_("magenta-k"),
+ N_("yellow-k"),
+ N_("black") } },
+
+ { N_("HSVA"), "HSVA", FALSE, 4, {"hue", "saturation", "value", "alpha"}, { N_("hue"),
+ N_("saturation"),
+ N_("value")} }
+ };
typedef struct
{
@@ -363,12 +260,13 @@ run (const gchar *name,
gint32 image_ID;
INIT_I18N ();
+ gegl_init (NULL, NULL);
run_mode = param[0].data.d_int32;
image_ID = param[1].data.d_image;
layer = param[2].data.d_drawable;
- *nreturn_vals = MAX_EXTRACT_IMAGES+1;
+ *nreturn_vals = MAX_EXTRACT_IMAGES + 1;
*return_vals = values;
values[0].type = GIMP_PDB_STATUS;
@@ -401,7 +299,7 @@ run (const gchar *name,
{
strncpy (decovals.extract_type, param[3].data.d_string,
sizeof (decovals.extract_type));
- decovals.extract_type[sizeof (decovals.extract_type)-1] = '\0';
+ decovals.extract_type[sizeof (decovals.extract_type) - 1] = '\0';
decovals.as_layers = nparams > 4 ? param[4].data.d_int32 : FALSE;
decovals.use_registration = (strcmp (name, PLUG_IN_PROC_REG) == 0);
@@ -417,13 +315,6 @@ run (const gchar *name,
break;
}
- /* Make sure that the drawable is RGB color */
- if (gimp_drawable_type_with_alpha (layer) != GIMP_RGBA_IMAGE)
- {
- g_message ("Can only work on RGB images.");
- status = GIMP_PDB_CALLING_ERROR;
- }
-
if (status == GIMP_PDB_SUCCESS)
{
gimp_progress_init (_("Decomposing"));
@@ -480,9 +371,9 @@ run (const gchar *name,
/* Decompose an image. It returns the number of new (gray) images.
- The image IDs for the new images are returned in image_ID_dst.
- On failure, -1 is returned.
-*/
+ * The image IDs for the new images are returned in image_ID_dst.
+ * On failure, -1 is returned.
+ */
static gint32
decompose (gint32 image_ID,
gint32 drawable_ID,
@@ -491,16 +382,13 @@ decompose (gint32 image_ID,
gint32 *nlayers,
gint32 *layer_ID_dst)
{
- const gchar *layername;
- gint i, j, extract_idx, scan_lines;
- gint height, width, tile_height, num_layers;
- gchar *filename;
- guchar *src;
- guchar *dst[MAX_EXTRACT_IMAGES];
- GimpDrawable *drawable_src;
- GimpDrawable *drawable_dst[MAX_EXTRACT_IMAGES];
- GimpPixelRgn pixel_rgn_src;
- GimpPixelRgn pixel_rgn_dst[MAX_EXTRACT_IMAGES];
+ const gchar *layername;
+ gint j, extract_idx;
+ gint height, width, num_layers;
+ GeglBuffer *src_buffer;
+ GeglBuffer *dst_buffer[MAX_EXTRACT_IMAGES];
+ GimpPrecision precision;
+ gboolean requirments = FALSE, decomp_has_alpha = FALSE;
extract_idx = -1; /* Search extract type */
for (j = 0; j < G_N_ELEMENTS (extract); j++)
@@ -514,82 +402,41 @@ decompose (gint32 image_ID,
if (extract_idx < 0)
return -1;
- /* Check structure of source image */
- drawable_src = gimp_drawable_get (drawable_ID);
- if (drawable_src->bpp < 3)
+ num_layers = extract[extract_idx].num_images;
+
+ /* Sanity checks */
+ src_buffer = gimp_drawable_get_buffer (drawable_ID);
+ precision = gimp_image_get_precision (image_ID);
+
+ for(j = 0; j < num_layers; j++)
{
- g_message ("Not an RGB image.");
- return -1;
+ decomp_has_alpha |= !g_strcmp0 ("alpha", extract[extract_idx].component[j]);
+ decomp_has_alpha |= !g_strcmp0 ("A", extract[extract_idx].component[j]);
}
- if ((extract[extract_idx].extract_fun == extract_alpha ||
- extract[extract_idx].extract_fun == extract_rgba) &&
- (!gimp_drawable_has_alpha (drawable_ID)))
+
+ requirments |= (gimp_drawable_is_rgb (drawable_ID));
+ requirments |= (gimp_drawable_is_indexed (drawable_ID));
+ requirments |= (gimp_drawable_is_gray (drawable_ID)
+ && gimp_drawable_has_alpha (drawable_ID)
+ && (num_layers <= 2)
+ && decomp_has_alpha);
+ requirments &= (!decomp_has_alpha || gimp_drawable_has_alpha (drawable_ID));
+
+ if (!requirments)
{
- g_message ("No alpha channel available.");
+ g_message (_("Image not suitable for this decomposition"));
return -1;
}
- width = drawable_src->width;
- height = drawable_src->height;
-
- tile_height = gimp_tile_height ();
- gimp_pixel_rgn_init (&pixel_rgn_src, drawable_src, 0, 0, width, height,
- FALSE, FALSE);
-
- /* allocate a buffer for retrieving information from the src pixel region */
- src = g_new (guchar, tile_height * width * drawable_src->bpp);
+ width = gegl_buffer_get_width (src_buffer);
+ height = gegl_buffer_get_height (src_buffer);
/* Create all new gray images */
- num_layers = extract[extract_idx].num_images;
- if (num_layers > MAX_EXTRACT_IMAGES)
- num_layers = MAX_EXTRACT_IMAGES;
-
for (j = 0; j < num_layers; j++)
{
- /* Build a filename like <imagename>-<channel>.<extension> */
- gchar *fname;
- gchar *extension;
+ gchar *filename;
gdouble xres, yres;
-
- fname = gimp_image_get_filename (image_ID);
-
- if (fname)
- {
- extension = fname + strlen (fname) - 1;
-
- while (extension >= fname)
- {
- if (*extension == '.') break;
- extension--;
- }
- if (extension >= fname)
- {
- *(extension++) = '\0';
-
- if (decovals.as_layers)
- filename = g_strdup_printf ("%s-%s.%s", fname,
- gettext (extract[extract_idx].type),
- extension);
- else
- filename = g_strdup_printf ("%s-%s.%s", fname,
- gettext (extract[extract_idx].channel_name[j]),
- extension);
- }
- else
- {
- if (decovals.as_layers)
- filename = g_strdup_printf ("%s-%s", fname,
- gettext (extract[extract_idx].type));
- else
- filename = g_strdup_printf ("%s-%s", fname,
- gettext (extract[extract_idx].channel_name[j]));
- }
- }
- else
- {
- filename = g_strdup (gettext (extract[extract_idx].channel_name[j]));
- }
-
+ filename = generate_filename (image_ID, extract_idx, j);
gimp_image_get_resolution (image_ID, &xres, &yres);
if (decovals.as_layers)
@@ -598,72 +445,43 @@ decompose (gint32 image_ID,
if (j == 0)
image_ID_dst[j] = create_new_image (filename, layername,
- width, height, GIMP_GRAY,
+ width, height, GIMP_GRAY, precision,
xres, yres,
- layer_ID_dst + j,
- drawable_dst + j,
- pixel_rgn_dst + j);
+ layer_ID_dst + j);
else
layer_ID_dst[j] = create_new_layer (image_ID_dst[0], j, layername,
- width, height, GIMP_GRAY,
- drawable_dst + j,
- pixel_rgn_dst + j);
+ width, height, GIMP_GRAY);
}
else
{
image_ID_dst[j] = create_new_image (filename, NULL,
- width, height, GIMP_GRAY,
+ width, height, GIMP_GRAY, precision,
xres, yres,
- layer_ID_dst + j,
- drawable_dst + j,
- pixel_rgn_dst + j);
+ layer_ID_dst + j);
}
g_free (filename);
- g_free (fname);
- dst[j] = g_new (guchar, tile_height * width);
- }
- i = 0;
- while (i < height)
- {
- /* Get source pixel region */
- scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i);
- gimp_pixel_rgn_get_rect (&pixel_rgn_src, src, 0, i, width, scan_lines);
-
- /* Extract the channel information */
- extract[extract_idx].extract_fun (src, drawable_src->bpp, scan_lines*width,
- dst);
-
- /* Transfer the registration color */
- if (decovals.use_registration)
- transfer_registration_color (src, drawable_src->bpp, scan_lines*width,
- dst, extract[extract_idx].num_images);
-
- /* Set destination pixel regions */
- for (j = 0; j < num_layers; j++)
- gimp_pixel_rgn_set_rect (&(pixel_rgn_dst[j]), dst[j], 0, i, width,
- scan_lines);
- i += scan_lines;
-
- gimp_progress_update ((gdouble) i / (gdouble) height);
+ dst_buffer[j] = gimp_drawable_get_buffer (layer_ID_dst[j]);
}
+
+ copy_n_components (src_buffer, dst_buffer,
+ extract[extract_idx].model,
+ extract[extract_idx].num_images,
+ extract[extract_idx].component);
+
+ if (decovals.use_registration)
+ transfer_registration_color (src_buffer, dst_buffer, num_layers);
+
gimp_progress_update (1.0);
- g_free (src);
+ g_object_unref (src_buffer);
for (j = 0; j < num_layers; j++)
{
- gimp_drawable_detach (drawable_dst[j]);
- gimp_drawable_update (layer_ID_dst[j], 0, 0,
- gimp_drawable_width (layer_ID_dst[j]),
- gimp_drawable_height (layer_ID_dst[j]));
- gimp_layer_add_alpha (layer_ID_dst[j]);
- g_free (dst[j]);
+ g_object_unref (dst_buffer[j]);
}
- gimp_drawable_detach (drawable_src);
-
*nlayers = num_layers;
return (decovals.as_layers ? 1 : num_layers);
@@ -677,23 +495,21 @@ create_new_image (const gchar *filename,
guint width,
guint height,
GimpImageBaseType type,
+ GimpPrecision precision,
gdouble xres,
gdouble yres,
- gint32 *layer_ID,
- GimpDrawable **drawable,
- GimpPixelRgn *pixel_rgn)
+ gint32 *layer_ID)
{
gint32 image_ID;
- image_ID = gimp_image_new (width, height, type);
+ image_ID = gimp_image_new_with_precision (width, height, type, precision);
gimp_image_undo_disable (image_ID);
gimp_image_set_filename (image_ID, filename);
gimp_image_set_resolution (image_ID, xres, yres);
*layer_ID = create_new_layer (image_ID, 0,
- layername, width, height, type,
- drawable, pixel_rgn);
+ layername, width, height, type);
return image_ID;
}
@@ -705,9 +521,7 @@ create_new_layer (gint32 image_ID,
const gchar *layername,
guint width,
guint height,
- GimpImageBaseType type,
- GimpDrawable **drawable,
- GimpPixelRgn *pixel_rgn)
+ GimpImageBaseType type)
{
gint32 layer_ID;
GimpImageType gdtype = GIMP_RGB_IMAGE;
@@ -732,736 +546,127 @@ create_new_layer (gint32 image_ID,
gdtype, 100, GIMP_NORMAL_MODE);
gimp_image_insert_layer (image_ID, layer_ID, -1, position);
- *drawable = gimp_drawable_get (layer_ID);
- gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
- (*drawable)->height, TRUE, FALSE);
-
return layer_ID;
}
/* Registration Color function */
static void
-transfer_registration_color (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst,
- gint num_channels)
+transfer_registration_color (GeglBuffer *src,
+ GeglBuffer **dst,
+ gint count)
{
- register const guchar *rgb_src = src;
- guchar *dsts[4];
- register gint count = numpix;
- gint channel;
- GimpRGB color;
- guchar red, green, blue;
+ GimpRGB color, test;
+ GeglBufferIterator *gi;
+ const Babl *src_format, *dst_format;
+ gint i, src_bpp, dst_bpp;
+ gdouble white;
gimp_context_get_foreground (&color);
- gimp_rgb_get_uchar (&color, &red, &green, &blue);
+ white = 1.0;
- for (channel = 0; channel < num_channels; channel++)
- dsts[channel] = dst[channel];
+ src_format = gegl_buffer_get_format (src);
+ src_bpp = babl_format_get_bytes_per_pixel (src_format);
- while (count-- > 0)
- {
- if (rgb_src[0] == red && rgb_src[1] == green && rgb_src[2] == blue)
- for (channel = 0; channel < num_channels; channel++)
- *(dsts[channel]++) = 255;
- else
- for (channel = 0; channel < num_channels; channel++)
- dsts[channel]++;
-
- rgb_src += bpp;
- }
-}
+ dst_format = gegl_buffer_get_format (dst[0]);
+ dst_bpp = babl_format_get_bytes_per_pixel (dst_format);
+ gi = gegl_buffer_iterator_new (src, NULL, 0, NULL,
+ GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
-/* Extract functions */
-
-static void
-extract_rgb (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *red_dst = dst[0];
- register guchar *green_dst = dst[1];
- register guchar *blue_dst = dst[2];
- register gint count = numpix, offset = bpp-3;
-
- while (count-- > 0)
+ for (i = 0; i < count; i++)
{
- *(red_dst++) = *(rgb_src++);
- *(green_dst++) = *(rgb_src++);
- *(blue_dst++) = *(rgb_src++);
- rgb_src += offset;
+ gegl_buffer_iterator_add (gi, dst[i], NULL, 0, NULL,
+ GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
}
-}
-static void
-extract_rgba (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgba_src = src;
- register guchar *red_dst = dst[0];
- register guchar *green_dst = dst[1];
- register guchar *blue_dst = dst[2];
- register guchar *alpha_dst = dst[3];
- register gint count = numpix, offset = bpp-4;
-
- while (count-- > 0)
- {
- *(red_dst++) = *(rgba_src++);
- *(green_dst++) = *(rgba_src++);
- *(blue_dst++) = *(rgba_src++);
- *(alpha_dst++) = *(rgba_src++);
- rgba_src += offset;
- }
-}
-
-static void
-extract_red (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *red_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- *(red_dst++) = *rgb_src;
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_green (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src+1;
- register guchar *green_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- *(green_dst++) = *rgb_src;
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_blue (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src+2;
- register guchar *blue_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- *(blue_dst++) = *rgb_src;
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_alpha (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src+3;
- register guchar *alpha_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
+ while (gegl_buffer_iterator_next (gi))
{
- *(alpha_dst++) = *rgb_src;
- rgb_src += offset;
- }
-}
+ guint j, k;
+ gpointer src_data, dst_data[MAX_EXTRACT_IMAGES];
+ src_data = gi->data[0];
+ for (j = 0; j < count; j++)
+ dst_data[j] = gi->data[j+1];
-static void
-extract_cmy (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *cyan_dst = dst[0];
- register guchar *magenta_dst = dst[1];
- register guchar *yellow_dst = dst[2];
- register gint count = numpix, offset = bpp-3;
-
- while (count-- > 0)
- {
- *(cyan_dst++) = 255 - *(rgb_src++);
- *(magenta_dst++) = 255 - *(rgb_src++);
- *(yellow_dst++) = 255 - *(rgb_src++);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_hsv (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *hue_dst = dst[0];
- register guchar *sat_dst = dst[1];
- register guchar *val_dst = dst[2];
- register gint count = numpix, offset = bpp;
- gdouble hue, sat, val;
-
- while (count-- > 0)
- {
- gimp_rgb_to_hsv4 (rgb_src, &hue, &sat, &val);
- *hue_dst++ = (guchar) (hue * 255.999);
- *sat_dst++ = (guchar) (sat * 255.999);
- *val_dst++ = (guchar) (val * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_hue (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *hue_dst = dst[0];
- register gint count = numpix, offset = bpp;
- gdouble hue, dummy;
-
- while (count-- > 0)
- {
- gimp_rgb_to_hsv4 (rgb_src, &hue, &dummy, &dummy);
- *hue_dst++ = (guchar) (hue * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_sat (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *sat_dst = dst[0];
- register gint count = numpix, offset = bpp;
- gdouble sat, dummy;
-
- while (count-- > 0)
- {
- gimp_rgb_to_hsv4 (rgb_src, &dummy, &sat, &dummy);
- *sat_dst++ = (guchar) (sat * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_val (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *val_dst = dst[0];
- register gint count = numpix, offset = bpp;
- gdouble val, dummy;
-
- while (count-- > 0)
- {
- gimp_rgb_to_hsv4 (rgb_src, &dummy, &dummy, &val);
- *val_dst++ = (guchar) (val * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_hsl (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *hue_dst = dst[0];
- register guchar *sat_dst = dst[1];
- register guchar *lum_dst = dst[2];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- GimpRGB rgb;
- GimpHSL hsl;
-
- gimp_rgb_set_uchar (&rgb, rgb_src[0], rgb_src[1], rgb_src[2]);
- gimp_rgb_to_hsl (&rgb, &hsl);
-
- *hue_dst++ = (guchar) (hsl.h * 255.999);
- *sat_dst++ = (guchar) (hsl.s * 255.999);
- *lum_dst++ = (guchar) (hsl.l * 255.999);
-
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_huel (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *hue_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- GimpRGB rgb;
- GimpHSL hsl;
-
- gimp_rgb_set_uchar (&rgb, rgb_src[0], rgb_src[1], rgb_src[2]);
- gimp_rgb_to_hsl (&rgb, &hsl);
-
- *hue_dst++ = (guchar) (hsl.h * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_satl (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *sat_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- GimpRGB rgb;
- GimpHSL hsl;
-
- gimp_rgb_set_uchar (&rgb, rgb_src[0], rgb_src[1], rgb_src[2]);
- gimp_rgb_to_hsl (&rgb, &hsl);
-
- *sat_dst++ = (guchar) (hsl.s * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_lightness (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *lum_dst = dst[0];
- register gint count = numpix, offset = bpp;
-
- while (count-- > 0)
- {
- GimpRGB rgb;
- GimpHSL hsl;
-
- gimp_rgb_set_uchar (&rgb, rgb_src[0], rgb_src[1], rgb_src[2]);
- gimp_rgb_to_hsl (&rgb, &hsl);
- *lum_dst++ = (guchar) (hsl.l * 255.999);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_cyan (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *cyan_dst = dst[0];
- register gint count = numpix, offset = bpp-1;
-
- while (count-- > 0)
- {
- *(cyan_dst++) = 255 - *(rgb_src++);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_magenta (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src+1;
- register guchar *magenta_dst = dst[0];
- register gint count = numpix, offset = bpp-1;
-
- while (count-- > 0)
- {
- *(magenta_dst++) = 255 - *(rgb_src++);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_yellow (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src+2;
- register guchar *yellow_dst = dst[0];
- register gint count = numpix, offset = bpp-1;
-
- while (count-- > 0)
- {
- *(yellow_dst++) = 255 - *(rgb_src++);
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_cmyk (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-
-{
- register const guchar *rgb_src = src;
- register guchar *cyan_dst = dst[0];
- register guchar *magenta_dst = dst[1];
- register guchar *yellow_dst = dst[2];
- register guchar *black_dst = dst[3];
- register gint count = numpix, offset = bpp-3;
- GimpCMYK gcmyk;
-
- gimp_cmyk_set (&gcmyk, 0, 0, 0, 0);
-
- while (count-- > 0)
- {
- GimpRGB grgb;
- guchar r, g, b;
-
- r = *rgb_src++;
- g = *rgb_src++;
- b = *rgb_src++;
-
- gimp_rgb_set_uchar (&grgb, r,g,b);
- gimp_rgb_to_cmyk (&grgb, 1.0, &gcmyk);
- gimp_cmyk_get_uchar (&gcmyk,
- cyan_dst++, magenta_dst++, yellow_dst++,
- black_dst++);
-
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_cyank (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *cyan_dst = dst[0];
- register gint count = numpix, offset = bpp-3;
- GimpCMYK gcmyk;
-
- gimp_cmyk_set(&gcmyk, 0, 0, 0, 0);
-
- while (count-- > 0)
- {
- GimpRGB grgb;
- guchar r, g, b;
-
- r = *rgb_src++;
- g = *rgb_src++;
- b = *rgb_src++;
-
- gimp_rgb_set_uchar (&grgb, r,g,b);
- gimp_rgb_to_cmyk (&grgb, 1.0, &gcmyk);
- gimp_cmyk_get_uchar (&gcmyk, cyan_dst++, NULL, NULL, NULL);
-
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_magentak (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *magenta_dst = dst[0];
- register gint count = numpix, offset = bpp-3;
- GimpCMYK gcmyk;
-
- gimp_cmyk_set(&gcmyk, 0, 0, 0, 0);
-
- while (count-- > 0)
- {
- GimpRGB grgb;
- guchar r, g, b;
-
- r = *rgb_src++;
- g = *rgb_src++;
- b = *rgb_src++;
-
- gimp_rgb_set_uchar (&grgb, r,g,b);
- gimp_rgb_to_cmyk (&grgb, 1.0, &gcmyk);
- gimp_cmyk_get_uchar (&gcmyk, NULL, magenta_dst++, NULL, NULL);
-
- rgb_src += offset;
- }
-}
-
-
-static void
-extract_yellowk (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-
-{
- register const guchar *rgb_src = src;
- register guchar *yellow_dst = dst[0];
- register gint count = numpix, offset = bpp-3;
- GimpCMYK gcmyk;
-
- gimp_cmyk_set(&gcmyk, 0, 0, 0, 0);
-
- while (count-- > 0)
- {
- GimpRGB grgb;
- guchar r, g, b;
-
- r = *rgb_src++;
- g = *rgb_src++;
- b = *rgb_src++;
-
- gimp_rgb_set_uchar (&grgb, r,g,b);
- gimp_rgb_to_cmyk (&grgb, 1.0, &gcmyk);
- gimp_cmyk_get_uchar (&gcmyk, NULL, NULL, yellow_dst++, NULL);
-
- rgb_src += offset;
- }
-}
-
-static void
-extract_lab (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *l_dst = dst[0];
- register guchar *a_dst = dst[1];
- register guchar *b_dst = dst[2];
- register gint count = numpix, offset = bpp;
-
- gdouble red, green, blue;
- gdouble x, y, z;
- gdouble l; /*, a, b; */
- gdouble tx, ty, tz;
- gdouble ftx, fty, ftz;
-
- gdouble sixteenth = 16.0 / 116.0;
-
- /* LAB colorspace constants */
-#define LAB_Xn 0.951
-#define LAB_Yn 1.0
-#define LAB_Zn 1.089
-
- while (count-- > 0)
- {
- red = rgb_src[0] / 255.0;
- green = rgb_src[1] / 255.0;
- blue = rgb_src[2] / 255.0;
-
- x = 0.431 * red + 0.342 * green + 0.178 * blue;
- y = 0.222 * red + 0.707 * green + 0.071 * blue;
- z = 0.020 * red + 0.130 * green + 0.939 * blue;
-
- if ((ty = y / LAB_Yn) > 0.008856)
- {
- l = 116.0 * cbrt (ty) - 16.0;
- fty = cbrt (ty);
- }
- else
+ for (k = 0; k < gi->length; k++)
{
- l = 903.3 * ty;
- fty = 7.78 * ty + sixteenth;
- }
-
- ftx = ((tx = x / LAB_Xn) > 0.008856) ? cbrt (tx) : 7.78 * tx + sixteenth;
- ftz = ((tz = z / LAB_Zn) > 0.008856) ? cbrt (tz) : 7.78 * tz + sixteenth;
-
- *l_dst++ = (guchar) CLAMP (l * 2.5599, 0., 256.);
- *a_dst++ = (guchar) CLAMP (128.0 + (ftx - fty) * 635, 0., 256.);
- *b_dst++ = (guchar) CLAMP (128.0 + (fty - ftz) * 254, 0., 256.);
+ gulong pos;
+ pos = k * src_bpp;
+ gimp_rgba_set_pixel (&test, src_format, ((guchar *)src_data) + pos);
- rgb_src += offset;
+ if (gimp_rgb_distance (&test, &color) < 1e-6)
+ {
+ for (j = 0; j < count; j++)
+ {
+ gpointer data;
+ data = dst_data[j];
+ babl_process (babl_fish (babl_format ("Y double"), dst_format),
+ &white, (guchar *)data + (k * dst_bpp), 1);
+ }
+ }
+ }
}
}
-
-/* these are here so the code is more readable and we can use
- the standard 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*219.0/255.0 + 0.5))
-#define FIXC(a) ((int)((a)*256.0*256.0*224.0/255.0 + 0.5))
-
static void
-extract_ycbcr470 (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
+copy_n_components (GeglBuffer *src,
+ GeglBuffer **dst,
+ const gchar *model,
+ guint n,
+ const gchar **components)
{
- register const guchar *rgb_src = src;
- register guchar *y_dst = dst[0];
- register guchar *cb_dst = dst[1];
- register guchar *cr_dst = dst[2];
- register gint count = numpix, offset = bpp-3;
+ gint i;
- while (count-- > 0)
+ for (i = 0; i < n; i++)
{
- register int r, g, b;
- r= *(rgb_src++);
- g= *(rgb_src++);
- b= *(rgb_src++);
- *(y_dst++) = ( FIXY(0.2989)*r + FIXY(0.5866)*g + FIXY(0.1145)*b + FIX( 16.5))>>16;
- *(cb_dst++) = (-FIXC(0.1688)*r - FIXC(0.3312)*g + FIXC(0.5000)*b + FIX(128.5))>>16;
- *(cr_dst++) = ( FIXC(0.5000)*r - FIXC(0.4184)*g - FIXC(0.0816)*b + FIX(128.5))>>16;
-
- rgb_src += offset;
+ gimp_progress_update ((gdouble) i / (gdouble) n);
+ copy_one_component (src, dst[i], model, components[i]);
}
}
-
static void
-extract_ycbcr709 (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
+copy_one_component (GeglBuffer *src,
+ GeglBuffer *dst,
+ const gchar *model,
+ const gchar *component)
{
- register const guchar *rgb_src = src;
- register guchar *y_dst = dst[0];
- register guchar *cb_dst = dst[1];
- register guchar *cr_dst = dst[2];
- register gint count = numpix, offset = bpp-3;
+ const Babl *component_format, *dst_format;
+ GeglBuffer *temp;
+ const GeglRectangle *extent;
- while (count-- > 0)
- {
- register int r, g, b;
- r= *(rgb_src++);
- g= *(rgb_src++);
- b= *(rgb_src++);
- *(y_dst++) = ( FIXY(0.2126)*r + FIXY(0.7152)*g + FIXY(0.0722)*b + FIX( 16.5))>>16;
- *(cb_dst++) = (-FIXC(0.1150)*r - FIXC(0.3860)*g + FIXC(0.5000)*b + FIX(128.5))>>16;
- *(cr_dst++) = ( FIXC(0.5000)*r - FIXC(0.4540)*g - FIXC(0.0460)*b + FIX(128.5))>>16;
-
- rgb_src += offset;
- }
-}
+ /* We are working in linear double precison*/
+ component_format = babl_format_new (babl_model (model),
+ babl_type ("double"),
+ babl_component (component),
+ NULL);
+ /* Alpha case, we need to enforce linearity here
+ * If the output is "Y'", the ouput of temp is already ok
+ * If the output is "Y" , it will enforce gamma-decoding...
+ * A bit tricky...
+ */
+ if (!g_strcmp0 (component , "A"))
+ dst_format = babl_format ("Y' double");
+ else
+ dst_format = babl_format ("Y double");
-static void
-extract_ycbcr470f (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *y_dst = dst[0];
- register guchar *cb_dst = dst[1];
- register guchar *cr_dst = dst[2];
- register gint count = numpix, offset = bpp-3;
+ extent = gegl_buffer_get_extent (src);
+ temp = gegl_buffer_new (extent, dst_format);
- while (count-- > 0)
- {
- register int r, g, b, cb, cr;
- r= *(rgb_src++);
- g= *(rgb_src++);
- b= *(rgb_src++);
- *(y_dst++ ) = ( FIX(0.2989)*r + FIX(0.5866)*g + FIX(0.1145)*b + FIX( 0.5))>>16;
- cb = (-FIX(0.1688)*r - FIX(0.3312)*g + FIX(0.5000)*b + FIX(128.5))>>16;
- cr = ( FIX(0.5000)*r - FIX(0.4184)*g - FIX(0.0816)*b + FIX(128.5))>>16;
- if(cb>255) cb=255;
- if(cr>255) cr=255;
- *(cb_dst++) = cb;
- *(cr_dst++) = cr;
- rgb_src += offset;
- }
-}
+ /* we want to copy the componnent as is */
+ gegl_buffer_set_format (temp, component_format);
+ gegl_buffer_copy (src, NULL, temp, NULL);
+ /* This is our new "Y(') double" componnent buffer */
+ gegl_buffer_set_format (temp, NULL);
-static void
-extract_ycbcr709f (const guchar *src,
- gint bpp,
- gint numpix,
- guchar **dst)
-{
- register const guchar *rgb_src = src;
- register guchar *y_dst = dst[0];
- register guchar *cb_dst = dst[1];
- register guchar *cr_dst = dst[2];
- register gint count = numpix, offset = bpp-3;
+ /* Now we let babl convert it back to the format that dst needs */
+ gegl_buffer_copy (temp, NULL, dst, NULL);
- while (count-- > 0)
- {
- register int r, g, b, cb, cr;
- r= *(rgb_src++);
- g= *(rgb_src++);
- b= *(rgb_src++);
- *(y_dst++) = ( FIX(0.2126)*r + FIX(0.7152)*g + FIX(0.0722)*b + FIX( 0.5))>>16;
- cb = (-FIX(0.1150)*r - FIX(0.3860)*g + FIX(0.5000)*b + FIX(128.5))>>16;
- cr = ( FIX(0.5000)*r - FIX(0.4540)*g - FIX(0.0460)*b + FIX(128.5))>>16;
- if(cb>255) cb=255;
- if(cr>255) cr=255;
- *(cb_dst++) = cb;
- *(cr_dst++) = cr;
-
- rgb_src += offset;
- }
+ g_object_unref (temp);
}
-
static gboolean
decompose_dialog (void)
{
@@ -1597,3 +802,54 @@ decompose_dialog (void)
return run;
}
+
+/* Build a filename like <imagename>-<channel>.<extension> */
+gchar *
+generate_filename (guint32 image_ID, guint colorspace, guint channel)
+{
+ /* Build a filename like <imagename>-<channel>.<extension> */
+ gchar *fname;
+ gchar *filename;
+ gchar *extension;
+
+ fname = gimp_image_get_filename (image_ID);
+
+ if (fname)
+ {
+ extension = fname + strlen (fname) - 1;
+
+ while (extension >= fname)
+ {
+ if (*extension == '.') break;
+ extension--;
+ }
+ if (extension >= fname)
+ {
+ *(extension++) = '\0';
+
+ if (decovals.as_layers)
+ filename = g_strdup_printf ("%s-%s.%s", fname,
+ gettext (extract[colorspace].type),
+ extension);
+ else
+ filename = g_strdup_printf ("%s-%s.%s", fname,
+ gettext (extract[colorspace].channel_name[channel]),
+ extension);
+ }
+ else
+ {
+ if (decovals.as_layers)
+ filename = g_strdup_printf ("%s-%s", fname,
+ gettext (extract[colorspace].type));
+ else
+ filename = g_strdup_printf ("%s-%s", fname,
+ gettext (extract[colorspace].channel_name[channel]));
+ }
+ }
+ else
+ {
+ filename = g_strdup (gettext (extract[colorspace].channel_name[channel]));
+ }
+ g_free (fname);
+ return filename;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]