diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c index ae47b35eb4..0c24e1e1d0 100644 --- a/app/pdb/internal-procs.c +++ b/app/pdb/internal-procs.c @@ -28,7 +28,7 @@ #include "internal-procs.h" -/* 729 procedures registered total */ +/* 730 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 ec26e651e5..a14ded9c27 100644 --- a/app/pdb/plug-in-compat-cmds.c +++ b/app/pdb/plug-in-compat-cmds.c @@ -702,6 +702,52 @@ plug_in_cubism_invoker (GimpProcedure *procedure, error ? *error : NULL); } +static GimpValueArray * +plug_in_deinterlace_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) +{ + gboolean success = TRUE; + GimpDrawable *drawable; + gint32 evenodd; + + drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp); + evenodd = g_value_get_int (gimp_value_array_index (args, 3)); + + 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)) + { + GeglNode *node; + + node = gegl_node_new_child (NULL, + "operation", "gegl:deinterlace", + "keep", evenodd ? 0 : 1, + "orientation", 0, /* HORIZONTAL */ + "size", 1, + NULL); + + node = wrap_in_gamma_cast (node, drawable); + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Deinterlace"), + node); + + g_object_unref (node); + } + else + success = FALSE; + } + + return gimp_procedure_get_return_values (procedure, success, + error ? *error : NULL); +} + static GimpValueArray * plug_in_gauss_invoker (GimpProcedure *procedure, Gimp *gimp, @@ -2799,6 +2845,48 @@ register_plug_in_compat_procs (GimpPDB *pdb) gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); + /* + * gimp-plug-in-deinterlace + */ + procedure = gimp_procedure_new (plug_in_deinterlace_invoker); + gimp_object_set_static_name (GIMP_OBJECT (procedure), + "plug-in-deinterlace"); + gimp_procedure_set_static_strings (procedure, + "plug-in-deinterlace", + "Fix images where every other row is missing", + "Deinterlace is useful for processing images from video capture cards. When only the odd or even fields get captured, deinterlace can be used to interpolate between the existing fields to correct this.", + "Compatibility procedure. Please see 'gegl:deinterlace' for credits.", + "Compatibility procedure. Please see 'gegl:deinterlace' for credits.", + "2014", + 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, + gimp_param_spec_int32 ("evenodd", + "evenodd", + "Which lines to keep { KEEP-ODD (0), KEEP-EVEN (1)", + 0, 1, 0, + GIMP_PARAM_READWRITE)); + gimp_pdb_register_procedure (pdb, procedure); + g_object_unref (procedure); + /* * gimp-plug-in-gauss */ diff --git a/plug-ins/common/.gitignore b/plug-ins/common/.gitignore index 1f2aad2176..29069b94b0 100644 --- a/plug-ins/common/.gitignore +++ b/plug-ins/common/.gitignore @@ -48,8 +48,6 @@ /curve-bend.exe /decompose /decompose.exe -/deinterlace -/deinterlace.exe /depth-merge /depth-merge.exe /despeckle diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am index d9363bee07..4e156b56b0 100644 --- a/plug-ins/common/Makefile.am +++ b/plug-ins/common/Makefile.am @@ -67,7 +67,6 @@ libexec_PROGRAMS = \ crop-zealous \ curve-bend \ decompose \ - deinterlace \ depth-merge \ despeckle \ destripe \ @@ -581,23 +580,6 @@ decompose_LDADD = \ $(INTLLIBS) \ $(decompose_RC) -deinterlace_SOURCES = \ - deinterlace.c - -deinterlace_LDADD = \ - $(libgimpui) \ - $(libgimpwidgets) \ - $(libgimpmodule) \ - $(libgimp) \ - $(libgimpmath) \ - $(libgimpconfig) \ - $(libgimpcolor) \ - $(libgimpbase) \ - $(GTK_LIBS) \ - $(RT_LIBS) \ - $(INTLLIBS) \ - $(deinterlace_RC) - depth_merge_SOURCES = \ depth-merge.c diff --git a/plug-ins/common/deinterlace.c b/plug-ins/common/deinterlace.c deleted file mode 100644 index 9753a48293..0000000000 --- a/plug-ins/common/deinterlace.c +++ /dev/null @@ -1,378 +0,0 @@ -/* Deinterlace 1.00 - image processing plug-in for GIMP - * - * Copyright (C) 1997 Andrew Kieschnick (andrewk@mail.utexas.edu) - * - * Original deinterlace for GIMP 0.54 API by Federico Mena Quintero - * - * Copyright (C) 1996 Federico Mena Quintero - * - * 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 . - */ - -#include "config.h" - -#include -#include - -#include "libgimp/stdplugins-intl.h" - - -#define PLUG_IN_PROC "plug-in-deinterlace" -#define PLUG_IN_BINARY "deinterlace" -#define PLUG_IN_ROLE "gimp-deinterlace" - - -enum -{ - ODD_FIELDS, - EVEN_FIELDS -}; - -typedef struct -{ - gint evenness; -} DeinterlaceValues; - - -/* 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 deinterlace (GimpDrawable *drawable, - GimpPreview *preview); - -static gboolean deinterlace_dialog (GimpDrawable *drawable); - - -const GimpPlugInInfo PLUG_IN_INFO = -{ - NULL, /* init_proc */ - NULL, /* quit_proc */ - query, /* query_proc */ - run, /* run_proc */ -}; - -static DeinterlaceValues devals = -{ - EVEN_FIELDS /* evenness */ -}; - -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 (unused)" }, - { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }, - { GIMP_PDB_INT32, "evenodd", "Which lines to keep { KEEP-ODD (0), KEEP-EVEN (1) }" } - }; - - gimp_install_procedure (PLUG_IN_PROC, - N_("Fix images where every other row is missing"), - "Deinterlace is useful for processing images from " - "video capture cards. When only the odd or even " - "fields get captured, deinterlace can be used to " - "interpolate between the existing fields to correct " - "this.", - "Andrew Kieschnick", - "Andrew Kieschnick", - "1997", - N_("_Deinterlace..."), - "RGB*, GRAY*", - GIMP_PLUGIN, - G_N_ELEMENTS (args), 0, - args, NULL); - - gimp_plugin_menu_register (PLUG_IN_PROC, "/Filters/Enhance"); -} - -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; - - run_mode = param[0].data.d_int32; - - INIT_I18N (); - - /* Get the specified drawable */ - drawable = gimp_drawable_get (param[2].data.d_drawable); - - switch (run_mode) - { - case GIMP_RUN_INTERACTIVE: - gimp_get_data (PLUG_IN_PROC, &devals); - if (! deinterlace_dialog (drawable)) - status = GIMP_PDB_EXECUTION_ERROR; - break; - - case GIMP_RUN_NONINTERACTIVE: - if (nparams != 4) - status = GIMP_PDB_CALLING_ERROR; - if (status == GIMP_PDB_SUCCESS) - devals.evenness = param[3].data.d_int32; - break; - - case GIMP_RUN_WITH_LAST_VALS: - gimp_get_data (PLUG_IN_PROC, &devals); - break; - - default: - break; - } - - if (status == GIMP_PDB_SUCCESS) - { - /* Make sure that the drawable is gray or RGB color */ - if (gimp_drawable_is_rgb (drawable->drawable_id) || - gimp_drawable_is_gray (drawable->drawable_id)) - { - gimp_progress_init (_("Deinterlace")); - gimp_tile_cache_ntiles (2 * (drawable->width / - gimp_tile_width () + 1)); - deinterlace (drawable, NULL); - - if (run_mode != GIMP_RUN_NONINTERACTIVE) - gimp_displays_flush (); - if (run_mode == GIMP_RUN_INTERACTIVE) - gimp_set_data (PLUG_IN_PROC, &devals, sizeof (DeinterlaceValues)); - } - else - { - status = GIMP_PDB_EXECUTION_ERROR; - } - } - *nreturn_vals = 1; - *return_vals = values; - - values[0].type = GIMP_PDB_STATUS; - values[0].data.d_status = status; - - gimp_drawable_detach (drawable); -} - -static void -deinterlace (GimpDrawable *drawable, - GimpPreview *preview) -{ - GimpPixelRgn srcPR, destPR; - gboolean has_alpha; - guchar *dest; - guchar *dest_buffer = NULL; - guchar *upper; - guchar *lower; - gint row, col; - gint x, y; - gint width, height; - gint bytes; - - bytes = drawable->bpp; - - if (preview) - { - gimp_preview_get_position (preview, &x, &y); - gimp_preview_get_size (preview, &width, &height); - - dest_buffer = g_new (guchar, width * height * bytes); - dest = dest_buffer; - } - else - { - if (! gimp_drawable_mask_intersect (drawable->drawable_id, - &x, &y, &width, &height)) - return; - - dest = g_new (guchar, width * bytes); - - gimp_pixel_rgn_init (&destPR, drawable, x, y, width, height, TRUE, TRUE); - } - - gimp_pixel_rgn_init (&srcPR, drawable, - x, MAX (y - 1, 0), - width, MIN (height + 1, drawable->height), - FALSE, FALSE); - - has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); - - /* allocate row buffers */ - upper = g_new (guchar, width * bytes); - lower = g_new (guchar, width * bytes); - - /* loop through the rows, performing our magic */ - for (row = y; row < y + height; row++) - { - gimp_pixel_rgn_get_row (&srcPR, dest, x, row, width); - - if (row % 2 != devals.evenness) - { - if (row > 0) - gimp_pixel_rgn_get_row (&srcPR, upper, x, row - 1, width); - else - gimp_pixel_rgn_get_row (&srcPR, upper, x, devals.evenness, width); - - if (row + 1 < drawable->height) - gimp_pixel_rgn_get_row (&srcPR, lower, x, row + 1, width); - else - gimp_pixel_rgn_get_row (&srcPR, lower, x, row - 1 + devals.evenness, - width); - - if (has_alpha) - { - const guchar *upix = upper; - const guchar *lpix = lower; - guchar *dpix = dest; - - for (col = 0; col < width; col++) - { - guint ualpha = upix[bytes - 1]; - guint lalpha = lpix[bytes - 1]; - guint alpha = ualpha + lalpha; - - if ((dpix[bytes - 1] = (alpha >> 1))) - { - gint b; - - for (b = 0; b < bytes - 1; b++) - dpix[b] = (upix[b] * ualpha + lpix[b] * lalpha) / alpha; - } - - upix += bytes; - lpix += bytes; - dpix += bytes; - } - } - else - { - for (col = 0; col < width * bytes; col++) - dest[col] = ((guint) upper[col] + (guint) lower[col]) / 2; - } - } - - if (preview) - { - dest += width * bytes; - } - else - { - gimp_pixel_rgn_set_row (&destPR, dest, x, row, width); - - if ((row % 20) == 0) - gimp_progress_update ((double) row / (double) (height)); - } - } - - if (preview) - { - gimp_preview_draw_buffer (preview, dest_buffer, width * bytes); - dest = dest_buffer; - } - else - { - gimp_progress_update (1.0); - /* update the deinterlaced region */ - gimp_drawable_flush (drawable); - gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); - gimp_drawable_update (drawable->drawable_id, x, y, width, height); - } - - g_free (lower); - g_free (upper); - g_free (dest); -} - -static gboolean -deinterlace_dialog (GimpDrawable *drawable) -{ - GtkWidget *dialog; - GtkWidget *main_vbox; - GtkWidget *preview; - GtkWidget *frame; - GtkWidget *odd; - GtkWidget *even; - gboolean run; - - gimp_ui_init (PLUG_IN_BINARY, FALSE); - - dialog = gimp_dialog_new (_("Deinterlace"), 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, NULL); - gtk_box_pack_start (GTK_BOX (main_vbox), preview, TRUE, TRUE, 0); - gtk_widget_show (preview); - g_signal_connect_swapped (preview, "invalidated", - G_CALLBACK (deinterlace), - drawable); - - frame = gimp_int_radio_group_new (FALSE, NULL, - G_CALLBACK (gimp_radio_button_update), - &devals.evenness, devals.evenness, - - _("Keep o_dd fields"), ODD_FIELDS, &odd, - _("Keep _even fields"), EVEN_FIELDS, &even, - - NULL); - - g_signal_connect_swapped (odd, "toggled", - G_CALLBACK (gimp_preview_invalidate), - preview); - g_signal_connect_swapped (even, "toggled", - G_CALLBACK (gimp_preview_invalidate), - preview); - - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - gtk_widget_show (dialog); - - run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK); - - gtk_widget_destroy (dialog); - - return run; -} diff --git a/plug-ins/common/gimprc.common b/plug-ins/common/gimprc.common index 801047d136..203d9990f1 100644 --- a/plug-ins/common/gimprc.common +++ b/plug-ins/common/gimprc.common @@ -21,7 +21,6 @@ convolution_matrix_RC = convolution-matrix.rc.o crop_zealous_RC = crop-zealous.rc.o curve_bend_RC = curve-bend.rc.o decompose_RC = decompose.rc.o -deinterlace_RC = deinterlace.rc.o depth_merge_RC = depth-merge.rc.o despeckle_RC = despeckle.rc.o destripe_RC = destripe.rc.o diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl index c55ecda49a..8f10de7238 100644 --- a/plug-ins/common/plugin-defs.pl +++ b/plug-ins/common/plugin-defs.pl @@ -22,7 +22,6 @@ 'crop-zealous' => {}, 'curve-bend' => { ui => 1 }, 'decompose' => { ui => 1, gegl => 1 }, - 'deinterlace' => { ui => 1 }, 'depth-merge' => { ui => 1 }, 'despeckle' => { ui => 1 }, 'destripe' => { ui => 1 }, diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in index e61f5a19a3..6d1cb04267 100644 --- a/po-plug-ins/POTFILES.in +++ b/po-plug-ins/POTFILES.in @@ -29,7 +29,6 @@ plug-ins/common/convolution-matrix.c plug-ins/common/crop-zealous.c plug-ins/common/curve-bend.c plug-ins/common/decompose.c -plug-ins/common/deinterlace.c plug-ins/common/depth-merge.c plug-ins/common/despeckle.c plug-ins/common/destripe.c diff --git a/tools/pdbgen/pdb/plug_in_compat.pdb b/tools/pdbgen/pdb/plug_in_compat.pdb index 11aae37ab3..bface97f3e 100644 --- a/tools/pdbgen/pdb/plug_in_compat.pdb +++ b/tools/pdbgen/pdb/plug_in_compat.pdb @@ -651,6 +651,60 @@ CODE ); } +sub plug_in_deinterlace { + $blurb = 'Fix images where every other row is missing'; + + $help = <<'HELP'; +Deinterlace is useful for processing images from video capture +cards. When only the odd or even fields get captured, deinterlace can +be used to interpolate between the existing fields to correct this. +HELP + + &std_pdb_compat('gegl:deinterlace'); + $date = '2014'; + + @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 => 'evenodd', type => '0 <= int32 <= 1', + desc => 'Which lines to keep { KEEP-ODD (0), KEEP-EVEN (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)) + { + GeglNode *node; + + node = gegl_node_new_child (NULL, + "operation", "gegl:deinterlace", + "keep", evenodd ? 0 : 1, + "orientation", 0, /* HORIZONTAL */ + "size", 1, + NULL); + + node = wrap_in_gamma_cast (node, drawable); + + gimp_drawable_apply_operation (drawable, progress, + C_("undo-type", "Deinterlace"), + node); + + g_object_unref (node); + } + else + success = FALSE; +} +CODE + ); +} + sub plug_in_gauss { $blurb = 'Simplest, most commonly used way of blurring'; @@ -2522,6 +2576,7 @@ CODE plug_in_colors_channel_mixer plug_in_colortoalpha plug_in_cubism + plug_in_deinterlace plug_in_gauss plug_in_gauss_iir plug_in_gauss_iir2