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

  1. /* $Id: handy.c,v 1.7 2000/08/23 10:23:07 neo Exp $
  2.  * These routines are useful for working with the GIMP and need not be
  3.  * specific to plug-in-maze.
  4.  *
  5.  * Kevin Turner <acapnotic@users.sourceforge.net>
  6.  * http://gimp-plug-ins.sourceforge.net/maze/
  7.  */
  8.  
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  *
  24.  */
  25.  
  26. #include <string.h>
  27.  
  28. #include "libgimp/gimp.h"
  29.  
  30. /* get_colors Returns the current foreground and background colors in
  31.    nice little arrays.  It works nicely for RGB and grayscale images,
  32.    however handling of indexed images is somewhat broken.  Patches
  33.    appreciated. */
  34. void      get_colors (GimpDrawable * drawable,
  35.               guint8 *fg,
  36.               guint8 *bg);
  37.  
  38. /* drawbox draws a solid colored box in a GimpPixelRgn, hopefully fairly
  39.    quickly.  See comments below. */
  40. void      drawbox (GimpPixelRgn *dest_rgn, 
  41.            guint x, 
  42.            guint y,
  43.            guint w,
  44.            guint h, 
  45.            guint8 clr[4]);
  46.  
  47.  
  48. void 
  49. get_colors (GimpDrawable *drawable, 
  50.         guint8    *fg, 
  51.         guint8    *bg) 
  52. {
  53.   switch ( gimp_drawable_type (drawable->id) )
  54.     {
  55.     case GIMP_RGBA_IMAGE:   /* ASSUMPTION: Assuming the user wants entire */
  56.       fg[3] = 255;                 /* area to be fully opaque.       */
  57.       bg[3] = 255;
  58.     case GIMP_RGB_IMAGE:
  59.       gimp_palette_get_foreground (&fg[0], &fg[1], &fg[2]);
  60.       gimp_palette_get_background (&bg[0], &bg[1], &bg[2]);
  61.       break;
  62.     case GIMP_GRAYA_IMAGE:       /* and again */
  63.       gimp_palette_get_foreground (&fg[0], &fg[1], &fg[2]);
  64.       gimp_palette_get_background (&bg[0], &bg[1], &bg[2]);
  65.       fg[0] = INTENSITY (fg[0], fg[1], fg[2]);
  66.       bg[0] = INTENSITY (bg[0], bg[1], bg[2]);
  67.       fg[1] = 255;
  68.       bg[1] = 255;
  69.       break;
  70.     case GIMP_GRAY_IMAGE:
  71.       gimp_palette_get_foreground (&fg[0], &fg[1], &fg[2]);
  72.       gimp_palette_get_background (&bg[0], &bg[1], &bg[2]);
  73.       fg[0] = INTENSITY (fg[0], fg[1], fg[2]);
  74.       bg[0] = INTENSITY (bg[0], bg[1], bg[2]);
  75.       break;
  76.     case GIMP_INDEXEDA_IMAGE:
  77.     case GIMP_INDEXED_IMAGE:     /* FIXME: Should use current fg/bg colors.  */
  78.     g_warning("maze: get_colors: Indexed image.  Using colors 15 and 0.\n");
  79.     fg[0] = 15;        /* As a plugin, I protest.  *I* shouldn't be the */
  80.     bg[0] = 0;       /* one who has to deal with this colormapcrap.   */
  81.     break;
  82.     default:
  83.       break;
  84.     }
  85. }
  86.  
  87. /* Draws a solid color box in a GimpPixelRgn. */
  88. /* Optimization assumptions:
  89.  * (Or, "Why Maze is Faster Than Checkerboard.")
  90.  * 
  91.  * Assuming calling memcpy is faster than using loops.
  92.  * Row buffers are nice...
  93.  *
  94.  * Assume allocating memory for row buffers takes a significant amount 
  95.  * of time.  Assume drawbox will be called many times.
  96.  * Only allocate memory once.
  97.  *
  98.  * Do not assume the row buffer will always be the same size.  Allow
  99.  * for reallocating to make it bigger if needed.  However, I don't see 
  100.  * reason to bother ever shrinking it again.
  101.  * (Under further investigation, assuming the row buffer never grows
  102.  * may be a safe assumption in this case.)
  103.  *
  104.  * Also assume that the program calling drawbox is short-lived, so
  105.  * memory leaks aren't of particular concern-- the memory allocated to 
  106.  * the row buffer is never set free.
  107.  */
  108.  
  109. /* Further optimizations that could be made...
  110.  *  Currently, the row buffer is re-filled with every call.  However,
  111.  *  plug-ins such as maze and checkerboard only use two colors, and
  112.  *  for the most part, have rows of the same size with every call.
  113.  *  We could keep a row of each color on hand so we wouldn't have to
  114.  *  re-fill it every time...  */
  115.  
  116. void 
  117. drawbox( GimpPixelRgn *dest_rgn, 
  118.      guint x, guint y, guint w, guint h, 
  119.      guint8 clr[4])
  120. {
  121.      const guint bpp=dest_rgn->bpp;
  122.      const guint x_min= x * bpp;
  123.  
  124.      /* x_max = dest_rgn->bpp * MIN(dest_rgn->w, (x + w)); */
  125.      /* rowsize = x_max - x_min */
  126.      const guint rowsize=bpp * MIN(dest_rgn->w, (x + w)) - x_min;
  127.   
  128.      /* The maximum [xy] value is that of the far end of the box, or
  129.       * the edge of the region, whichever comes first. */
  130.      const guint y_max= dest_rgn->rowstride * MIN(dest_rgn->h, (y + h));
  131.      
  132.      static guint8 *rowbuf;
  133.      static guint high_size=0; 
  134.      
  135.      guint xx, yy;
  136.      
  137.      /* Does the row buffer need to be (re)allocated? */
  138.      if (high_size == 0) {
  139.       rowbuf = g_new(guint8, rowsize);
  140.      } else if (rowsize > high_size) {
  141.       rowbuf = g_renew(guint8, rowbuf, rowsize);
  142.      }
  143.      
  144.      high_size = MAX(high_size, rowsize);
  145.      
  146.      /* Fill the row buffer with the color. */
  147.      for (xx= 0;
  148.       xx < rowsize;
  149.       xx+= bpp) {
  150.       memcpy (&rowbuf[xx], clr, bpp);
  151.      } /* next xx */
  152.      
  153.      /* Fill in the box in the region with rows... */
  154.      for (yy = dest_rgn->rowstride * y; 
  155.       yy < y_max; 
  156.       yy += dest_rgn->rowstride ) {
  157.       memcpy (&dest_rgn->data[yy+x_min], rowbuf, rowsize);
  158.      } /* next yy */
  159. }
  160.  
  161. /* Alternate ways of doing things if you don't like memcpy. */
  162. #if 0
  163.     for (xx= x * dest_rgn->bpp;
  164.          xx < bar;
  165.          xx+= dest_rgn->bpp) {
  166. #if 0
  167.         for (bp=0; bp < dest_rgn->bpp; bp++) {
  168.         dest_rgn->data[yy+xx+bp]=clr[bp];
  169.         } /* next bp */
  170. #else
  171.         memcpy (&dest_rgn->data[yy+xx], clr, dest_rgn->bpp);
  172. #endif
  173.     } /* next xx */
  174.     } /* next yy */
  175. }
  176. #endif 
  177.