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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <gtk/gtk.h>
  6. #include "ppmtool.h"
  7. #include "gimpressionist.h"
  8. #include "gtk/gtk.h"
  9. #include "libgimp/gimp.h"
  10. #include "config.h"
  11. #include "libgimp/stdplugins-intl.h"
  12.  
  13. static void query(void);
  14. static void gimpressionist_main(void);
  15. static void run(char *, int, GimpParam *, int *, GimpParam **);
  16. void repaint(struct ppm *p, struct ppm *a);
  17.  
  18. int create_gimpressionist(void);
  19.  
  20. static gint img_width, img_height, img_bpp;
  21. gint img_has_alpha = 0;
  22. static gint sel_x1, sel_y1, sel_x2, sel_y2;
  23.  
  24. GimpPlugInInfo PLUG_IN_INFO = {
  25.         NULL,   /* init_proc */
  26.         NULL,   /* quit_proc */
  27.         query,  /* query_proc */
  28.         run     /* run_proc */
  29. }; /* PLUG_IN_INFO */
  30.  
  31. gimpressionist_vals_t pcvals;
  32.  
  33. gimpressionist_vals_t defaultpcvals = {
  34.   4,
  35.   0.0,
  36.   60.0,
  37.   0,
  38.   12.0,
  39.   20.0,
  40.   20.0,
  41.   1.0,
  42.   1,
  43.   0.1,
  44.   0.0,
  45.   30.0,
  46.   0,
  47.   0,
  48.   "defaultbrush.pgm",
  49.   "defaultpaper.pgm",
  50.   {0,0,0},
  51.   1,
  52.   0,
  53.   { { 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0 } },
  54.   1,
  55.   0,
  56.   0.0,
  57.   0.0,
  58.   1.0,
  59.   0,
  60.   0,
  61.   0,
  62.   0,
  63.   0,
  64.   20.0,
  65.   1,
  66.   10.0,
  67.   20.0,
  68.   0,
  69.   0.1,
  70.  
  71.   { { 0.5, 0.5, 50.0, 1.0 } },
  72.   1,
  73.   1.0,
  74.   0,
  75.  
  76.   10,
  77.   4,
  78.  
  79.   0, 0.0
  80. };
  81.  
  82. static GimpDrawable *drawable;
  83.  
  84. static void
  85. query(void)
  86. {
  87.   static GimpParamDef args[] = {
  88.     { GIMP_PDB_INT32,    "run_mode",  "Interactive" },
  89.     { GIMP_PDB_IMAGE,    "image",     "Input image" },
  90.     { GIMP_PDB_DRAWABLE, "drawable",  "Input drawable" },
  91.   }; /* args */
  92.  
  93.   static GimpParamDef *return_vals = NULL;
  94.   static int        nargs = sizeof(args) / sizeof(args[0]);
  95.   static int        nreturn_vals = 0;
  96.  
  97.   INIT_I18N();
  98.  
  99.   gimp_install_procedure(PLUG_IN_NAME,
  100.              "Performs various artistic operations on an image",
  101.              "Performs various artistic operations on an image",
  102.              "Vidar Madsen <vidar@prosalg.no>",
  103.              "Vidar Madsen",
  104.              PLUG_IN_VERSION,
  105.              N_("<Image>/Filters/Artistic/GIMPressionist..."),
  106.              "RGB*, GRAY*",
  107.              GIMP_PLUGIN,
  108.              nargs,
  109.              nreturn_vals,
  110.              args,
  111.              return_vals);
  112. } /* query */
  113.  
  114. static void
  115. gimpressionist_get_data(char *name, void *ptr)
  116. {
  117.   memcpy(&pcvals, &defaultpcvals, sizeof(pcvals));
  118.   gimp_get_data(name, ptr);
  119. }
  120.  
  121.  
  122. static void
  123. run(char *name, int nparams, GimpParam *param, int *nreturn_vals, GimpParam **return_vals)
  124. {
  125.   static GimpParam values[1];
  126.  
  127.   GimpRunModeType run_mode;
  128.   GimpPDBStatusType  status;
  129.  
  130.   status = GIMP_PDB_SUCCESS;
  131.   run_mode = param[0].data.d_int32;
  132.  
  133.   values[0].type = GIMP_PDB_STATUS;
  134.   values[0].data.d_status = status;
  135.  
  136.   *nreturn_vals = 1;
  137.   *return_vals = values;
  138.  
  139.   /* Get the active drawable info */
  140.  
  141.   drawable = gimp_drawable_get(param[2].data.d_drawable);
  142.   
  143.   img_width     = gimp_drawable_width(drawable->id);
  144.   img_height    = gimp_drawable_height(drawable->id);
  145.   img_bpp       = gimp_drawable_bpp(drawable->id);
  146.   img_has_alpha = gimp_drawable_has_alpha(drawable->id);
  147.  
  148.   gimp_drawable_mask_bounds(drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
  149.  
  150.   switch (run_mode) {
  151.   case GIMP_RUN_INTERACTIVE:
  152.     INIT_I18N_UI();
  153.     gimpressionist_get_data(PLUG_IN_NAME, &pcvals);
  154.     if(!create_gimpressionist())
  155.       return;
  156.     break;
  157.   case GIMP_RUN_NONINTERACTIVE:
  158.     INIT_I18N();
  159.     g_message("GIMPressionist: GIMP_RUN_NONINTERACTIVE not implemented yet!\n");
  160.     status = GIMP_PDB_EXECUTION_ERROR;
  161.     break;
  162.   case GIMP_RUN_WITH_LAST_VALS:
  163.     INIT_I18N_UI();
  164.     gimpressionist_get_data(PLUG_IN_NAME, &pcvals);
  165.     break;
  166.   default:
  167.     g_message("Huh?!\n");
  168.     status = GIMP_PDB_EXECUTION_ERROR;
  169.     break;
  170.   }
  171.   if((status == GIMP_PDB_SUCCESS) && (gimp_drawable_is_rgb(drawable->id) || gimp_drawable_is_gray(drawable->id))) {
  172.     gimpressionist_main();
  173.     gimp_displays_flush ();
  174.     
  175.     if (run_mode == GIMP_RUN_INTERACTIVE)
  176.       gimp_set_data(PLUG_IN_NAME, &pcvals, sizeof(gimpressionist_vals_t));
  177.     
  178.   } else if(status == GIMP_PDB_SUCCESS)
  179.     status = GIMP_PDB_EXECUTION_ERROR;
  180.  
  181.   values[0].data.d_status = status;
  182.   
  183.   gimp_drawable_detach(drawable);
  184. }
  185.  
  186. void grabarea(void)
  187. {
  188.   GimpPixelRgn src_rgn;
  189.   guchar *src_row;
  190.   guchar *src;
  191.   gint alpha, has_alpha, bpp;
  192.   gint x, y;
  193.   struct ppm *p;
  194.   gint x1, y1, x2, y2;
  195.   gint row, col;
  196.   int rowstride;
  197.  
  198.   if(standalone) {
  199.     loadppm(standalone, &infile);
  200.     return;
  201.   }
  202.  
  203.   gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
  204.  
  205.   bpp = gimp_drawable_bpp (drawable->id);
  206.   has_alpha = gimp_drawable_has_alpha (drawable->id);
  207.   alpha = (has_alpha) ? bpp - 1 : bpp;
  208.   
  209.   newppm(&infile, x2-x1, y2-y1);
  210.   p = &infile;
  211.   if(has_alpha) {
  212.     newppm(&inalpha, x2-x1, y2-y1);
  213.   }
  214.  
  215.   rowstride = p->width * 3;
  216.  
  217.   src_row = g_new (guchar, (x2 - x1) * bpp);
  218.  
  219.   gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, x2-x1, y2-y1, FALSE, FALSE);
  220.  
  221.   if(bpp == 3) { /* RGB */
  222.     int bpr = (x2-x1) * 3;
  223.     for(row = 0, y = y1; y < y2; row++, y++) {
  224.       gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
  225.       memcpy(p->col + row * rowstride, src_row, bpr);
  226.     }
  227.   } else if(bpp > 3) { /* RGBA */
  228.     for(row = 0, y = y1; y < y2; row++, y++) {
  229.       guchar *tmprow = p->col + row * rowstride;
  230.       guchar *tmparow = inalpha.col + row * rowstride;
  231.       gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
  232.       src = src_row;
  233.       for (col = 0, x = x1; x < x2; col++, x++) {
  234.     int k = col * 3;
  235.     tmprow[k+0] = src[0];
  236.     tmprow[k+1] = src[1];
  237.     tmprow[k+2] = src[2];
  238.     tmparow[k] = 255 - src[3];
  239.     src += src_rgn.bpp;
  240.       }
  241.     }
  242.   } else if(bpp == 2) { /* GrayA */
  243.     for(row = 0, y = y1; y < y2; row++, y++) {
  244.       guchar *tmprow = p->col + row * rowstride;
  245.       guchar *tmparow = inalpha.col + row * rowstride;
  246.       gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
  247.       src = src_row;
  248.       for (col = 0, x = x1; x < x2; col++, x++) {
  249.     int k = col * 3;
  250.     tmprow[k+0] = src[0];
  251.     tmprow[k+1] = src[0];
  252.     tmprow[k+2] = src[0];
  253.     tmparow[k] = 255 - src[1];
  254.     src += src_rgn.bpp;
  255.       }
  256.     }
  257.   } else { /* Gray */
  258.     for(row = 0, y = y1; y < y2; row++, y++) {
  259.       guchar *tmprow = p->col + row * rowstride;
  260.       gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
  261.       src = src_row;
  262.       for (col = 0, x = x1; x < x2; col++, x++) {
  263.     int k = col * 3;
  264.     tmprow[k+0] = src[0];
  265.     tmprow[k+1] = src[0];
  266.     tmprow[k+2] = src[0];
  267.     src += src_rgn.bpp;
  268.       }
  269.     }
  270.   }
  271.   g_free (src_row);
  272. }
  273.  
  274. void gimpressionist_main(void)
  275. {
  276.   GimpPixelRgn dest_rgn;
  277.   guchar *dest_row;
  278.   guchar *dest;
  279.   gint alpha, has_alpha, bpp;
  280.   gint x, y;
  281.   struct ppm *p;
  282.   gint x1, y1, x2, y2;
  283.   gint row, col;
  284.   int rowstride;
  285.  
  286.   gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
  287.  
  288.   bpp = gimp_drawable_bpp (drawable->id);
  289.   has_alpha = gimp_drawable_has_alpha (drawable->id);
  290.   alpha = (has_alpha) ? bpp - 1 : bpp;
  291.  
  292.   dest_row = g_new (guchar, (x2 - x1) * bpp);
  293.  
  294.   gimp_progress_init( _("Painting..."));
  295.  
  296.   if(!infile.col) {
  297.     grabarea();
  298.   }
  299.  
  300.   if(img_has_alpha)
  301.     repaint(&infile, &inalpha);
  302.   else
  303.     repaint(&infile, NULL);
  304.  
  305.   gimp_pixel_rgn_init (&dest_rgn, drawable, 0, 0, x2-x1, y2-y1, TRUE, TRUE);
  306.  
  307.   p = &infile;
  308.  
  309.   rowstride = p->width * 3;
  310.  
  311.   if(bpp == 3) {
  312.  
  313.     int bpr = (x2 - x1) * 3;
  314.  
  315.     for(row = 0, y = y1; y < y2; row++, y++) {
  316.       if(row % 10 == 0)
  317.     gimp_progress_update(0.8 + 0.2*((double)row / (y2-y1)));
  318.       memcpy(dest_row, p->col + row * rowstride, bpr);
  319.       gimp_pixel_rgn_set_row (&dest_rgn, dest_row, x1, y, (x2 - x1));
  320.     }
  321.  
  322.   } else if(bpp == 4) {
  323.  
  324.     for(row = 0, y = y1; y < y2; row++, y++) {
  325.       guchar *tmprow = p->col + row * rowstride;
  326.       if(row % 10 == 0)
  327.     gimp_progress_update(0.8 + 0.2*((double)row / (y2-y1)));
  328.       dest = dest_row;
  329.       for(col = 0, x = x1; x < x2; col++, x++) {
  330.     int k = col * 3;
  331.     dest[0] = tmprow[k+0];
  332.     dest[1] = tmprow[k+1];
  333.     dest[2] = tmprow[k+2];
  334.     dest[3] = 255 - inalpha.col[row * rowstride + k];
  335.     dest += dest_rgn.bpp;
  336.       }
  337.       gimp_pixel_rgn_set_row (&dest_rgn, dest_row, x1, y, (x2 - x1));
  338.     }
  339.  
  340.   } else if(bpp == 2) {
  341.  
  342.     for(row = 0, y = y1; y < y2; row++, y++) {
  343.       guchar *tmprow = p->col + row * rowstride;
  344.       if(row % 10 == 0)
  345.     gimp_progress_update(0.8 + 0.2*((double)row / (y2-y1)));
  346.       dest = dest_row;
  347.       for(col = 0, x = x1; x < x2; col++, x++) {
  348.     int k = col * 3;
  349.     dest[0] = (tmprow[k] + tmprow[k+1] + tmprow[k+2]) / 3;
  350.     dest[1] = 255 - inalpha.col[row*rowstride + k];
  351.     dest += dest_rgn.bpp;
  352.       }
  353.       gimp_pixel_rgn_set_row (&dest_rgn, dest_row, x1, y, (x2 - x1));
  354.     }
  355.  
  356.   } else {
  357.  
  358.  
  359.     for(row = 0, y = y1; y < y2; row++, y++) {
  360.       guchar *tmprow = p->col + row * rowstride;
  361.       if(row % 10 == 0)
  362.     gimp_progress_update(0.8 + 0.2*((double)row / (y2-y1)));
  363.       dest = dest_row;
  364.       for(col = 0, x = x1; x < x2; col++, x++) {
  365.     int k = col * 3;
  366.     dest[0] = (tmprow[k] + tmprow[k+1] + tmprow[k+2]) / 3;
  367.     dest += dest_rgn.bpp;
  368.       }
  369.       gimp_pixel_rgn_set_row (&dest_rgn, dest_row, x1, y, (x2 - x1));
  370.     }
  371.   }
  372.  
  373.   g_free (dest_row);
  374.  
  375.   gimp_drawable_flush (drawable);
  376.   gimp_drawable_merge_shadow (drawable->id, TRUE);
  377.   gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
  378. }
  379.