home *** CD-ROM | disk | FTP | other *** search
/ ftp.sunet.sepub/pictures / 2014.11.ftp.sunet.se-pictures.tar / ftp.sunet.se / pub / pictures / ACiD-artpacks / programs / unix / editors / gimp-plugins-unstable-0_99_23_tar.gz / gimp-plugins-unstable-0_99_23_tar / gimp-plugins-unstable-0.99.23 / fp / fp.c < prev    next >
C/C++ Source or Header  |  1998-02-19  |  7KB  |  288 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "gtk/gtk.h"
  4. #include "libgimp/gimp.h"
  5. #include "fp.h"
  6. #include "fp_hsv.h"
  7.  
  8. FP_Params Current =
  9. {
  10.   1,
  11.   .25,                /* Initial Roughness */
  12.   NULL,
  13.   .6,                 /* Initial Degree of Aliasing */
  14.   NULL,
  15.   60,
  16.   NULL,
  17.   MIDTONES,           /* Initial Range */
  18.   BY_VAL,             /* Initial God knows what */
  19.   TRUE,               /* Selection Only */
  20.   TRUE,               /* Real Time */
  21.   0,                  /* Offset */
  22.   HUE|VALUE,
  23.   {32,224,255},
  24.   {0,0,0}
  25. };
  26.  
  27. GDrawable *drawable, *mask;
  28.  
  29. void      query  (void);
  30. void      run    (char      *name,
  31.           int        nparams,
  32.           GParam    *param,
  33.           int       *nreturn_vals,
  34.           GParam   **return_vals);
  35.  
  36. GPlugInInfo PLUG_IN_INFO =
  37. {
  38.   NULL,    /* init_proc */
  39.   NULL,    /* quit_proc */
  40.   query,   /* query_proc */
  41.   run,     /* run_proc */
  42. };
  43.  
  44.  
  45.  
  46. MAIN()
  47.  
  48.  
  49. void
  50. query ()
  51. {
  52.   GParamDef args[] =
  53.   {
  54.     { PARAM_INT32, "run_mode", "Interactive, non-interactive" },
  55.     { PARAM_IMAGE, "image", "Input image (used for indexed images)" },
  56.     { PARAM_DRAWABLE, "drawable", "Input drawable" },
  57.   };
  58.    GParamDef *return_vals = NULL;
  59.    int nargs = sizeof (args) / sizeof (args[0]);
  60.    int nreturn_vals = 0;
  61.  
  62.   gimp_install_procedure ("plug_in_filter_pack",
  63.               "Allows the user to change H, S, or C with many previews",
  64.               "Then something else here",
  65.               "Pavel Grinfeld (pavel@ml.com)",
  66.               "Pavel Grinfeld (pavel@ml.com)",
  67.               "27th March 1997",
  68.               "<Image>/Filters/Colors/Filter Pack",
  69.               "RGB*,INDEXED*,GRAY*",
  70.               PROC_PLUG_IN,
  71.               nargs, nreturn_vals,
  72.               args, return_vals);
  73. }
  74.  
  75. /********************************STANDARD RUN*************************/
  76. void
  77. run (char    *name,
  78.      int      nparams,
  79.      GParam  *param,
  80.      int     *nreturn_vals,
  81.      GParam **return_vals)
  82. {
  83.   GParam values[1];
  84.   GStatusType status = STATUS_SUCCESS;
  85.  
  86.   *nreturn_vals = 1;
  87.   *return_vals = values;
  88.  
  89.   values[0].type = PARAM_STATUS;
  90.   values[0].data.d_status = status;
  91.  
  92.   initializeFilterPacks();
  93.  
  94.   drawable = gimp_drawable_get (param[2].data.d_drawable);
  95.   mask=gimp_drawable_get(gimp_image_get_selection(param[1].data.d_image));
  96.  
  97.   if (gimp_drawable_indexed (drawable->id) ||gimp_drawable_gray (drawable->id) ) {
  98.     ErrorMessage("Convert the image to RGB first!");
  99.     status = STATUS_EXECUTION_ERROR;
  100.   }
  101.  
  102.   else if (gimp_drawable_color (drawable->id) && fp_dialog())
  103.     {
  104.       gimp_progress_init ("Applying the Filter Pack...");
  105.       gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
  106.       fp (drawable);
  107.       gimp_displays_flush ();
  108.     }
  109.   else status = STATUS_EXECUTION_ERROR;
  110.  
  111.  
  112.   values[0].data.d_status = status;
  113.   if (status==STATUS_SUCCESS)
  114.     gimp_drawable_detach (drawable);
  115. }
  116.  
  117.  
  118. void
  119. fp_row (const guchar *src_row,
  120.     guchar       *dest_row,
  121.     gint         row,
  122.     gint         row_width,
  123.     gint         bytes)
  124. {
  125.   gint col, bytenum, k;
  126.   int JudgeBy, Intensity, P[3], backupP[3];
  127.   hsv H,S,V;
  128.   gint M, m, middle;
  129.  
  130.   /* initialize */
  131.  
  132.   Intensity = 0;
  133.  
  134.   for (col = 0; col < row_width ; col++)
  135.     {
  136.  
  137.       backupP[0] = P[0] = src_row[col*bytes+0];
  138.       backupP[0] = P[1] = src_row[col*bytes+1];
  139.       backupP[0] = P[2] = src_row[col*bytes+2];
  140.  
  141.  
  142.       rgb_to_hsv(P[0]/255.0, P[1]/255.0, P[2]/255.0, &H, &S, &V);
  143.  
  144.       for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++) {
  145.     if (!Current.Touched[JudgeBy]) continue;
  146.  
  147.     switch (JudgeBy) {
  148.     case BY_HUE:
  149.       Intensity=255*H;
  150.       break;
  151.     case BY_SAT:
  152.       Intensity=255*S;
  153.       break;
  154.     case BY_VAL:
  155.       Intensity=255*V;
  156.       break;
  157.     }
  158.  
  159.  
  160.     /* It's important to take care of Saturation first!!! */
  161.  
  162.       m = MIN(MIN(P[0],P[1]),P[2]);
  163.       M = MAX(MAX(P[0],P[1]),P[2]);
  164.       middle=(M+m)/2;
  165.  
  166.       for (k=0; k<3; k++)
  167.     if (P[k]!=m && P[k]!=M) middle=P[k];
  168.  
  169.     for (k=0; k<3; k++)
  170.       if (M!=m)
  171.         if (P[k] == M)
  172.           P[k] = MAX(P[k]+Current.satAdj[JudgeBy][Intensity],middle);
  173.         else if (P[k] == m)
  174.           P[k] = MIN(P[k]-Current.satAdj[JudgeBy][Intensity],middle);
  175.  
  176.  
  177.  
  178.     P[0] += Current.redAdj[JudgeBy][Intensity];
  179.     P[1] += Current.greenAdj[JudgeBy][Intensity];
  180.     P[2] += Current.blueAdj[JudgeBy][Intensity];
  181.  
  182.     P[0]  =  MAX(0,MIN(255, P[0]));
  183.     P[1]  =  MAX(0,MIN(255, P[1]));
  184.     P[2]  =  MAX(0,MIN(255, P[2]));
  185.       }
  186.       dest_row[col*bytes + 0] = P[0];
  187.       dest_row[col*bytes + 1] = P[1];
  188.       dest_row[col*bytes + 2] = P[2];
  189.  
  190.       if (bytes>3)
  191.     for (bytenum = 3; bytenum<bytes; bytenum++)
  192.       dest_row[col*bytes+bytenum] = src_row[col*bytes+bytenum];
  193.     }
  194. }
  195.  
  196.  
  197. void fp (GDrawable *drawable)
  198. {
  199.   GPixelRgn srcPR, destPR;
  200.   gint width, height;
  201.   gint bytes;
  202.   guchar *src_row, *dest_row;
  203.   gint row;
  204.   gint x1, y1, x2, y2;
  205.  
  206.   gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
  207.  
  208.   width = drawable->width;
  209.   height = drawable->height;
  210.   bytes = drawable->bpp;
  211.  
  212.   src_row = (guchar *) malloc ((x2 - x1) * bytes);
  213.   dest_row = (guchar *) malloc ((x2 - x1) * bytes);
  214.  
  215.   gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  216.   gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
  217.  
  218.   for (row = y1; row < y2; row++)
  219.     {
  220.       gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1));
  221.  
  222.       fp_row (src_row,
  223.           dest_row,
  224.           row,
  225.           (x2 - x1),
  226.           bytes
  227.           );
  228.  
  229.       gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1));
  230.  
  231.       if ((row % 10) == 0)
  232.     gimp_progress_update ((double) row / (double) (y2 - y1));
  233.     }
  234.  
  235.  
  236.   /*  update the processed region  */
  237.  
  238.   gimp_drawable_flush (drawable);
  239.   gimp_drawable_merge_shadow (drawable->id, TRUE);
  240.   gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
  241.  
  242.   free (src_row);
  243.   free (dest_row);
  244.  
  245. }
  246.  
  247.  
  248. void
  249. ErrorMessage(guchar *message)
  250. {
  251.   GtkWidget *window, *label, *button,*table;
  252.   gchar **argv=g_new (gchar *, 1);
  253.   gint argc=1;
  254.   argv[0] = g_strdup ("fp");
  255.   gtk_init (&argc, &argv);
  256.   gtk_rc_parse (gimp_gtkrc ());
  257.  
  258.   window=gtk_dialog_new();
  259.   gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
  260.   gtk_window_set_title(GTK_WINDOW(window),"Filter Pack Simulation Message");
  261.   gtk_signal_connect (GTK_OBJECT (window), "destroy",
  262.               (GtkSignalFunc) fp_close_callback,
  263.               NULL);
  264.  
  265.   button = gtk_button_new_with_label ("Got It!");
  266.   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
  267.   gtk_signal_connect (GTK_OBJECT (button), "clicked",
  268.                       (GtkSignalFunc) fp_ok_callback,
  269.                       window);
  270.   gtk_widget_grab_default (button);
  271.   gtk_widget_show (button);
  272.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
  273.  
  274.   table=gtk_table_new(2,2,FALSE);
  275.   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),table,TRUE,TRUE,0);
  276.   gtk_widget_show(table);
  277.  
  278.   label=gtk_label_new("");
  279.   gtk_label_set(GTK_LABEL(label),message);
  280.   gtk_widget_show(label);
  281.   gtk_table_attach(GTK_TABLE(table),label,0,1,0,1,
  282.            GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,15,15);
  283.  
  284.   gtk_widget_show(window);
  285.   gtk_main ();
  286.  
  287. }
  288.