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

  1. /*
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This is a plug-in for the GIMP.
  5.  *
  6.  * Colormap-Rotation plug-in. Exchanges two color ranges.
  7.  *
  8.  * Copyright (C) 1999 Sven Anders (anderss@fmi.uni-passau.de)
  9.  *                    Based on code from Pavel Grinfeld (pavel@ml.com)
  10.  *
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25.  */
  26.  
  27. /*-----------------------------------------------------------------------------------
  28.  * Change log:
  29.  * 
  30.  * Version 2.0, 04 April 1999.
  31.  *  Nearly complete rewrite, made plug-in stable.
  32.  *  (Works with GIMP 1.1 and GTK+ 1.2)
  33.  *
  34.  * Version 1.0, 27 March 1997.
  35.  *  Initial (unstable) release by Pavel Grinfeld
  36.  *
  37.  *-----------------------------------------------------------------------------------*/
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <math.h>
  42.  
  43. #include "config.h"
  44. #include <gtk/gtk.h>
  45. #include "libgimp/gimp.h"
  46. #include "libgimp/stdplugins-intl.h"
  47.  
  48. #include "rcm.h"
  49. #include "rcm_misc.h"
  50. #include "rcm_dialog.h"
  51. #include "rcm_callback.h"
  52.  
  53. /*-----------------------------------------------------------------------------------*/
  54. /* Forward declarations */
  55. /*-----------------------------------------------------------------------------------*/
  56.  
  57. void query (void);
  58. void run   (char *name, int nparams, GimpParam *param, int *nreturn_vals, GimpParam **return_vals);
  59.  
  60. /*-----------------------------------------------------------------------------------*/
  61. /* Global variables */
  62. /*-----------------------------------------------------------------------------------*/
  63.  
  64. RcmParams Current =
  65. {
  66.   SELECTION,           /* SELECTION ONLY */
  67.   TRUE,                /* REAL TIME */
  68.   FALSE,               /* SUCCESS */
  69.   RADIANS_OVER_PI,     /* START IN RADIANS OVER PI */
  70.   GRAY_TO
  71. };
  72.  
  73. /*-----------------------------------------------------------------------------------*/
  74. /* Local variables */
  75. /*-----------------------------------------------------------------------------------*/
  76.  
  77. GimpPlugInInfo PLUG_IN_INFO =
  78. {
  79.   NULL,    /* init_proc */
  80.   NULL,    /* quit_proc */
  81.   query,   /* query_proc */
  82.   run,     /* run_proc */
  83. };
  84.  
  85. /*-----------------------------------------------------------------------------------*/
  86. /* Dummy function */
  87. /*-----------------------------------------------------------------------------------*/
  88.  
  89. MAIN()
  90.  
  91. /*-----------------------------------------------------------------------------------*/
  92. /* Query plug-in */
  93. /*-----------------------------------------------------------------------------------*/
  94.  
  95. void 
  96. query (void)
  97. {
  98.   GimpParamDef args[] =
  99.   {
  100.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  101.     { GIMP_PDB_IMAGE, "image", "Input image (used for indexed images)" },
  102.     { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
  103.   };
  104.  
  105.   GimpParamDef *return_vals = NULL;
  106.   int nargs = sizeof (args) / sizeof (args[0]);
  107.   int nreturn_vals = 0;
  108.  
  109.   INIT_I18N();
  110.   gimp_install_procedure ("plug-in-rotate-colormap",
  111.               "Colormap rotation as in xv",
  112.               "Exchanges two color ranges. "
  113.                 "Based on code from Pavel Grinfeld (pavel@ml.com). "
  114.                 "This version written by Sven Anders (anderss@fmi.uni-passau.de).",
  115.               "Sven Anders (anderss@fmi.uni-passau.de) and Pavel Grinfeld (pavel@ml.com)",
  116.               "Sven Anders (anderss@fmi.uni-passau.de)",
  117.               "04th April 1999",
  118.               N_("<Image>/Image/Colors/Colormap Rotation..."),
  119.               "RGB*",
  120.               GIMP_PLUGIN,
  121.               nargs, nreturn_vals,
  122.               args, return_vals);
  123. }
  124.  
  125. /*-----------------------------------------------------------------------------------*/
  126. /* Rotate colormap of a single row */
  127. /*-----------------------------------------------------------------------------------*/
  128.  
  129. void 
  130. rcm_row (const guchar *src_row, 
  131.      guchar       *dest_row,
  132.      gint          row, 
  133.      gint          row_width, 
  134.      gint          bytes)
  135. {
  136.   gint col, bytenum, skip;
  137.   gdouble H,S,V;
  138.   guchar rgb[3];
  139.   
  140.   for (col=0; col < row_width; col++)
  141.   {
  142.     skip = 0;
  143.       
  144.     rgb[0] = src_row[col*bytes + 0];
  145.     rgb[1] = src_row[col*bytes + 1];
  146.     rgb[2] = src_row[col*bytes + 2];
  147.       
  148.     gimp_rgb_to_hsv4 (rgb, &H, &S, &V);
  149.       
  150.     if (rcm_is_gray(S))
  151.     {
  152.       if (Current.Gray_to_from == GRAY_FROM)
  153.       {
  154.     if (rcm_angle_inside_slice(Current.Gray->hue,Current.From->angle) <= 1)
  155.     {
  156.       H = Current.Gray->hue / TP;
  157.       S = Current.Gray->satur;
  158.     }
  159.     else 
  160.     {
  161.       skip = 1;
  162.     }
  163.       }
  164.       else
  165.       {
  166.     skip = 1;
  167.     gimp_hsv_to_rgb4 (rgb, Current.Gray->hue/TP, Current.Gray->satur, V);
  168.       }
  169.     }
  170.       
  171.     if (!skip)
  172.     {
  173.       H = rcm_linear(rcm_left_end(Current.From->angle),
  174.              rcm_right_end(Current.From->angle),
  175.              rcm_left_end(Current.To->angle),
  176.              rcm_right_end(Current.To->angle),
  177.              H*TP);    
  178.  
  179.       H = angle_mod_2PI(H) / TP;
  180.       gimp_hsv_to_rgb4 (rgb, H, S, V);
  181.     }
  182.       
  183.     dest_row[col * bytes + 0] = rgb[0];
  184.     dest_row[col * bytes + 1] = rgb[1];
  185.     dest_row[col * bytes + 2] = rgb[2];
  186.       
  187.     if (bytes > 3)
  188.     {
  189.       for (bytenum=3; bytenum<bytes; bytenum++)
  190.     dest_row[col*bytes+bytenum] = src_row[col*bytes+bytenum];
  191.     }
  192.   }
  193. }
  194.  
  195. /*-----------------------------------------------------------------------------------*/
  196. /* Rotate colormap row by row ... */
  197. /*-----------------------------------------------------------------------------------*/
  198.  
  199. void 
  200. rcm (GimpDrawable *drawable)
  201. {
  202.   GimpPixelRgn srcPR, destPR;
  203.   gint width, height;
  204.   gint bytes;
  205.   guchar *src_row, *dest_row;
  206.   gint row;
  207.   gint x1, y1, x2, y2;
  208.   
  209.   gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
  210.  
  211.   width = drawable->width;
  212.   height = drawable->height;
  213.   bytes = drawable->bpp;
  214.  
  215.   src_row = (guchar *) malloc ((x2 - x1) * bytes);
  216.   dest_row = (guchar *) malloc ((x2 - x1) * bytes);
  217.  
  218.   gimp_pixel_rgn_init(&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  219.   gimp_pixel_rgn_init(&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
  220.  
  221.   for (row=y1; row < y2; row++)
  222.   {
  223.     gimp_pixel_rgn_get_row(&srcPR, src_row, x1, row, (x2 - x1));
  224.  
  225.     rcm_row(src_row, dest_row, row, (x2 - x1), bytes);
  226.       
  227.     gimp_pixel_rgn_set_row(&destPR, dest_row, x1, row, (x2 - x1));
  228.       
  229.     if ((row % 10) == 0)
  230.       gimp_progress_update((double) row / (double) (y2 - y1));
  231.   }
  232.  
  233.   /*  update the processed region  */
  234.  
  235.   gimp_drawable_flush(drawable);
  236.   gimp_drawable_merge_shadow(drawable->id, TRUE);
  237.   gimp_drawable_update(drawable->id, x1, y1, (x2 - x1), (y2 - y1));
  238.   
  239.   free (src_row);
  240.   free (dest_row);
  241. }
  242.  
  243. /*-----------------------------------------------------------------------------------*/
  244. /* STANDARD RUN */
  245. /*-----------------------------------------------------------------------------------*/
  246.  
  247. void 
  248. run (char    *name, 
  249.      int      nparams, 
  250.      GimpParam  *param, 
  251.      int     *nreturn_vals, 
  252.      GimpParam **return_vals)
  253. {
  254.   GimpParam values[1];
  255.   GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  256.   
  257.   *nreturn_vals = 1;
  258.   *return_vals = values;
  259.  
  260.   values[0].type = GIMP_PDB_STATUS;
  261.   values[0].data.d_status = status;
  262.  
  263.   Current.drawable = gimp_drawable_get(param[2].data.d_drawable);
  264.   Current.mask = gimp_drawable_get(gimp_image_get_selection(param[1].data.d_image));
  265.  
  266.   /* works not on INDEXED images */     
  267.  
  268.   if (gimp_drawable_is_indexed (Current.drawable->id) ||
  269.       gimp_drawable_is_gray (Current.drawable->id) )
  270.   {
  271.     status = GIMP_PDB_EXECUTION_ERROR;
  272.   }
  273.   else
  274.   {
  275.     /* call dialog and rotate the colormap */
  276.  
  277.     INIT_I18N_UI(); 
  278.  
  279.     if (gimp_drawable_is_rgb(Current.drawable->id) && rcm_dialog())
  280.     {
  281.       gimp_progress_init(_("Rotating the colormap..."));
  282.  
  283.       gimp_tile_cache_ntiles(2 * (Current.drawable->width / gimp_tile_width() + 1));
  284.       rcm(Current.drawable);
  285.       gimp_displays_flush();
  286.     }
  287.     else
  288.       status = GIMP_PDB_EXECUTION_ERROR;
  289.   }
  290.   
  291.   values[0].data.d_status = status;
  292.   if (status == GIMP_PDB_SUCCESS)
  293.     gimp_drawable_detach(Current.drawable);
  294. }
  295.