home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / brush_scale.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-21  |  6.8 KB  |  345 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include <glib.h>
  20. #include "brush_scale.h"
  21.  
  22.  
  23. MaskBuf *
  24. brush_scale_mask (MaskBuf *brush_mask,
  25.           int      dest_width, 
  26.           int      dest_height)
  27. {
  28.   MaskBuf *scale_brush;
  29.   int src_width;
  30.   int src_height;
  31.   int value;
  32.   int area;
  33.   int i, j;
  34.   int x, x0, y, y0;
  35.   int dx, dx0, dy, dy0;
  36.   int fx, fx0, fy, fy0;
  37.   unsigned char *src, *dest;
  38.  
  39.   g_return_val_if_fail (brush_mask != NULL &&
  40.             dest_width != 0 && dest_height != 0, NULL);
  41.  
  42.   src_width  = brush_mask->width;
  43.   src_height = brush_mask->height;
  44.  
  45.   scale_brush = mask_buf_new (dest_width, dest_height);
  46.   g_return_val_if_fail (scale_brush != NULL, NULL);
  47.  
  48.   /*  get the data  */
  49.   dest = mask_buf_data (scale_brush);
  50.   src  = mask_buf_data (brush_mask);
  51.  
  52.   fx = fx0 = (256.0 * src_width) / dest_width;
  53.   fy = fy0 = (256.0 * src_height) / dest_height;
  54.   area = fx0 * fy0;
  55.  
  56.   x = x0 = 0;
  57.   y = y0 = 0;
  58.   dx = dx0 = 0;
  59.   dy = dy0 = 0;
  60.  
  61.   for (i=0; i<dest_height; i++)
  62.     {
  63.       for (j=0; j<dest_width; j++)
  64.     {
  65.       value  = 0;
  66.  
  67.       fy = fy0;
  68.       y  = y0;
  69.       dy = dy0;
  70.        
  71.       if (dy)
  72.         {
  73.           fx = fx0;
  74.           x  = x0;
  75.           dx = dx0;
  76.           
  77.           if (dx)
  78.         {
  79.           value += dx * dy * src[x + src_width * y]; 
  80.           x++;
  81.           fx -= dx;
  82.           dx = 0;
  83.         }
  84.           while (fx >= 256)
  85.         {
  86.           value += 256 * dy * src[x + src_width * y];  
  87.           x++;
  88.           fx -= 256;
  89.         }
  90.           if (fx)
  91.         {
  92.           value += fx * dy * src[x + src_width * y];
  93.           dx = 256 - fx;
  94.         }          
  95.           y++;
  96.           fy -= dy;
  97.           dy = 0;
  98.         }  
  99.       
  100.       while (fy >= 256)
  101.         {
  102.           fx = fx0;
  103.           x  = x0;
  104.           dx = dx0;
  105.           
  106.           if (dx)
  107.         {
  108.           value += dx * 256 * src[x + src_width * y]; 
  109.           x++;
  110.           fx -= dx;
  111.           dx = 0;
  112.         }
  113.           while (fx >= 256)
  114.         {
  115.           value += 256 * 256 * src[x + src_width * y];  
  116.           x++;
  117.           fx -= 256;
  118.         }
  119.           if (fx)
  120.         {
  121.           value += fx * 256 * src[x + src_width * y];
  122.           dx = 256 - fx;
  123.         }
  124.           y++;
  125.           fy -= 256;
  126.         }
  127.       
  128.       if (fy)
  129.         {
  130.           fx = fx0;
  131.           x  = x0;
  132.           dx = dx0;
  133.           
  134.           if (dx)
  135.         {
  136.           value += dx * fy * src[x + src_width * y]; 
  137.           x++;
  138.           fx -= dx;
  139.           dx = 0;
  140.         }
  141.           while (fx >= 256)
  142.         {
  143.           value += 256 * fy * src[x + src_width * y];  
  144.           x++;
  145.           fx -= 256;
  146.         }
  147.           if (fx)
  148.         {
  149.           value += fx * fy * src[x + src_width * y];
  150.           dx = 256 - fx;
  151.         }
  152.           dy = 256 - fy;
  153.         }        
  154.       
  155.       *dest++ = MIN ((value / area), 255);
  156.     
  157.       x0  = x;
  158.       dx0 = dx;
  159.     }
  160.       x0  = 0;
  161.       dx0 = 0;
  162.       y0  = y;
  163.       dy0 = dy;
  164.     }
  165.  
  166.   return scale_brush;
  167. }
  168.  
  169.  
  170. #define ADD_RGB(dest, factor, src) \
  171.   dest[0] += factor * src[0]; \
  172.   dest[1] += factor * src[1]; \
  173.   dest[2] += factor * src[2];
  174.  
  175. MaskBuf *
  176. brush_scale_pixmap (MaskBuf *pixmap,
  177.             int      dest_width, 
  178.             int      dest_height)
  179. {
  180.   MaskBuf *scale_brush;
  181.   int src_width;
  182.   int src_height;
  183.   int value[3];
  184.   int factor;
  185.   int area;
  186.   int i, j;
  187.   int x, x0, y, y0;
  188.   int dx, dx0, dy, dy0;
  189.   int fx, fx0, fy, fy0;
  190.   unsigned char *src, *src_ptr, *dest;
  191.  
  192.   g_return_val_if_fail (pixmap != NULL && pixmap->bytes == 3 &&
  193.             dest_width != 0 && dest_height != 0, NULL);
  194.  
  195.   src_width  = pixmap->width;
  196.   src_height = pixmap->height;
  197.  
  198.   scale_brush = temp_buf_new (dest_width, dest_height, 3, 0, 0, NULL);
  199.   g_return_val_if_fail (scale_brush != NULL, NULL);
  200.  
  201.   /*  get the data  */
  202.   dest = mask_buf_data (scale_brush);
  203.   src  = mask_buf_data (pixmap);
  204.  
  205.   fx = fx0 = (256.0 * src_width) / dest_width;
  206.   fy = fy0 = (256.0 * src_height) / dest_height;
  207.   area = fx0 * fy0;
  208.  
  209.   x = x0 = 0;
  210.   y = y0 = 0;
  211.   dx = dx0 = 0;
  212.   dy = dy0 = 0;
  213.  
  214.   for (i=0; i<dest_height; i++)
  215.     {
  216.       for (j=0; j<dest_width; j++)
  217.     {
  218.       value[0] = 0;
  219.       value[1] = 0;
  220.       value[2] = 0;
  221.  
  222.       fy = fy0;
  223.       y  = y0;
  224.       dy = dy0;
  225.        
  226.       if (dy)
  227.         {
  228.           fx = fx0;
  229.           x  = x0;
  230.           dx = dx0;
  231.           
  232.           if (dx)
  233.         {
  234.           factor = dx * dy;
  235.           src_ptr = src + 3 * (x + y * src_width);
  236.           ADD_RGB (value, factor, src_ptr);
  237.           x++;
  238.           fx -= dx;
  239.           dx = 0;
  240.         }
  241.           while (fx >= 256)
  242.         {
  243.           factor = 256 * dy;
  244.           src_ptr = src + 3 * (x + y * src_width);
  245.           ADD_RGB (value, factor, src_ptr);
  246.           x++;
  247.           fx -= 256;
  248.         }
  249.           if (fx)
  250.         {
  251.           factor = fx * dy;
  252.           src_ptr = src + 3 * (x + y * src_width);
  253.           ADD_RGB (value, factor, src_ptr);
  254.           dx = 256 - fx;
  255.         }          
  256.           y++;
  257.           fy -= dy;
  258.           dy = 0;
  259.         }  
  260.       
  261.       while (fy >= 256)
  262.         {
  263.           fx = fx0;
  264.           x  = x0;
  265.           dx = dx0;
  266.           
  267.           if (dx)
  268.         {
  269.           factor = dx * 256;
  270.           src_ptr = src + 3 * (x + y * src_width);
  271.           ADD_RGB (value, factor, src_ptr);
  272.           x++;
  273.           fx -= dx;
  274.           dx = 0;
  275.         }
  276.           while (fx >= 256)
  277.         {
  278.           factor = 256 * 256;
  279.           src_ptr = src + 3 * (x + y * src_width);
  280.           ADD_RGB (value, factor, src_ptr);
  281.           x++;
  282.           fx -= 256;
  283.         }
  284.           if (fx)
  285.         {
  286.           factor = fx * 256;
  287.           src_ptr = src + 3 * (x + y * src_width);
  288.           ADD_RGB (value, factor, src_ptr);
  289.           dx = 256 - fx;
  290.         }
  291.           y++;
  292.           fy -= 256;
  293.         }
  294.       
  295.       if (fy)
  296.         {
  297.           fx = fx0;
  298.           x  = x0;
  299.           dx = dx0;
  300.           
  301.           if (dx)
  302.         {
  303.           factor = dx * fy;
  304.           src_ptr = src + 3 * (x + y * src_width);
  305.           ADD_RGB (value, factor, src_ptr);
  306.           x++;
  307.           fx -= dx;
  308.           dx = 0;
  309.         }
  310.           while (fx >= 256)
  311.         {
  312.           factor = 256 * fy;
  313.           src_ptr = src + 3 * (x + y * src_width);
  314.           ADD_RGB (value, factor, src_ptr);
  315.           x++;
  316.           fx -= 256;
  317.         }
  318.           if (fx)
  319.         {
  320.           factor = fx * fy;
  321.           src_ptr = src + 3 * (x + y * src_width);
  322.           ADD_RGB (value, factor, src_ptr);
  323.           dx = 256 - fx;
  324.         }
  325.           dy = 256 - fy;
  326.         }        
  327.       
  328.       *dest++ = MIN ((value[0] / area), 255);
  329.       *dest++ = MIN ((value[1] / area), 255);
  330.       *dest++ = MIN ((value[2] / area), 255);
  331.     
  332.       x0  = x;
  333.       dx0 = dx;
  334.     }
  335.       x0  = 0;
  336.       dx0 = 0;
  337.       y0  = y;
  338.       dy0 = dy;
  339.     }
  340.  
  341.   return scale_brush;
  342. }
  343.  
  344. #undef ADD_RGB
  345.