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

  1. /*
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This is a plug-in for the GIMP.
  5.  *
  6.  * Copyright (C) Pavel Grinfeld (pavel@ml.com)
  7.  *
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22.  */
  23.  
  24. #include "config.h"
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28.  
  29. #include <gtk/gtk.h>
  30.  
  31. #include <libgimp/gimp.h>
  32.  
  33. #include "fp.h"
  34.  
  35. #include "libgimp/stdplugins-intl.h"
  36.  
  37.  
  38. FP_Params Current =
  39. {
  40.   1,
  41.   .25,                /* Initial Roughness */
  42.   NULL,
  43.   .6,                 /* Initial Degree of Aliasing */
  44.   NULL,
  45.   80,
  46.   NULL,
  47.   MIDTONES,           /* Initial Range */
  48.   BY_VAL,             /* Initial God knows what */
  49.   TRUE,               /* Selection Only */
  50.   TRUE,               /* Real Time */
  51.   0,                  /* Offset */
  52.   0,
  53.   {32,224,255},
  54.   {0,0,0}
  55. };
  56.  
  57. GimpDrawable *drawable, *mask;
  58.  
  59. void      query  (void);
  60. void      run    (gchar     *name,
  61.           gint       nparams,
  62.           GimpParam    *param,
  63.           gint      *nreturn_vals,
  64.           GimpParam   **return_vals);
  65.  
  66. GimpPlugInInfo PLUG_IN_INFO =
  67. {
  68.   NULL,  /* init_proc  */
  69.   NULL,  /* quit_proc  */
  70.   query, /* query_proc */
  71.   run,   /* run_proc   */
  72. };
  73.  
  74. MAIN()
  75.  
  76. void
  77. query (void)
  78. {
  79.   GimpParamDef args[] =
  80.   {
  81.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  82.     { GIMP_PDB_IMAGE, "image", "Input image (used for indexed images)" },
  83.     { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
  84.   };
  85.   gint nargs = sizeof (args) / sizeof (args[0]);
  86.   
  87.   gimp_install_procedure ("plug_in_filter_pack",
  88.               "Allows the user to change H, S, or C with many previews",
  89.               "No help available",
  90.               "Pavel Grinfeld (pavel@ml.com)",
  91.               "Pavel Grinfeld (pavel@ml.com)",
  92.               "27th March 1997",
  93.               N_("<Image>/Image/Colors/Filter Pack..."),
  94.               "RGB*",
  95.               GIMP_PLUGIN,
  96.               nargs, 0,
  97.               args, NULL);
  98. }
  99.  
  100. /********************************STANDARD RUN*************************/
  101.  
  102. void
  103. run (gchar   *name,
  104.      gint     nparams,
  105.      GimpParam  *param,
  106.      gint    *nreturn_vals,
  107.      GimpParam **return_vals)
  108. {
  109.   GimpParam values[1];
  110.   GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  111.   
  112.   *nreturn_vals = 1;
  113.   *return_vals = values;
  114.  
  115.   INIT_I18N_UI(); 
  116.  
  117.   values[0].type = GIMP_PDB_STATUS;
  118.   values[0].data.d_status = status;
  119.  
  120.   initializeFilterPacks();
  121.  
  122.   drawable = gimp_drawable_get (param[2].data.d_drawable);
  123.   mask = gimp_drawable_get (gimp_image_get_selection (param[1].data.d_image));
  124.  
  125.   if (gimp_drawable_is_indexed (drawable->id) ||
  126.       gimp_drawable_is_gray (drawable->id) )
  127.     {
  128.       gimp_message (_("Convert the image to RGB first!"));
  129.       status = GIMP_PDB_EXECUTION_ERROR;
  130.     }
  131.   else if (gimp_drawable_is_rgb (drawable->id) && fp_dialog())
  132.     {
  133.       gimp_progress_init (_("Applying the Filter Pack...")); 
  134.       gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
  135.       fp (drawable);
  136.       gimp_displays_flush ();
  137.     }
  138.   else status = GIMP_PDB_EXECUTION_ERROR;
  139.   
  140.   
  141.   values[0].data.d_status = status;
  142.   if (status==GIMP_PDB_SUCCESS)
  143.     gimp_drawable_detach (drawable);
  144. }
  145.  
  146.  
  147. void
  148. fp_row (const guchar *src_row,
  149.     guchar       *dest_row,
  150.     gint         row,
  151.     gint         row_width,
  152.     gint         bytes)
  153. {
  154.   gint col, bytenum, k;
  155.   int JudgeBy, Intensity=0, P[3], backupP[3];
  156.   hsv H,S,V;
  157.   gint M, m, middle;
  158.  
  159.   for (col = 0; col < row_width ; col++)
  160.     {
  161.       
  162.       backupP[0] = P[0] = src_row[col*bytes+0];
  163.       backupP[0] = P[1] = src_row[col*bytes+1];
  164.       backupP[0] = P[2] = src_row[col*bytes+2];
  165.  
  166.       H = P[0]/255.0;
  167.       S = P[1]/255.0;
  168.       V = P[2]/255.0;
  169.       gimp_rgb_to_hsv_double(&H, &S, &V);
  170.       
  171.       for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++) {
  172.     if (!Current.Touched[JudgeBy]) continue;
  173.     
  174.     switch (JudgeBy) {
  175.     case BY_HUE:
  176.       Intensity=255*H;
  177.       break;
  178.     case BY_SAT:
  179.       Intensity=255*S;
  180.       break;
  181.     case BY_VAL:
  182.       Intensity=255*V;
  183.       break;
  184.     }
  185.  
  186.  
  187.     /* It's important to take care of Saturation first!!! */
  188.       
  189.       m = MIN(MIN(P[0],P[1]),P[2]);
  190.       M = MAX(MAX(P[0],P[1]),P[2]);
  191.       middle=(M+m)/2;
  192.  
  193.       for (k=0; k<3; k++)
  194.     if (P[k]!=m && P[k]!=M) middle=P[k];
  195.       
  196.     for (k=0; k<3; k++) 
  197.       if (M!=m) {
  198.         if (P[k] == M)
  199.           P[k] = MAX(P[k]+Current.satAdj[JudgeBy][Intensity],middle);
  200.         else if (P[k] == m)
  201.           P[k] = MIN(P[k]-Current.satAdj[JudgeBy][Intensity],middle); 
  202.       }
  203.  
  204.     
  205.     P[0] += Current.redAdj[JudgeBy][Intensity];
  206.     P[1] += Current.greenAdj[JudgeBy][Intensity];
  207.     P[2] += Current.blueAdj[JudgeBy][Intensity];
  208.        
  209.     P[0]  =  MAX(0,MIN(255, P[0]));
  210.     P[1]  =  MAX(0,MIN(255, P[1]));
  211.     P[2]  =  MAX(0,MIN(255, P[2]));
  212.       }
  213.       dest_row[col*bytes + 0] = P[0];
  214.       dest_row[col*bytes + 1] = P[1];
  215.       dest_row[col*bytes + 2] = P[2];
  216.       
  217.       if (bytes>3)
  218.     for (bytenum = 3; bytenum<bytes; bytenum++)
  219.       dest_row[col*bytes+bytenum] = src_row[col*bytes+bytenum];
  220.     }
  221. }
  222.  
  223.  
  224. void fp (GimpDrawable *drawable)
  225. {
  226.   GimpPixelRgn srcPR, destPR;
  227.   gint width, height;
  228.   gint bytes;
  229.   guchar *src_row, *dest_row;
  230.   gint row;
  231.   gint x1, y1, x2, y2;
  232.   
  233.   gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
  234.  
  235.   width = drawable->width;
  236.   height = drawable->height;
  237.   bytes = drawable->bpp;
  238.  
  239.   src_row = (guchar *) malloc ((x2 - x1) * bytes);
  240.   dest_row = (guchar *) malloc ((x2 - x1) * bytes);
  241.  
  242.   gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  243.   gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
  244.  
  245.   for (row = y1; row < y2; row++)
  246.     {
  247.       gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1));
  248.  
  249.       fp_row (src_row,
  250.           dest_row,
  251.           row,
  252.           (x2 - x1),
  253.           bytes
  254.           );
  255.  
  256.       gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1));
  257.       
  258.       if ((row % 10) == 0)
  259.     gimp_progress_update ((double) row / (double) (y2 - y1));
  260.     }
  261.  
  262.  
  263.   /*  update the processed region  */
  264.  
  265.   gimp_drawable_flush (drawable);
  266.   gimp_drawable_merge_shadow (drawable->id, TRUE);
  267.   gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
  268.   
  269.   free (src_row);
  270.   free (dest_row);
  271.  
  272. }
  273.