home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / common / threshold_alpha.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-24  |  8.2 KB  |  318 lines

  1. /* threshold_alpha.c -- This is a plug-in for the GIMP (1.0's API)
  2.  * Author: Shuji Narazaki <narazaki@InetQ.or.jp>
  3.  * Time-stamp: <2000-01-09 13:25:30 yasuhiro>
  4.  * Version: 0.13A (the 'A' is for Adam who hacked in greyscale
  5.  *                 support - don't know if there's a more recent official
  6.  *                 version)
  7.  *
  8.  * Copyright (C) 1997 Shuji Narazaki <narazaki@InetQ.or.jp>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  */
  24.  
  25. #include "config.h"
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29.  
  30. #include <gtk/gtk.h>
  31.  
  32. #include <libgimp/gimp.h>
  33. #include <libgimp/gimpui.h>
  34.  
  35. #include "libgimp/stdplugins-intl.h"
  36.  
  37.  
  38. #define    PLUG_IN_NAME        "plug_in_threshold_alpha"
  39. #define SHORT_NAME          "threshold_alpha"
  40. #define PROGRESS_UPDATE_NUM 100
  41. #define SCALE_WIDTH         120
  42.  
  43. static void query (void);
  44. static void run   (gchar      *name,
  45.            gint        nparams,
  46.            GimpParam  *param,
  47.            gint       *nreturn_vals,
  48.            GimpParam **return_vals);
  49.  
  50. static GimpPDBStatusType threshold_alpha             (gint32     drawable_id);
  51.  
  52. static gint              threshold_alpha_dialog      (void);
  53. static void              threshold_alpha_ok_callback (GtkWidget *widget,
  54.                               gpointer   data);
  55.  
  56. GimpPlugInInfo PLUG_IN_INFO =
  57. {
  58.   NULL,  /* init_proc  */
  59.   NULL,  /* quit_proc  */
  60.   query, /* query_proc */
  61.   run,   /* run_proc   */
  62. };
  63.  
  64. typedef struct
  65. {
  66.   gint    threshold;
  67. } ValueType;
  68.  
  69. static ValueType VALS = 
  70. {
  71.   127
  72. };
  73.  
  74. typedef struct 
  75. {
  76.   gint run;
  77. } Interface;
  78.  
  79. static Interface INTERFACE =
  80. {
  81.   FALSE
  82. };
  83.  
  84. MAIN ()
  85.  
  86. static void
  87. query (void)
  88. {
  89.   static GimpParamDef args [] =
  90.   {
  91.     { GIMP_PDB_INT32,    "run_mode",  "Interactive, non-interactive"},
  92.     { GIMP_PDB_IMAGE,    "image",     "Input image (not used)"},
  93.     { GIMP_PDB_DRAWABLE, "drawable",  "Input drawable" },
  94.     { GIMP_PDB_INT32,    "threshold", "Threshold" }
  95.   };
  96.   static gint nargs = sizeof (args) / sizeof (args[0]);
  97.  
  98.   gimp_install_procedure (PLUG_IN_NAME,
  99.               "",
  100.               "",
  101.               "Shuji Narazaki (narazaki@InetQ.or.jp)",
  102.               "Shuji Narazaki",
  103.               "1997",
  104.               N_("<Image>/Image/Alpha/Threshold Alpha..."),
  105.               "RGBA,GRAYA",
  106.               GIMP_PLUGIN,
  107.               nargs, 0,
  108.               args, NULL);
  109. }
  110.  
  111. static void
  112. run (gchar      *name,
  113.      gint        nparams,
  114.      GimpParam  *param,
  115.      gint       *nreturn_vals,
  116.      GimpParam **return_vals)
  117. {
  118.   static GimpParam   values[1];
  119.   GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
  120.   GimpRunModeType    run_mode;
  121.   gint               drawable_id;
  122.   
  123.   run_mode    = param[0].data.d_int32;
  124.   drawable_id = param[2].data.d_int32;
  125.  
  126.   if (run_mode != GIMP_RUN_INTERACTIVE)
  127.     {
  128.       INIT_I18N();
  129.     }
  130.   else
  131.     {
  132.       INIT_I18N_UI();
  133.     }
  134.  
  135.   *nreturn_vals = 1;
  136.   *return_vals = values;
  137.   
  138.   values[0].type = GIMP_PDB_STATUS;
  139.   values[0].data.d_status = status;
  140.  
  141.   switch (run_mode)
  142.     {
  143.     case GIMP_RUN_INTERACTIVE:
  144.       /* Since a channel might be selected, we must check wheter RGB or not. */
  145.       if (gimp_layer_get_preserve_transparency (drawable_id))
  146.     {
  147.       g_message (_("The layer preserves transparency."));
  148.       return;
  149.     }
  150.       if (!gimp_drawable_is_rgb (drawable_id) &&
  151.       !gimp_drawable_is_gray (drawable_id))
  152.     {
  153.       g_message (_("RGBA/GRAYA drawable is not selected."));
  154.       return;
  155.     }
  156.       gimp_get_data (PLUG_IN_NAME, &VALS);
  157.       if (! threshold_alpha_dialog ())
  158.     return;
  159.       break;
  160.  
  161.     case GIMP_RUN_NONINTERACTIVE:
  162.       if (nparams != 4)
  163.     {
  164.       status = GIMP_PDB_CALLING_ERROR;
  165.     }
  166.       else
  167.     {
  168.       VALS.threshold = param[3].data.d_int32;
  169.     } 
  170.       break;
  171.  
  172.     case GIMP_RUN_WITH_LAST_VALS:
  173.       gimp_get_data (PLUG_IN_NAME, &VALS);
  174.       break;
  175.     }
  176.   
  177.   if (status == GIMP_PDB_SUCCESS)
  178.     {
  179.       status = threshold_alpha (drawable_id);
  180.  
  181.       if (run_mode != GIMP_RUN_NONINTERACTIVE)
  182.     gimp_displays_flush ();
  183.       if (run_mode == GIMP_RUN_INTERACTIVE && status == GIMP_PDB_SUCCESS)
  184.     gimp_set_data (PLUG_IN_NAME, &VALS, sizeof (ValueType));
  185.     }
  186.  
  187.   values[0].type = GIMP_PDB_STATUS;
  188.   values[0].data.d_status = status;
  189. }
  190.  
  191. static GimpPDBStatusType
  192. threshold_alpha (gint32 drawable_id)
  193. {
  194.   GimpDrawable *drawable;
  195.   GimpPixelRgn  src_rgn, dest_rgn;
  196.   guchar       *src, *dest;
  197.   gpointer      pr;
  198.   gint          x, y, x1, x2, y1, y2;
  199.   gint          gap, total, processed = 0;
  200.   
  201.   drawable = gimp_drawable_get (drawable_id);
  202.   if (! gimp_drawable_has_alpha (drawable_id))
  203.     return GIMP_PDB_EXECUTION_ERROR;
  204.  
  205.   if (gimp_drawable_is_rgb (drawable_id))
  206.     gap = 3;
  207.   else
  208.     gap = 1;
  209.  
  210.   gimp_drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
  211.   total = (x2 - x1) * (y2 - y1);
  212.   if (total < 1)
  213.     return GIMP_PDB_EXECUTION_ERROR;
  214.  
  215.   gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
  216.   gimp_pixel_rgn_init (&src_rgn, drawable,
  217.                x1, y1, (x2 - x1), (y2 - y1), FALSE, FALSE);
  218.   gimp_pixel_rgn_init (&dest_rgn, drawable,
  219.                x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE);
  220.  
  221.   pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
  222.   gimp_progress_init (_("Threshold Alpha: Coloring Transparency..."));
  223.  
  224.   for (; pr != NULL; pr = gimp_pixel_rgns_process (pr))
  225.     {
  226.       gint offset, index;
  227.  
  228.       for (y = 0; y < src_rgn.h; y++)
  229.     {
  230.       src = src_rgn.data + y * src_rgn.rowstride;
  231.       dest = dest_rgn.data + y * dest_rgn.rowstride;
  232.       offset = 0;
  233.  
  234.       for (x = 0; x < src_rgn.w; x++)
  235.         {
  236.           for (index = 0; index < gap; index++)
  237.         *dest++ = *src++;
  238.           *dest++ = (VALS.threshold < *src++) ? 255 : 0;
  239.  
  240.           if ((++processed % (total / PROGRESS_UPDATE_NUM + 1)) == 0)
  241.         gimp_progress_update ((gdouble) processed /(gdouble) total); 
  242.         }
  243.     }
  244.   }
  245.  
  246.   gimp_progress_update (1.0);
  247.   gimp_drawable_flush (drawable);
  248.   gimp_drawable_merge_shadow (drawable->id, TRUE);
  249.   gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
  250.   gimp_drawable_detach (drawable);
  251.  
  252.   return GIMP_PDB_SUCCESS;
  253. }
  254.  
  255. /* dialog stuff */
  256. static gint
  257. threshold_alpha_dialog (void)
  258. {
  259.   GtkWidget *dlg;
  260.   GtkWidget *frame;
  261.   GtkWidget *table;
  262.   GtkObject *adj;
  263.  
  264.   gimp_ui_init ("threshold_alpha", FALSE);
  265.  
  266.   dlg = gimp_dialog_new (_("Threshold Alpha"), "threshold_alpha",
  267.              gimp_standard_help_func, "filters/threshold_alpha.html",
  268.              GTK_WIN_POS_MOUSE,
  269.              FALSE, TRUE, FALSE,
  270.  
  271.              _("OK"), threshold_alpha_ok_callback,
  272.              NULL, NULL, NULL, TRUE, FALSE,
  273.              _("Cancel"), gtk_widget_destroy,
  274.              NULL, 1, NULL, FALSE, TRUE,
  275.  
  276.              NULL);
  277.  
  278.   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
  279.               GTK_SIGNAL_FUNC (gtk_main_quit),
  280.               NULL);
  281.  
  282.   frame = gtk_frame_new (_("Parameter Settings"));
  283.   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
  284.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, FALSE, FALSE, 0);
  285.   gtk_widget_show (frame);
  286.  
  287.   table = gtk_table_new (1 ,3, FALSE);
  288.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  289.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  290.   gtk_container_add (GTK_CONTAINER (frame), table);
  291.   gtk_widget_show (table);
  292.  
  293.   adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
  294.                   _("Threshold:"), SCALE_WIDTH, 0,
  295.                   VALS.threshold, 0, 255, 1, 8, 0,
  296.                   TRUE, 0, 0,
  297.                   NULL, NULL);
  298.   gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
  299.               GTK_SIGNAL_FUNC (gimp_int_adjustment_update),
  300.               &VALS.threshold);
  301.  
  302.   gtk_widget_show (dlg);
  303.  
  304.   gtk_main ();
  305.   gdk_flush ();
  306.  
  307.   return INTERFACE.run;
  308. }
  309.  
  310. static void
  311. threshold_alpha_ok_callback (GtkWidget *widget,
  312.                  gpointer   data)
  313. {
  314.   INTERFACE.run = TRUE;
  315.  
  316.   gtk_widget_destroy (GTK_WIDGET (data));
  317. }
  318.