diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index 60e4ad677e..7724eb4ea4 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -28,7 +28,7 @@ #include "internal-procs.h" -/* 685 procedures registered total */ +/* 686 procedures registered total */ void internal_procs_init (GimpPDB *pdb) diff --git a/app/pdb/plug-in-compat-cmds.c b/app/pdb/plug-in-compat-cmds.c index 912836adf6..a705fe628b 100644 --- a/app/pdb/plug-in-compat-cmds.c +++ b/app/pdb/plug-in-compat-cmds.c @@ -195,6 +195,69 @@ plug_in_colortoalpha_invoker (GimpProcedure *procedure, error ? *error : NULL); } +static GimpValueArray * +plug_in_cubism_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpDrawable *drawable; + gdouble tile_size; + gdouble tile_saturation; + gint32 bg_color; + + drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp); + tile_size = g_value_get_double (gimp_value_array_index (args, 3)); + tile_saturation = g_value_get_double (gimp_value_array_index (args, 4)); + bg_color = g_value_get_int (gimp_value_array_index (args, 5)); + + if (success) + { + if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, + GIMP_PDB_ITEM_CONTENT, error) && + gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) + { + GimpRGB color; + GeglColor *gegl_color; + GeglNode *node; + + if (bg_color) + { + gimp_context_get_background (context, &color); + gimp_rgb_set_alpha (&color, 0.0); + } + else + { + gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0); + } + + gegl_color = gimp_gegl_color_new (&color); + + node = gegl_node_new_child (NULL, + "operation", "gegl:cubism", + "tile-size", tile_size, + "tile-saturation", tile_saturation, + "bg-color", gegl_color, + NULL); + g_object_unref (gegl_color); + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Cubism"), + node); + + g_object_unref (node); + } + else + success = FALSE; + } + + return gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); +} + static GimpValueArray * plug_in_pixelize_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -782,6 +845,60 @@ register_plug_in_compat_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); + /* + * gimp-plug-in-cubism + */ + procedure = gimp_procedure_new (plug_in_cubism_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "plug-in-cubism"); + gimp_procedure_set_static_strings (procedure, + "plug-in-cubism", + "Convert the image into randomly rotated square blobs", + "Convert the image into randomly rotated square blobs.", + "Compatibility procedure. Please see 'gegl:cubism' for credits.", + "Compatibility procedure. Please see 'gegl:cubism' for credits.", + "2013", + NULL); + gimp_procedure_add_argument (procedure, + g_param_spec_enum ("run-mode", + "run mode", + "The run mode", + GIMP_TYPE_RUN_MODE, + GIMP_RUN_INTERACTIVE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_image_id ("image", + "image", + "Input image (unused)", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_drawable_id ("drawable", + "drawable", + "Input drawable", + pdb->gimp, FALSE, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + g_param_spec_double ("tile-size", + "tile size", + "Average diameter of each tile (in pixels)", + 0.0, 100.0, 0.0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + g_param_spec_double ("tile-saturation", + "tile saturation", + "Expand tiles by this amount", + 0.0, 10.0, 0.0, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_int32 ("bg-color", + "bg color", + "Background color { BLACK (0), BG (1) }", + 0, 1, 0, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + /* * gimp-plug-in-pixelize */ diff --git a/plug-ins/common/.gitignore b/plug-ins/common/.gitignore index 68e1695d69..aecdcef676 100644 --- a/plug-ins/common/.gitignore +++ b/plug-ins/common/.gitignore @@ -60,8 +60,6 @@ /convolution-matrix.exe /crop-zealous /crop-zealous.exe -/cubism -/cubism.exe /curve-bend /curve-bend.exe /decompose diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am index 30d1962a6a..6c0a0ab358 100644 --- a/plug-ins/common/Makefile.am +++ b/plug-ins/common/Makefile.am @@ -73,7 +73,6 @@ libexec_PROGRAMS = \ contrast-stretch-hsv \ convolution-matrix \ crop-zealous \ - cubism \ curve-bend \ decompose \ deinterlace \ @@ -697,23 +696,6 @@ crop_zealous_LDADD = \ $(INTLLIBS) \ $(crop_zealous_RC) -cubism_SOURCES = \ - cubism.c - -cubism_LDADD = \ - $(libgimpui) \ - $(libgimpwidgets) \ - $(libgimpmodule) \ - $(libgimp) \ - $(libgimpmath) \ - $(libgimpconfig) \ - $(libgimpcolor) \ - $(libgimpbase) \ - $(GTK_LIBS) \ - $(RT_LIBS) \ - $(INTLLIBS) \ - $(cubism_RC) - curve_bend_SOURCES = \ curve-bend.c diff --git a/plug-ins/common/cubism.c b/plug-ins/common/cubism.c deleted file mode 100644 index bf36a1f6dd..0000000000 --- a/plug-ins/common/cubism.c +++ /dev/null @@ -1,878 +0,0 @@ -/* Cubism --- image filter plug-in for GIMP - * Copyright (C) 1996 Spencer Kimball, Tracy Scott - * - * 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 . - * - * You can contact me at quartic@polloux.fciencias.unam.mx - * You can contact the original GIMP authors at gimp@xcf.berkeley.edu - * Speedups by Elliot Lee - */ - -#include "config.h" - -#include - -#include -#include - -#include "libgimp/stdplugins-intl.h" - - -#define PLUG_IN_PROC "plug-in-cubism" -#define PLUG_IN_BINARY "cubism" -#define PLUG_IN_ROLE "gimp-cubism" - -#define SCALE_WIDTH 125 -#define BLACK 0 -#define BG 1 -#define SUPERSAMPLE 4 -#define MAX_POINTS 4 -#define RANDOMNESS 5 - - -typedef struct -{ - gint npts; - GimpVector2 pts[MAX_POINTS]; -} Polygon; - -typedef struct -{ - gdouble tile_size; - gdouble tile_saturation; - gint bg_color; - gboolean preview; -} CubismVals; - -/* 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 void cubism (GimpDrawable *drawable, - GimpPreview *preview); -static gboolean cubism_dialog (GimpDrawable *drawable); - -static void fill_poly_color (Polygon *poly, - GimpDrawable *drawable, - GimpPreview *preview, - guchar *col, - guchar *dest); - -static void convert_segment (gint x1, - gint y1, - gint x2, - gint y2, - gint offset, - gint *min, - gint *max); - -static void randomize_indices (gint count, - gint *indices); - -static gdouble calc_alpha_blend (gdouble *vec, - gdouble one_over_dist, - gdouble x, - gdouble y); - -static void polygon_add_point (Polygon *poly, - gdouble x, - gdouble y); -static void polygon_translate (Polygon *poly, - gdouble tx, - gdouble ty); -static void polygon_rotate (Polygon *poly, - gdouble theta); -static gint polygon_extents (Polygon *poly, - gdouble *min_x, - gdouble *min_y, - gdouble *max_x, - gdouble *max_y); -static void polygon_reset (Polygon *poly); - - -/* - * Local variables - */ - -static CubismVals cvals = -{ - 10.0, /* tile_size */ - 2.5, /* tile_saturation */ - BLACK, /* bg_color */ - TRUE /* preview */ -}; - -const GimpPlugInInfo PLUG_IN_INFO = -{ - NULL, /* init_proc */ - NULL, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ -}; - - -/* - * Functions - */ - -MAIN () - -static void -query (void) -{ - static const GimpParamDef args[] = - { - { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" }, - { GIMP_PDB_IMAGE, "image", "Input image" }, - { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }, - { GIMP_PDB_FLOAT, "tile-size", "Average diameter of each tile (in pixels)" }, - { GIMP_PDB_FLOAT, "tile-saturation", "Expand tiles by this amount" }, - { GIMP_PDB_INT32, "bg-color", "Background color { BLACK (0), BG (1) }" } - }; - - gimp_install_procedure (PLUG_IN_PROC, - N_("Convert the image into randomly rotated square blobs"), - "Help not yet written for this plug-in", - "Spencer Kimball & Tracy Scott", - "Spencer Kimball & Tracy Scott", - "1996", - N_("_Cubism..."), - "RGB*, GRAY*", - GIMP_PLUGIN, - G_N_ELEMENTS (args), 0, - args, NULL); - - gimp_plugin_menu_register (PLUG_IN_PROC, "/Filters/Artistic"); -} - -static void -run (const gchar *name, - gint nparams, - const GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals) -{ - static GimpParam values[1]; - GimpDrawable *drawable; - GimpRunMode run_mode; - GimpPDBStatusType status = GIMP_PDB_SUCCESS; - - INIT_I18N (); - - run_mode = param[0].data.d_int32; - - *nreturn_vals = 1; - *return_vals = values; - - values[0].type = GIMP_PDB_STATUS; - values[0].data.d_status = status; - - /* get the active drawable */ - drawable = gimp_drawable_get (param[2].data.d_drawable); - - /* set cache size */ - /* asking for a lot here but seems to give a speedup -- WES 12-23-04 */ - gimp_tile_cache_ntiles (2 * drawable->ntile_rows * drawable->ntile_cols); - - switch (run_mode) - { - case GIMP_RUN_INTERACTIVE: - /* Possibly retrieve data */ - gimp_get_data (PLUG_IN_PROC, &cvals); - - /* First acquire information with a dialog */ - if (! cubism_dialog (drawable)) - return; - break; - - case GIMP_RUN_NONINTERACTIVE: - /* Make sure all the arguments are there! */ - if (nparams != 6) - status = GIMP_PDB_CALLING_ERROR; - if (status == GIMP_PDB_SUCCESS) - { - cvals.tile_size = param[3].data.d_float; - cvals.tile_saturation = param[4].data.d_float; - cvals.bg_color = param[5].data.d_int32; - } - if (status == GIMP_PDB_SUCCESS && - (cvals.bg_color < BLACK || cvals.bg_color > BG)) - status = GIMP_PDB_CALLING_ERROR; - break; - - case GIMP_RUN_WITH_LAST_VALS: - /* Possibly retrieve data */ - gimp_get_data (PLUG_IN_PROC, &cvals); - break; - - default: - break; - } - - /* Render the cubism effect */ - if ((status == GIMP_PDB_SUCCESS) && - (gimp_drawable_is_rgb (drawable->drawable_id) || - gimp_drawable_is_gray (drawable->drawable_id))) - { - - cubism (drawable, NULL); - - /* If the run mode is interactive, flush the displays */ - if (run_mode != GIMP_RUN_NONINTERACTIVE) - gimp_displays_flush (); - - /* Store mvals data */ - if (run_mode == GIMP_RUN_INTERACTIVE) - gimp_set_data (PLUG_IN_PROC, &cvals, sizeof (CubismVals)); - } - else if (status == GIMP_PDB_SUCCESS) - { - /* gimp_message ("cubism: cannot operate on indexed color images"); */ - status = GIMP_PDB_EXECUTION_ERROR; - } - - values[0].data.d_status = status; - - gimp_drawable_detach (drawable); -} - -static gboolean -cubism_dialog (GimpDrawable *drawable) -{ - GtkWidget *dialog; - GtkWidget *main_vbox; - GtkWidget *preview; - GtkWidget *toggle; - GtkWidget *table; - GtkObject *scale_data; - gboolean run; - - gimp_ui_init (PLUG_IN_BINARY, FALSE); - - dialog = gimp_dialog_new (_("Cubism"), PLUG_IN_ROLE, - NULL, 0, - gimp_standard_help_func, PLUG_IN_PROC, - - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - - NULL); - - gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - GTK_RESPONSE_OK, - GTK_RESPONSE_CANCEL, - -1); - - gimp_window_set_transient (GTK_WINDOW (dialog)); - - 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); - - preview = gimp_drawable_preview_new (drawable, &cvals.preview); - gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0); - gtk_widget_show (preview); - - g_signal_connect_swapped (preview, "invalidated", - G_CALLBACK (cubism), - drawable); - - table = gtk_table_new (2, 3, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_row_spacing (GTK_TABLE (table), 0, 4); - gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0); - gtk_widget_show (table); - - scale_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 0, - _("_Tile size:"), SCALE_WIDTH, 5, - cvals.tile_size, 0.0, 100.0, 1.0, 10.0, 1, - TRUE, 0, 0, - NULL, NULL); - g_signal_connect (scale_data, "value-changed", - G_CALLBACK (gimp_double_adjustment_update), - &cvals.tile_size); - g_signal_connect_swapped (scale_data, "value-changed", - G_CALLBACK (gimp_preview_invalidate), - preview); - - scale_data = - gimp_scale_entry_new (GTK_TABLE (table), 0, 1, - _("T_ile saturation:"), SCALE_WIDTH, 5, - cvals.tile_saturation, 0.0, 10.0, 0.1, 1, 1, - TRUE, 0, 0, - NULL, NULL); - g_signal_connect (scale_data, "value-changed", - G_CALLBACK (gimp_double_adjustment_update), - &cvals.tile_saturation); - g_signal_connect_swapped (scale_data, "value-changed", - G_CALLBACK (gimp_preview_invalidate), - preview); - - toggle = gtk_check_button_new_with_mnemonic (_("_Use background color")); - gtk_box_pack_start (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 0); - gtk_widget_show (toggle); - - g_signal_connect (toggle, "toggled", - G_CALLBACK (gimp_toggle_button_update), - &cvals.bg_color); - g_signal_connect_swapped (toggle, "toggled", - G_CALLBACK (gimp_preview_invalidate), - preview); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), - (cvals.bg_color == BG)); - - gtk_widget_show (dialog); - - run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK); - - gtk_widget_destroy (dialog); - - return run; -} - -static void -cubism (GimpDrawable *drawable, - GimpPreview *preview) -{ - GimpPixelRgn src_rgn; - guchar bg_col[4]; - gdouble x, y; - gdouble width, height; - gdouble theta; - gint ix, iy; - gint rows, cols; - gint i, j, count; - gint num_tiles; - gint x1, y1, x2, y2; - gint sel_width, sel_height; - Polygon poly; - guchar col[4]; - guchar *dest = NULL; - gint bytes; - gboolean has_alpha; - gint *random_indices; - gpointer pr; - GRand *gr; - - gr = g_rand_new (); - has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); - bytes = drawable->bpp; - - if (preview) - { - gimp_preview_get_position (preview, &x1, &y1); - gimp_preview_get_size (preview, &sel_width, &sel_height); - dest = g_new (guchar, sel_height * sel_width * bytes); - } - else if (! gimp_drawable_mask_intersect (drawable->drawable_id, - &x1, &y1, &sel_width, &sel_height)) - { - return; - } - - x2 = x1 + sel_width; - y2 = y1 + sel_height; - - /* determine the background color */ - if (cvals.bg_color == BLACK) - { - bg_col[0] = bg_col[1] = bg_col[2] = bg_col[3] = 0; - } - else - { - GimpRGB color; - - gimp_context_get_background (&color); - gimp_rgb_set_alpha (&color, 0.0); - gimp_drawable_get_color_uchar (drawable->drawable_id, &color, bg_col); - } - - cols = ((x2 - x1) + cvals.tile_size - 1) / cvals.tile_size; - rows = ((y2 - y1) + cvals.tile_size - 1) / cvals.tile_size; - - /* Fill the image with the background color */ - if (preview) - { - for (i = 0; i < sel_width * sel_height ; i++) - for (count = 0; count < bytes; count++) - dest[i * bytes + count] = bg_col[count]; - } - else - { - gimp_progress_init (_("Cubistic transformation")); - gimp_pixel_rgn_init (&src_rgn, drawable, - x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE); - - for (pr = gimp_pixel_rgns_register (1, &src_rgn); - pr != NULL; - pr = gimp_pixel_rgns_process (pr)) - { - count = src_rgn.w * src_rgn.h; - dest = src_rgn.data; - - while (count--) - for (i = 0; i < bytes; i++) - *dest++ = bg_col[i]; - } - - dest = NULL; - } - - num_tiles = (rows + 1) * (cols + 1); - random_indices = g_new (gint, num_tiles); - for (i = 0; i < num_tiles; i++) - random_indices[i] = i; - - randomize_indices (num_tiles, random_indices); - - gimp_pixel_rgn_init (&src_rgn, drawable, - x1, y1, x2 - x1, y2 - y1, FALSE, FALSE); - - for (count = 0; count < num_tiles; count++) - { - i = random_indices[count] / (cols + 1); - j = random_indices[count] % (cols + 1); - x = j * cvals.tile_size + (cvals.tile_size / 4.0) - - g_rand_double_range (gr, 0, cvals.tile_size/2.0) + x1; - y = i * cvals.tile_size + (cvals.tile_size / 4.0) - - g_rand_double_range (gr, 0, cvals.tile_size/2.0) + y1; - width = (cvals.tile_size + - g_rand_double_range (gr, 0, cvals.tile_size / 4.0) - - cvals.tile_size / 8.0) * cvals.tile_saturation; - height = (cvals.tile_size + - g_rand_double_range (gr, 0, cvals.tile_size / 4.0) - - cvals.tile_size / 8.0) * cvals.tile_saturation; - theta = g_rand_double_range (gr, 0, 2 * G_PI); - polygon_reset (&poly); - polygon_add_point (&poly, -width / 2.0, -height / 2.0); - polygon_add_point (&poly, width / 2.0, -height / 2.0); - polygon_add_point (&poly, width / 2.0, height / 2.0); - polygon_add_point (&poly, -width / 2.0, height / 2.0); - polygon_rotate (&poly, theta); - polygon_translate (&poly, x, y); - - /* bounds check on x, y */ - ix = CLAMP (x, x1, x2 - 1); - iy = CLAMP (y, y1, y2 - 1); - - gimp_pixel_rgn_get_pixel (&src_rgn, col, ix, iy); - - if (! has_alpha || col[bytes - 1]) - fill_poly_color (&poly, drawable, preview, col, dest); - - if (! preview) - { - if (count % 8 == 0) - gimp_progress_update ((gdouble) count / (gdouble) num_tiles); - } - } - - g_free (random_indices); - g_rand_free (gr); - - if (preview) - { - gimp_preview_draw_buffer (preview, dest, sel_width * bytes); - g_free (dest); - } - else - { - gimp_progress_update (1.0); - /* merge the shadow, update the drawable */ - gimp_drawable_flush (drawable); - gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); - gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1); - } -} - -static inline gdouble -calc_alpha_blend (gdouble *vec, - gdouble one_over_dist, - gdouble x, - gdouble y) -{ - gdouble r; - - if (! one_over_dist) - return 1.0; - - r = (vec[0] * x + vec[1] * y) * one_over_dist; - - return CLAMP (r, 0.2, 1.0); -} - -static void -fill_poly_color (Polygon *poly, - GimpDrawable *drawable, - GimpPreview *preview, - guchar *col, - guchar *dest) -{ - GimpPixelRgn src_rgn; - gdouble dmin_x = 0.0; - gdouble dmin_y = 0.0; - gdouble dmax_x = 0.0; - gdouble dmax_y = 0.0; - gint xs, ys; - gint xe, ye; - gint min_x, min_y; - gint max_x, max_y; - gint size_x, size_y; - gint *max_scanlines, *max_scanlines_iter; - gint *min_scanlines, *min_scanlines_iter; - gint val; - gint alpha; - gint bytes; - guchar buf[4]; - gint i, j, x, y; - gdouble sx, sy; - gdouble ex, ey; - gdouble xx, yy; - gdouble vec[2]; - gdouble dist, one_over_dist; - gint x1, y1, x2, y2; - gint sel_width, sel_height; - gint *vals, *vals_iter, *vals_end; - gint b; - - sx = poly->pts[0].x; - sy = poly->pts[0].y; - ex = poly->pts[1].x; - ey = poly->pts[1].y; - - dist = sqrt (SQR (ex - sx) + SQR (ey - sy)); - if (dist > 0.0) - { - one_over_dist = 1.0 / dist; - vec[0] = (ex - sx) * one_over_dist; - vec[1] = (ey - sy) * one_over_dist; - } - else - { - one_over_dist = 0.0; - vec[0] = 0.0; - vec[1] = 0.0; - } - - if (preview) - { - gimp_preview_get_position (preview, &x1, &y1); - gimp_preview_get_size (preview, &sel_width, &sel_height); - x2 = x1 + sel_width; - y2 = y1 + sel_height; - } - else - { - gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); - gimp_pixel_rgn_init (&src_rgn, drawable, - x1, y1, x2 - x1, y2 - y1, - TRUE, TRUE); - } - bytes = drawable->bpp; - - polygon_extents (poly, &dmin_x, &dmin_y, &dmax_x, &dmax_y); - min_x = (gint) dmin_x; - min_y = (gint) dmin_y; - max_x = (gint) dmax_x; - max_y = (gint) dmax_y; - - size_y = (max_y - min_y) * SUPERSAMPLE; - size_x = (max_x - min_x) * SUPERSAMPLE; - - min_scanlines = min_scanlines_iter = g_new (gint, size_y); - max_scanlines = max_scanlines_iter = g_new (gint, size_y); - for (i = 0; i < size_y; i++) - { - min_scanlines[i] = max_x * SUPERSAMPLE; - max_scanlines[i] = min_x * SUPERSAMPLE; - } - - if (poly->npts) - { - GimpVector2 *curptr; - gint poly_npts = poly->npts; - - xs = (gint) (poly->pts[poly_npts-1].x); - ys = (gint) (poly->pts[poly_npts-1].y); - xe = (gint) poly->pts[0].x; - ye = (gint) poly->pts[0].y; - - xs *= SUPERSAMPLE; - ys *= SUPERSAMPLE; - xe *= SUPERSAMPLE; - ye *= SUPERSAMPLE; - - convert_segment (xs, ys, xe, ye, min_y * SUPERSAMPLE, - min_scanlines, max_scanlines); - - for (i = 1, curptr = &poly->pts[0]; i < poly_npts; i++) - { - xs = (gint) curptr->x; - ys = (gint) curptr->y; - curptr++; - xe = (gint) curptr->x; - ye = (gint) curptr->y; - - xs *= SUPERSAMPLE; - ys *= SUPERSAMPLE; - xe *= SUPERSAMPLE; - ye *= SUPERSAMPLE; - - convert_segment (xs, ys, xe, ye, min_y * SUPERSAMPLE, - min_scanlines, max_scanlines); - } - } - - vals = g_new (gint, size_x); - - for (i = 0; i < size_y; i++, min_scanlines_iter++, max_scanlines_iter++) - { - if (! (i % SUPERSAMPLE)) - { - memset (vals, 0, sizeof (gint) * size_x); - } - - yy = (gdouble)i / (gdouble)SUPERSAMPLE + min_y; - - for (j = *min_scanlines_iter; j < *max_scanlines_iter; j++) - { - x = j - min_x * SUPERSAMPLE; - vals[x] += 255; - } - - if (! ((i + 1) % SUPERSAMPLE)) - { - y = (i / SUPERSAMPLE) + min_y; - - if (y >= y1 && y < y2) - { - for (j = 0; j < size_x; j += SUPERSAMPLE) - { - x = (j / SUPERSAMPLE) + min_x; - - if (x >= x1 && x < x2) - { - for (val = 0, vals_iter = &vals[j], - vals_end = &vals_iter[SUPERSAMPLE]; - vals_iter < vals_end; - vals_iter++) - val += *vals_iter; - - val /= SQR(SUPERSAMPLE); - - if (val > 0) - { - xx = (gdouble) j / (gdouble) SUPERSAMPLE + min_x; - alpha = (gint) (val * calc_alpha_blend (vec, - one_over_dist, - xx - sx, - yy - sy)); - if (preview) - { - for (b = 0; b < bytes; b++) - buf[b] = dest[ ( (y-y1) * sel_width + (x-x1) ) * bytes + b]; - } - else - { - gimp_pixel_rgn_get_pixel (&src_rgn, buf, x, y); - } - -#ifndef USE_READABLE_BUT_SLOW_CODE - { - guchar *buf_iter = buf; - guchar *col_iter = col; - guchar *buf_end = buf + bytes; - - for(; buf_iter < buf_end; buf_iter++, col_iter++) - *buf_iter = ((guint) (*col_iter * alpha) - + (((guint) *buf_iter) - * (256 - alpha))) >> 8; - } -#else /* original, pre-ECL code */ - for (b = 0; b < bytes; b++) - buf[b] = ((col[b] * alpha) + (buf[b] * (255 - alpha))) / 255; - -#endif - if (preview) - { - for (b = 0; b < bytes; b++) - dest[ ( (y-y1) * sel_width + (x-x1) ) * bytes + b] = buf[b]; - } - else - { - gimp_pixel_rgn_set_pixel (&src_rgn, buf, x, y); - } - } - } - } - } - } - } - - g_free (vals); - g_free (min_scanlines); - g_free (max_scanlines); -} - -static void -convert_segment (gint x1, - gint y1, - gint x2, - gint y2, - gint offset, - gint *min, - gint *max) -{ - gint ydiff, y, tmp; - gdouble xinc, xstart; - - if (y1 > y2) - { - tmp = y2; y2 = y1; y1 = tmp; - tmp = x2; x2 = x1; x1 = tmp; - } - ydiff = (y2 - y1); - - if (ydiff) - { - xinc = (gdouble) (x2 - x1) / (gdouble) ydiff; - xstart = x1 + 0.5 * xinc; - for (y = y1 ; y < y2; y++) - { - if (xstart < min[y - offset]) - min[y-offset] = xstart; - if (xstart > max[y - offset]) - max[y-offset] = xstart; - - xstart += xinc; - } - } -} - -static void -randomize_indices (gint count, - gint *indices) -{ - gint i; - gint index1, index2; - gint tmp; - GRand *gr; - - gr = g_rand_new(); - - for (i = 0; i < count * RANDOMNESS; i++) - { - index1 = g_rand_int_range (gr, 0, count); - index2 = g_rand_int_range (gr, 0, count); - tmp = indices[index1]; - indices[index1] = indices[index2]; - indices[index2] = tmp; - } - - g_rand_free (gr); -} - -static void -polygon_add_point (Polygon *poly, - gdouble x, - gdouble y) -{ - if (poly->npts < MAX_POINTS) - { - poly->pts[poly->npts].x = x; - poly->pts[poly->npts].y = y; - poly->npts++; - } - else - g_print ("Unable to add additional point.\n"); -} - -static void -polygon_rotate (Polygon *poly, - gdouble theta) -{ - gint i; - gdouble ct, st; - gdouble ox, oy; - - ct = cos (theta); - st = sin (theta); - - for (i = 0; i < poly->npts; i++) - { - ox = poly->pts[i].x; - oy = poly->pts[i].y; - poly->pts[i].x = ct * ox - st * oy; - poly->pts[i].y = st * ox + ct * oy; - } -} - -static void -polygon_translate (Polygon *poly, - gdouble tx, - gdouble ty) -{ - gint i; - - for (i = 0; i < poly->npts; i++) - { - poly->pts[i].x += tx; - poly->pts[i].y += ty; - } -} - -static gint -polygon_extents (Polygon *poly, - gdouble *x1, - gdouble *y1, - gdouble *x2, - gdouble *y2) -{ - gint i; - - if (!poly->npts) - return 0; - - *x1 = *x2 = poly->pts[0].x; - *y1 = *y2 = poly->pts[0].y; - - for (i = 1; i < poly->npts; i++) - { - if (poly->pts[i].x < *x1) - *x1 = poly->pts[i].x; - if (poly->pts[i].x > *x2) - *x2 = poly->pts[i].x; - if (poly->pts[i].y < *y1) - *y1 = poly->pts[i].y; - if (poly->pts[i].y > *y2) - *y2 = poly->pts[i].y; - } - - return 1; -} - -static void -polygon_reset (Polygon *poly) -{ - poly->npts = 0; -} diff --git a/plug-ins/common/gimprc.common b/plug-ins/common/gimprc.common index e599d67719..265d26a496 100644 --- a/plug-ins/common/gimprc.common +++ b/plug-ins/common/gimprc.common @@ -27,7 +27,6 @@ contrast_stretch_RC = contrast-stretch.rc.o contrast_stretch_hsv_RC = contrast-stretch-hsv.rc.o convolution_matrix_RC = convolution-matrix.rc.o crop_zealous_RC = crop-zealous.rc.o -cubism_RC = cubism.rc.o curve_bend_RC = curve-bend.rc.o decompose_RC = decompose.rc.o deinterlace_RC = deinterlace.rc.o diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl index b02d721a5f..0b98271fc9 100644 --- a/plug-ins/common/plugin-defs.pl +++ b/plug-ins/common/plugin-defs.pl @@ -28,7 +28,6 @@ 'contrast-stretch-hsv' => {}, 'convolution-matrix' => { ui => 1 }, 'crop-zealous' => {}, - 'cubism' => { ui => 1 }, 'curve-bend' => { ui => 1 }, 'decompose' => { ui => 1 }, 'deinterlace' => { ui => 1 }, diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in index 411e9be2fb..86708ea6e4 100644 --- a/po-plug-ins/POTFILES.in +++ b/po-plug-ins/POTFILES.in @@ -35,7 +35,6 @@ plug-ins/common/contrast-stretch.c plug-ins/common/contrast-stretch-hsv.c plug-ins/common/convolution-matrix.c plug-ins/common/crop-zealous.c -plug-ins/common/cubism.c plug-ins/common/curve-bend.c plug-ins/common/decompose.c plug-ins/common/deinterlace.c diff --git a/tools/pdbgen/pdb/plug_in_compat.pdb b/tools/pdbgen/pdb/plug_in_compat.pdb index 20b799625b..375847593a 100644 --- a/tools/pdbgen/pdb/plug_in_compat.pdb +++ b/tools/pdbgen/pdb/plug_in_compat.pdb @@ -175,6 +175,75 @@ CODE ); } +sub plug_in_cubism { + $blurb = 'Convert the image into randomly rotated square blobs'; + + $help = <<'HELP'; +Convert the image into randomly rotated square blobs. +HELP + + &std_pdb_compat('gegl:cubism'); + $date = '2013'; + + @inargs = ( + { name => 'run_mode', type => 'enum GimpRunMode', dead => 1, + desc => 'The run mode' }, + { name => 'image', type => 'image', dead => 1, + desc => 'Input image (unused)' }, + { name => 'drawable', type => 'drawable', + desc => 'Input drawable' }, + { name => 'tile_size', type => '0.0 <= float <= 100.0', + desc => 'Average diameter of each tile (in pixels)' }, + { name => 'tile_saturation', type => '0.0 <= float <= 10.0', + desc => 'Expand tiles by this amount' }, + { name => 'bg_color', type => '0 <= int32 <= 1', + desc => 'Background color { BLACK (0), BG (1) }' } + ); + + %invoke = ( + code => <<'CODE' +{ + if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL, + GIMP_PDB_ITEM_CONTENT, error) && + gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error)) + { + GimpRGB color; + GeglColor *gegl_color; + GeglNode *node; + + if (bg_color) + { + gimp_context_get_background (context, &color); + gimp_rgb_set_alpha (&color, 0.0); + } + else + { + gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0); + } + + gegl_color = gimp_gegl_color_new (&color); + + node = gegl_node_new_child (NULL, + "operation", "gegl:cubism", + "tile-size", tile_size, + "tile-saturation", tile_saturation, + "bg-color", gegl_color, + NULL); + g_object_unref (gegl_color); + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Cubism"), + node); + + g_object_unref (node); + } + else + success = FALSE; +} +CODE + ); +} + sub plug_in_pixelize { $blurb = 'Simplify image into an array of solid-colored squares'; @@ -735,6 +804,7 @@ CODE @procs = qw(plug_in_autocrop plug_in_autocrop_layer plug_in_colortoalpha + plug_in_cubism plug_in_pixelize plug_in_pixelize2 plug_in_polar_coords