home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / paint_funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  135.1 KB  |  5,953 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 "config.h"
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. #include <glib.h>
  26.  
  27. #include "apptypes.h"
  28.  
  29. #include "appenv.h"
  30. #include "gimprc.h"
  31. #include "paint_funcs.h"
  32. #include "boundary.h"
  33. #include "tile_manager.h"
  34.  
  35. #include "tile_manager_pvt.h"  /* For copy-on-write */
  36. #include "tile_pvt.h"  /* For accessing the tiles directly */
  37. #include "tile.h"            /* ick. */
  38.  
  39. #include "libgimp/gimpintl.h"
  40. #include "libgimp/gimpmath.h"
  41. #include "libgimp/gimpcolorspace.h"
  42.  
  43. #define STD_BUF_SIZE       1021
  44. #define MAXDIFF            195076
  45. #define HASH_TABLE_SIZE    1021
  46. #define RANDOM_TABLE_SIZE  4096
  47. #define RANDOM_SEED        314159265
  48. #define EPSILON            0.0001
  49.  
  50. #define INT_MULT(a,b,t)  ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
  51.  
  52. /* This version of INT_MULT3 is very fast, but suffers from some
  53.    slight roundoff errors.  It returns the correct result 99.987
  54.    percent of the time */
  55. #define INT_MULT3(a,b,c,t)  ((t) = (a) * (b) * (c)+ 0x7F5B, \
  56.                             ((((t) >> 7) + (t)) >> 16))
  57. /*
  58.   This version of INT_MULT3 always gives the correct result, but runs at
  59.   approximatly one third the speed. */
  60. /*  #define INT_MULT3(a,b,c,t) (((a) * (b) * (c)+ 32512) / 65025.0)
  61.  */
  62.  
  63. #define INT_BLEND(a,b,alpha,tmp)  (INT_MULT((a)-(b), alpha, tmp) + (b))
  64.  
  65. typedef enum
  66. {
  67.   MinifyX_MinifyY,
  68.   MinifyX_MagnifyY,
  69.   MagnifyX_MinifyY,
  70.   MagnifyX_MagnifyY
  71. } ScaleType;
  72.  
  73. /*  Layer modes information  */
  74. typedef struct _LayerMode LayerMode;
  75. struct _LayerMode
  76. {
  77.   int affect_alpha;     /*  does the layer mode affect the alpha channel  */
  78.   int increase_opacity; /*  layer mode can increase opacity */
  79.   int decrease_opacity; /*  layer mode can decrease opacity */
  80.   char *name;           /*  layer mode specification  */
  81. };
  82.  
  83. LayerMode layer_modes[] =    /* This must obviously be in the same
  84.                  * order as the corresponding values
  85.                  * in the LayerModeEffects enumeration.
  86.                  */
  87. {
  88.   { 1, 1, 0, N_("Normal") },
  89.   { 1, 1, 0, N_("Dissolve") },
  90.   { 1, 1, 0, N_("Behind") },
  91.   { 0, 0, 0, N_("Multiply (Burn)") },
  92.   { 0, 0, 0, N_("Screen") },
  93.   { 0, 0, 0, N_("Overlay") },
  94.   { 0, 0, 0, N_("Difference") },
  95.   { 0, 0, 0, N_("Addition") },
  96.   { 0, 0, 0, N_("Subtraction") },
  97.   { 0, 0, 0, N_("Darken Only") },
  98.   { 0, 0, 0, N_("Lighten Only") },
  99.   { 0, 0, 0, N_("Hue") },
  100.   { 0, 0, 0, N_("Saturation") },
  101.   { 0, 0, 0, N_("Color") },
  102.   { 0, 0, 0, N_("Value") },
  103.   { 0, 0, 0, N_("Divide (Dodge)") },
  104.   { 1, 0, 1, N_("Erase") },
  105.   { 1, 1, 1, N_("Replace") },
  106.   { 1, 0, 1, N_("Anti Erase") }
  107. };
  108.  
  109. /*  ColorHash structure  */
  110. typedef struct _ColorHash ColorHash;
  111.  
  112. struct _ColorHash
  113. {
  114.   int pixel;           /*  R << 16 | G << 8 | B  */
  115.   int index;           /*  colormap index        */
  116.   GimpImage* gimage;     
  117. };
  118.  
  119. static ColorHash color_hash_table [HASH_TABLE_SIZE];
  120. static int random_table [RANDOM_TABLE_SIZE];
  121. static int color_hash_misses;
  122. static int color_hash_hits;
  123. static unsigned char * tmp_buffer;  /* temporary buffer available upon request */
  124. static int tmp_buffer_size;
  125. static unsigned char no_mask = OPAQUE_OPACITY;
  126. static int add_lut[256][256];
  127.  
  128. /*******************************/
  129. /*  Local function prototypes  */
  130. static int *  make_curve         (double, int *);
  131. static void   run_length_encode  (unsigned char *, int *, int, int);
  132. static double cubic              (double, int, int, int, int);
  133. static void   apply_layer_mode_replace (unsigned char *, unsigned char *,
  134.                     unsigned char *, unsigned char *,
  135.                     int, int, int,
  136.                     int, int, int, int *);
  137. static void   rotate_pointers    (void **p, guint32 n);
  138.  
  139.  
  140. void
  141. update_tile_rowhints (Tile *tile, 
  142.               int   ymin, 
  143.               int   ymax)
  144. {
  145.   int bpp, ewidth;
  146.   int x,y;
  147.   guchar* ptr;
  148.   guchar alpha;
  149.   TileRowHint thishint;
  150.  
  151. #ifdef HINTS_SANITY
  152.   g_assert(tile!=NULL);
  153. #endif
  154.  
  155.   tile_sanitize_rowhints (tile);
  156.  
  157.   bpp = tile_bpp (tile);
  158.   ewidth = tile->ewidth;
  159.  
  160.   if (bpp == 1 || bpp == 3)
  161.     {
  162.       for (y=ymin; y<=ymax; y++)
  163.     tile_set_rowhint (tile, y, TILEROWHINT_OPAQUE);
  164.  
  165.       return;
  166.     }
  167.  
  168.   if (bpp == 4)
  169.     {
  170. #ifdef HINTS_SANITY
  171.       g_assert(tile!=NULL);
  172. #endif
  173.  
  174.       ptr = tile_data_pointer (tile, 0, ymin);
  175.  
  176. #ifdef HINTS_SANITY
  177.       g_assert(ptr!=NULL);
  178. #endif
  179.  
  180.       for (y = ymin; y <= ymax; y++)
  181.     {
  182.       thishint = tile_get_rowhint (tile, y);
  183.  
  184. #ifdef HINTS_SANITY
  185.       if (thishint==TILEROWHINT_BROKEN)
  186.         g_error("BROKEN y=%d",y);
  187.       if (thishint==TILEROWHINT_OUTOFRANGE)
  188.         g_error("OOR y=%d",y);
  189.       if (thishint==TILEROWHINT_UNDEFINED)
  190.         g_error("UNDEFINED y=%d - bpp=%d ew=%d eh=%d",
  191.             y,bpp,ewidth,eheight);
  192. #endif
  193.  
  194. #ifdef HINTS_SANITY
  195.       if (thishint == TILEROWHINT_TRANSPARENT ||
  196.           thishint == TILEROWHINT_MIXED ||
  197.           thishint == TILEROWHINT_OPAQUE)
  198.         {
  199.           goto next_row4;
  200.         }
  201.  
  202.       if (thishint != TILEROWHINT_UNKNOWN)
  203.         {
  204.           g_error("MEGABOGUS y=%d - bpp=%d ew=%d eh=%d",
  205.               y,bpp,ewidth,eheight);
  206.         }
  207. #endif
  208.  
  209.       if (thishint == TILEROWHINT_UNKNOWN)
  210.         {
  211.           alpha = ptr[3];
  212.  
  213.           /* row is all-opaque or all-transparent? */
  214.           if (alpha == 0 || alpha == 255)
  215.         {
  216.           if (ewidth > 1)
  217.             {
  218.               for (x = 1; x < ewidth; x++)
  219.             {
  220.               if (ptr[x*4 + 3] != alpha)
  221.                 {
  222.                   tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  223.                   goto next_row4;
  224.                 }
  225.             }
  226.             }
  227.           tile_set_rowhint (tile, y,
  228.                     (alpha == 0) ?
  229.                     TILEROWHINT_TRANSPARENT :
  230.                     TILEROWHINT_OPAQUE);
  231.         }
  232.           else
  233.         {
  234.           tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  235.         }
  236.         }
  237.  
  238.     next_row4:
  239.       ptr += 4 * ewidth;
  240.     }
  241.       
  242.       return;
  243.     }
  244.  
  245.   if (bpp == 2)
  246.     {
  247. #ifdef HINTS_SANITY
  248.       g_assert(tile!=NULL);
  249. #endif
  250.  
  251.       ptr = tile_data_pointer (tile, 0, ymin);
  252.  
  253. #ifdef HINTS_SANITY
  254.       g_assert(ptr!=NULL);
  255. #endif
  256.  
  257.       for (y = ymin; y <= ymax; y++)
  258.     {
  259.       thishint = tile_get_rowhint (tile, y);
  260.  
  261. #ifdef HINTS_SANITY
  262.       if (thishint==TILEROWHINT_BROKEN)
  263.         g_error("BROKEN y=%d",y);
  264.       if (thishint==TILEROWHINT_OUTOFRANGE)
  265.         g_error("OOR y=%d",y);
  266.       if (thishint==TILEROWHINT_UNDEFINED)
  267.         g_error("UNDEFINED y=%d - bpp=%d ew=%d eh=%d",
  268.             y,bpp,ewidth,eheight);
  269. #endif
  270.  
  271. #ifdef HINTS_SANITY
  272.       if (thishint == TILEROWHINT_TRANSPARENT ||
  273.           thishint == TILEROWHINT_MIXED ||
  274.           thishint == TILEROWHINT_OPAQUE)
  275.         {
  276.           goto next_row2;
  277.         }
  278.  
  279.       if (thishint != TILEROWHINT_UNKNOWN)
  280.         {
  281.           g_error("MEGABOGUS y=%d - bpp=%d ew=%d eh=%d",
  282.               y,bpp,ewidth,eheight);
  283.         }
  284. #endif
  285.  
  286.       if (thishint == TILEROWHINT_UNKNOWN)
  287.         {
  288.           alpha = ptr[1];
  289.  
  290.           /* row is all-opaque or all-transparent? */
  291.           if (alpha == 0 || alpha == 255)
  292.         {
  293.           if (ewidth > 1)
  294.             {
  295.               for (x = 1; x < ewidth; x++)
  296.             {
  297.               if (ptr[x*2 + 1] != alpha)
  298.                 {
  299.                   tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  300.                   goto next_row2;
  301.                 }
  302.             }
  303.             }
  304.           tile_set_rowhint (tile, y,
  305.                     (alpha == 0) ?
  306.                     TILEROWHINT_TRANSPARENT :
  307.                     TILEROWHINT_OPAQUE);
  308.         }
  309.           else
  310.         {
  311.           tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  312.         }
  313.         }
  314.  
  315.     next_row2:
  316.       ptr += 2 * ewidth;
  317.     }
  318.       
  319.       return;
  320.     }
  321.  
  322.   g_warning ("update_tile_rowhints: Don't know about tiles with bpp==%d", bpp);
  323. }
  324.  
  325.  
  326. static unsigned char *
  327. paint_funcs_get_buffer (int size)
  328. {
  329.   if (size > tmp_buffer_size)
  330.     {
  331.       tmp_buffer_size = size;
  332.       tmp_buffer = (unsigned char *) g_realloc (tmp_buffer, size);
  333.     }
  334.  
  335.   return tmp_buffer;
  336. }
  337.  
  338.  
  339. /*
  340.  * The equations: g(r) = exp (- r^2 / (2 * sigma^2))
  341.  *                   r = sqrt (x^2 + y ^2)
  342.  */
  343.  
  344. static int *
  345. make_curve (double  sigma,
  346.         int    *length)
  347. {
  348.   int *curve;
  349.   double sigma2;
  350.   double l;
  351.   int temp;
  352.   int i, n;
  353.  
  354.   sigma2 = 2 * sigma * sigma;
  355.   l = sqrt (-sigma2 * log (1.0 / 255.0));
  356.  
  357.   n = ceil (l) * 2;
  358.   if ((n % 2) == 0)
  359.     n += 1;
  360.  
  361.   curve = g_malloc (sizeof (int) * n);
  362.  
  363.   *length = n / 2;
  364.   curve += *length;
  365.   curve[0] = 255;
  366.  
  367.   for (i = 1; i <= *length; i++)
  368.     {
  369.       temp = (int) (exp (- (i * i) / sigma2) * 255);
  370.       curve[-i] = temp;
  371.       curve[i] = temp;
  372.     }
  373.  
  374.   return curve;
  375. }
  376.  
  377.  
  378. static void
  379. run_length_encode (unsigned char *src,
  380.            int           *dest,
  381.            int            w,
  382.            int            bytes)
  383. {
  384.   int start;
  385.   int i;
  386.   int j;
  387.   unsigned char last;
  388.  
  389.   last = *src;
  390.   src += bytes;
  391.   start = 0;
  392.  
  393.   for (i = 1; i < w; i++)
  394.     {
  395.       if (*src != last)
  396.     {
  397.       for (j = start; j < i; j++)
  398.         {
  399.           *dest++ = (i - j);
  400.           *dest++ = last;
  401.         }
  402.       start = i;
  403.       last = *src;
  404.     }
  405.       src += bytes;
  406.     }
  407.  
  408.   for (j = start; j < i; j++)
  409.     {
  410.       *dest++ = (i - j);
  411.       *dest++ = last;
  412.     }
  413. }
  414.  
  415. /* Note: cubic function no longer clips result */
  416. static inline double
  417. cubic (double dx,
  418.        int    jm1,
  419.        int    j,
  420.        int    jp1,
  421.        int    jp2)
  422. {
  423.  
  424.   /* Catmull-Rom - not bad */
  425.   return (double) ((( ( - jm1 + 3 * j - 3 * jp1 + jp2 ) * dx +
  426.           ( 2 * jm1 - 5 * j + 4 * jp1 - jp2 ) ) * dx +
  427.           ( - jm1 + jp1 ) ) * dx + (j + j) ) / 2.0;
  428. }
  429.  
  430. /*********************/
  431. /*  FUNCTIONS        */
  432. /*********************/
  433.  
  434. void
  435. paint_funcs_setup ()
  436. {
  437.   int i;
  438.   int j,k;
  439.   int tmp_sum;
  440.  
  441.   /*  allocate the temporary buffer  */
  442.   tmp_buffer = (unsigned char *) g_malloc (STD_BUF_SIZE);
  443.   tmp_buffer_size = STD_BUF_SIZE;
  444.  
  445.   /*  initialize the color hash table--invalidate all entries  */
  446.   for (i = 0; i < HASH_TABLE_SIZE; i++)
  447.     color_hash_table[i].gimage = NULL;
  448.   color_hash_misses = 0;
  449.   color_hash_hits = 0;
  450.  
  451.   /*  generate a table of random seeds  */
  452.   srand (RANDOM_SEED);
  453.  
  454.   /* FIXME: Why creating an array of random values and shuffle it randomly
  455.    * afterwards??? 
  456.    */
  457.   
  458.   for (i = 0; i < RANDOM_TABLE_SIZE; i++)
  459.     random_table[i] = rand ();
  460.  
  461.   for (i = 0; i < RANDOM_TABLE_SIZE; i++)
  462.     {
  463.       int tmp;
  464.       int swap = i + rand () % (RANDOM_TABLE_SIZE - i);
  465.       tmp = random_table[i];
  466.       random_table[i] = random_table[swap];
  467.       random_table[swap] = tmp;
  468.     }
  469.  
  470.   for (j = 0; j < 256; j++)
  471.     {    /* rows */
  472.       for (k = 0; k < 256; k++)
  473.     {   /* column */
  474.       tmp_sum = j + k;
  475.       if(tmp_sum > 255)
  476.         tmp_sum = 255;
  477.       add_lut[j][k] = tmp_sum; 
  478.     }
  479.     }
  480. }
  481.  
  482.  
  483. void
  484. paint_funcs_free ()
  485. {
  486.   /*  free the temporary buffer  */
  487.   g_free (tmp_buffer);
  488.  
  489.   /*  print out the hash table statistics
  490.       printf ("RGB->indexed hash table lookups: %d\n", color_hash_hits + color_hash_misses);
  491.       printf ("RGB->indexed hash table hits: %d\n", color_hash_hits);
  492.       printf ("RGB->indexed hash table misses: %d\n", color_hash_misses);
  493.       printf ("RGB->indexed hash table hit rate: %f\n",
  494.       100.0 * color_hash_hits / (color_hash_hits + color_hash_misses));
  495.       */
  496. }
  497.  
  498. void
  499. paint_funcs_invalidate_color_hash_table (GimpImage* gimage,
  500.                      gint       index)
  501. {
  502.   gint i;
  503.  
  504.   g_return_if_fail (gimage != NULL);
  505.  
  506.   if (index == -1) /* invalidate all entries */
  507.     {
  508.       for (i = 0; i < HASH_TABLE_SIZE; i++)
  509.     if (color_hash_table[i].gimage == gimage)
  510.       color_hash_table[i].gimage = NULL;
  511.     }
  512.   else
  513.     {
  514.       for (i = 0; i < HASH_TABLE_SIZE; i++)
  515.     if (color_hash_table[i].gimage == gimage && 
  516.         color_hash_table[i].index  == index)
  517.       color_hash_table[i].gimage = NULL;      
  518.     }
  519. }
  520.  
  521.  
  522. void
  523. color_pixels (unsigned char *dest,
  524.           const unsigned char *color,
  525.           int            w,
  526.           int            bytes)
  527. {
  528.   /* dest % bytes and color % bytes must be 0 or we will crash 
  529.      when bytes = 2 or 4.
  530.      Is this safe to assume?  Lets find out.
  531.      This is 4-7X as fast as the simple version.
  532.      */
  533.  
  534. #if defined(sparc) || defined(__sparc__)
  535.   register unsigned char c0, c1, c2, c3;
  536. #else
  537.   register unsigned char c0, c1, c2;
  538.   register guint32 *longd, longc;
  539.   register guint16 *shortd, shortc;
  540. #endif
  541.  
  542.   switch (bytes)
  543.   {
  544.    case 1:
  545.      memset(dest, *color, w);
  546.      break;
  547.  
  548.    case 2:
  549. #if defined(sparc) || defined(__sparc__)
  550.      c0 = color[0];
  551.      c1 = color[1];
  552.      while (w--)
  553.        {
  554.      dest[0] = c0;
  555.      dest[1] = c1;
  556.      dest += 2;
  557.        }
  558. #else
  559.      shortc = ((guint16 *)color)[0];
  560.      shortd = (guint16 *)dest;
  561.      while (w--)
  562.        {
  563.      *shortd = shortc;
  564.      shortd++;
  565.        }
  566. #endif /* sparc || __sparc__ */
  567.      break;
  568.    case 3:
  569.      c0 = color[0];
  570.      c1 = color[1];
  571.      c2 = color[2];
  572.      while (w--)
  573.        {
  574.      dest[0] = c0;
  575.      dest[1] = c1;
  576.      dest[2] = c2;
  577.      dest += 3;
  578.        }
  579.      break;
  580.    case 4:
  581. #if defined(sparc) || defined(__sparc__)
  582.      c0 = color[0];
  583.      c1 = color[1];
  584.      c2 = color[2];
  585.      c3 = color[3];
  586.      while (w--)
  587.        {
  588.      dest[0] = c0;
  589.      dest[1] = c1;
  590.      dest[2] = c2;
  591.      dest[3] = c3;
  592.      dest += 4;
  593.        }
  594. #else
  595.      longc = ((guint32 *)color)[0];
  596.      longd = (guint32 *)dest;
  597.      while (w--)
  598.        {
  599.      *longd = longc;
  600.      longd++;
  601.        }
  602. #endif /* sparc || __sparc__ */
  603.      break;
  604.    default:
  605.      while (w--)
  606.        {
  607.          memcpy (dest, color, bytes);
  608.          dest += bytes;
  609.        }
  610.   }
  611. }
  612.  
  613.  
  614. void
  615. blend_pixels (const unsigned char *src1,
  616.           const unsigned char *src2,
  617.           unsigned char *dest,
  618.           int            blend,
  619.           int            w,
  620.           int            bytes,
  621.           int            has_alpha)
  622. {
  623.   int b;
  624.   unsigned char blend2 = (255 - blend);
  625.  
  626.   while (w --)
  627.     {
  628.       for (b = 0; b < bytes; b++)
  629.     dest[b] = (src1[b] * blend2 + src2[b] * blend) / 255;
  630.  
  631.       src1 += bytes;
  632.       src2 += bytes;
  633.       dest += bytes;
  634.     }
  635. }
  636.  
  637.  
  638. void
  639. shade_pixels (const unsigned char *src,
  640.           unsigned char *dest,
  641.           const unsigned char *col,
  642.           int            blend,
  643.           int            w,
  644.           int            bytes,
  645.           int            has_alpha)
  646. {
  647.   int alpha, b;
  648.   unsigned char blend2 = (255 - blend);
  649.  
  650.   alpha = (has_alpha) ? bytes - 1 : bytes;
  651.   while (w --)
  652.     {
  653.       for (b = 0; b < alpha; b++)
  654.     dest[b] = (src[b] * blend2 + col[b] * blend) / 255;
  655.  
  656.       if (has_alpha)
  657.     dest[alpha] = src[alpha];  /* alpha channel */
  658.  
  659.       src += bytes;
  660.       dest += bytes;
  661.     }
  662. }
  663.  
  664.  
  665. void
  666. extract_alpha_pixels (const unsigned char *src,
  667.               const unsigned char *mask,
  668.               unsigned char *dest,
  669.               int            w,
  670.               int            bytes)
  671. {
  672.   const unsigned char * m;
  673.   int tmp;
  674.  
  675.   const int alpha = bytes - 1;
  676.   
  677.   if (mask)
  678.     {
  679.       m = mask;
  680.       while (w --)
  681.         {
  682.           *dest++ = INT_MULT(src[alpha], *m, tmp);
  683.           m++;
  684.           src += bytes;
  685.         }
  686.      }  else
  687.      { 
  688.        m = &no_mask;
  689.        while (w --)
  690.         { 
  691.           *dest++ = INT_MULT(src[alpha], *m, tmp);
  692.           src += bytes;
  693.         }
  694.      }
  695. }
  696.  
  697. void
  698. darken_pixels (const unsigned char *src1,
  699.            const unsigned char *src2,
  700.            unsigned char *dest,
  701.            int            length,
  702.            int            bytes1,
  703.            int            bytes2,
  704.            int            has_alpha1,
  705.            int            has_alpha2)
  706. {
  707.   int b, alpha;
  708.   unsigned char s1, s2;
  709.  
  710.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  711.  
  712.   while (length--)
  713.     {
  714.       for (b = 0; b < alpha; b++)
  715.     {
  716.       s1 = src1[b];
  717.       s2 = src2[b];
  718.       dest[b] = (s1 < s2) ? s1 : s2;
  719.     }
  720.  
  721.       if (has_alpha1 && has_alpha2)
  722.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  723.       else if (has_alpha2)
  724.     dest[alpha] = src2[alpha];
  725.  
  726.       src1 += bytes1;
  727.       src2 += bytes2;
  728.       dest += bytes2;
  729.     }
  730. }
  731.  
  732.  
  733. void
  734. lighten_pixels (const unsigned char *src1,
  735.         const unsigned char *src2,
  736.         unsigned char *dest,
  737.         int            length,
  738.         int            bytes1,
  739.         int            bytes2,
  740.         int            has_alpha1,
  741.         int            has_alpha2)
  742. {
  743.   int b, alpha;
  744.   unsigned char s1, s2;
  745.  
  746.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  747.  
  748.   while (length--)
  749.     {
  750.       for (b = 0; b < alpha; b++)
  751.     {
  752.       s1 = src1[b];
  753.       s2 = src2[b];
  754.       dest[b] = (s1 < s2) ? s2 : s1;
  755.     }
  756.  
  757.       if (has_alpha1 && has_alpha2)
  758.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  759.       else if (has_alpha2)
  760.     dest[alpha] = src2[alpha];
  761.  
  762.       src1 += bytes1;
  763.       src2 += bytes2;
  764.       dest += bytes2;
  765.     }
  766. }
  767.  
  768.  
  769. void
  770. hsv_only_pixels (const unsigned char *src1,
  771.          const unsigned char *src2,
  772.          unsigned char *dest,
  773.          int            mode,
  774.          int            length,
  775.          int            bytes1,
  776.          int            bytes2,
  777.          int            has_alpha1,
  778.          int            has_alpha2)
  779. {
  780.   int r1, g1, b1;
  781.   int r2, g2, b2;
  782.  
  783.   /*  assumes inputs are only 4 byte RGBA pixels  */
  784.   while (length--)
  785.     {
  786.       r1 = src1[0]; g1 = src1[1]; b1 = src1[2];
  787.       r2 = src2[0]; g2 = src2[1]; b2 = src2[2];
  788.       gimp_rgb_to_hsv (&r1, &g1, &b1);
  789.       gimp_rgb_to_hsv (&r2, &g2, &b2);
  790.  
  791.       switch (mode)
  792.     {
  793.     case HUE_MODE:
  794.       r1 = r2;
  795.       break;
  796.     case SATURATION_MODE:
  797.       g1 = g2;
  798.       break;
  799.     case VALUE_MODE:
  800.       b1 = b2;
  801.       break;
  802.     }
  803.  
  804.       /*  set the destination  */
  805.       gimp_hsv_to_rgb (&r1, &g1, &b1);
  806.  
  807.       dest[0] = r1; dest[1] = g1; dest[2] = b1;
  808.  
  809.       if (has_alpha1 && has_alpha2)
  810.     dest[3] = MIN (src1[3], src2[3]);
  811.       else if (has_alpha2)
  812.     dest[3] = src2[3];
  813.  
  814.       src1 += bytes1;
  815.       src2 += bytes2;
  816.       dest += bytes2;
  817.     }
  818. }
  819.  
  820.  
  821. void
  822. color_only_pixels (const unsigned char *src1,
  823.            const unsigned char *src2,
  824.            unsigned char *dest,
  825.            int            mode,
  826.            int            length,
  827.            int            bytes1,
  828.            int            bytes2,
  829.            int            has_alpha1,
  830.            int            has_alpha2)
  831. {
  832.   int r1, g1, b1;
  833.   int r2, g2, b2;
  834.  
  835.   /*  assumes inputs are only 4 byte RGBA pixels  */
  836.   while (length--)
  837.     {
  838.       r1 = src1[0]; g1 = src1[1]; b1 = src1[2];
  839.       r2 = src2[0]; g2 = src2[1]; b2 = src2[2];
  840.       gimp_rgb_to_hls (&r1, &g1, &b1);
  841.       gimp_rgb_to_hls (&r2, &g2, &b2);
  842.  
  843.       /*  transfer hue and saturation to the source pixel  */
  844.       r1 = r2;
  845.       b1 = b2;
  846.  
  847.       /*  set the destination  */
  848.       gimp_hls_to_rgb (&r1, &g1, &b1);
  849.  
  850.       dest[0] = r1; dest[1] = g1; dest[2] = b1;
  851.  
  852.       if (has_alpha1 && has_alpha2)
  853.     dest[3] = MIN (src1[3], src2[3]);
  854.       else if (has_alpha2)
  855.     dest[3] = src2[3];
  856.  
  857.       src1 += bytes1;
  858.       src2 += bytes2;
  859.       dest += bytes2;
  860.     }
  861. }
  862.  
  863. void
  864. multiply_pixels (const unsigned char *src1,
  865.          const unsigned char *src2,
  866.          unsigned char *dest,
  867.          int            length,
  868.          int            bytes1,
  869.          int            bytes2,
  870.          int            has_alpha1,
  871.          int            has_alpha2)
  872. {
  873.   int alpha, b;
  874.   int tmp;
  875.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  876.  
  877.   if (has_alpha1 && has_alpha2)
  878.     while (length --)
  879.     {
  880.       for (b = 0; b < alpha; b++)
  881.     dest[b] = INT_MULT(src1[b], src2[b], tmp);
  882.  
  883.       dest[alpha] = MIN (src1[alpha], src2[alpha]);
  884.  
  885.       src1 += bytes1;
  886.       src2 += bytes2;
  887.       dest += bytes2;
  888.     }
  889.   else if (has_alpha2)
  890.     while (length --)
  891.     {
  892.       for (b = 0; b < alpha; b++)
  893.     dest[b] = INT_MULT(src1[b], src2[b], tmp);
  894.  
  895.       dest[alpha] = src2[alpha];
  896.  
  897.       src1 += bytes1;
  898.       src2 += bytes2;
  899.       dest += bytes2;
  900.     }
  901.   else
  902.     while (length --)
  903.     {
  904.       for (b = 0; b < alpha; b++)
  905.     dest[b] = INT_MULT(src1[b], src2[b], tmp);
  906.  
  907.       src1 += bytes1;
  908.       src2 += bytes2;
  909.       dest += bytes2;
  910.     }
  911. }
  912.  
  913.  
  914. void
  915. divide_pixels (const unsigned char *src1,
  916.          const unsigned char *src2,
  917.          unsigned char *dest,
  918.          int            length,
  919.          int            bytes1,
  920.          int            bytes2,
  921.          int            has_alpha1,
  922.          int            has_alpha2)
  923. {
  924.   int alpha, b, result;
  925.  
  926.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  927.  
  928.   while (length --)
  929.     {
  930.       for (b = 0; b < alpha; b++)
  931.     {
  932.       result = ((src1[b] * 256) / (1+src2[b]));
  933.       dest[b] = MIN (result, 255);
  934.     }
  935.  
  936.       if (has_alpha1 && has_alpha2)
  937.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  938.       else if (has_alpha2)
  939.     dest[alpha] = src2[alpha];
  940.  
  941.       src1 += bytes1;
  942.       src2 += bytes2;
  943.       dest += bytes2;
  944.     }
  945. }
  946.  
  947.  
  948. void
  949. screen_pixels (const unsigned char *src1,
  950.            const unsigned char *src2,
  951.            unsigned char *dest,
  952.            int            length,
  953.            int            bytes1,
  954.            int            bytes2,
  955.            int            has_alpha1,
  956.            int            has_alpha2)
  957. {
  958.   int alpha, b;
  959.   int tmp;
  960.  
  961.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  962.  
  963.   while (length --)
  964.     {
  965.       for (b = 0; b < alpha; b++)
  966.     dest[b] = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp);
  967.  
  968.       if (has_alpha1 && has_alpha2)
  969.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  970.       else if (has_alpha2)
  971.     dest[alpha] = src2[alpha];
  972.  
  973.       src1 += bytes1;
  974.       src2 += bytes2;
  975.       dest += bytes2;
  976.     }
  977. }
  978.  
  979.  
  980. void
  981. overlay_pixels (const unsigned char *src1,
  982.         const unsigned char *src2,
  983.         unsigned char *dest,
  984.         int            length,
  985.         int            bytes1,
  986.         int            bytes2,
  987.         int            has_alpha1,
  988.         int            has_alpha2)
  989. {
  990.   int alpha, b;
  991.   int tmp;
  992.  
  993.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  994.  
  995.   while (length --)
  996.     {
  997.       for (b = 0; b < alpha; b++)
  998.     {
  999.       dest[b] = INT_MULT(src1[b], src1[b] + INT_MULT(2 * src2[b],
  1000.                              255 - src1[b],
  1001.                              tmp), tmp);
  1002.     }
  1003.  
  1004.       if (has_alpha1 && has_alpha2)
  1005.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1006.       else if (has_alpha2)
  1007.     dest[alpha] = src2[alpha];
  1008.  
  1009.       src1 += bytes1;
  1010.       src2 += bytes2;
  1011.       dest += bytes2;
  1012.     }
  1013. }
  1014.  
  1015.  
  1016. void
  1017. add_pixels (const unsigned char *src1,
  1018.         const unsigned char *src2,
  1019.         unsigned char *dest,
  1020.         int            length,
  1021.         int            bytes1,
  1022.         int            bytes2,
  1023.         int            has_alpha1,
  1024.         int            has_alpha2)
  1025. {
  1026.   int alpha, b;
  1027.  
  1028.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  1029.  
  1030.   while (length --)
  1031.     {
  1032.       for (b = 0; b < alpha; b++)
  1033.     {
  1034.       /* TODO: wouldn't it be better use a 1 dimensional lut ie. add_lut[src1+src2]; */
  1035.       dest[b] = add_lut[(src1[b])] [(src2[b])];
  1036.     }
  1037.  
  1038.       if (has_alpha1 && has_alpha2)
  1039.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1040.       else if (has_alpha2)
  1041.     dest[alpha] = src2[alpha];
  1042.  
  1043.       src1 += bytes1;
  1044.       src2 += bytes2;
  1045.       dest += bytes2;
  1046.     }
  1047. }
  1048.  
  1049.  
  1050. void
  1051. subtract_pixels (const unsigned char *src1,
  1052.          const unsigned char *src2,
  1053.          unsigned char *dest,
  1054.          int            length,
  1055.          int            bytes1,
  1056.          int            bytes2,
  1057.          int            has_alpha1,
  1058.          int            has_alpha2)
  1059. {
  1060.   int alpha, b;
  1061.   int diff;
  1062.  
  1063.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  1064.  
  1065.   while (length --)
  1066.     {
  1067.       for (b = 0; b < alpha; b++)
  1068.     {
  1069.       diff = src1[b] - src2[b];
  1070.       dest[b] = (diff < 0) ? 0 : diff;
  1071.     }
  1072.  
  1073.       if (has_alpha1 && has_alpha2)
  1074.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1075.       else if (has_alpha2)
  1076.     dest[alpha] = src2[alpha];
  1077.  
  1078.       src1 += bytes1;
  1079.       src2 += bytes2;
  1080.       dest += bytes2;
  1081.     }
  1082. }
  1083.  
  1084.  
  1085. void
  1086. difference_pixels (const unsigned char *src1,
  1087.            const unsigned char *src2,
  1088.            unsigned char *dest,
  1089.            int            length,
  1090.            int            bytes1,
  1091.            int            bytes2,
  1092.            int            has_alpha1,
  1093.            int            has_alpha2)
  1094. {
  1095.   int alpha, b;
  1096.   int diff;
  1097.  
  1098.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  1099.  
  1100.   while (length --)
  1101.     {
  1102.       for (b = 0; b < alpha; b++)
  1103.     {
  1104.       diff = src1[b] - src2[b];
  1105.       dest[b] = (diff < 0) ? -diff : diff;
  1106.     }
  1107.  
  1108.       if (has_alpha1 && has_alpha2)
  1109.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1110.       else if (has_alpha2)
  1111.     dest[alpha] = src2[alpha];
  1112.  
  1113.       src1 += bytes1;
  1114.       src2 += bytes2;
  1115.       dest += bytes2;
  1116.     }
  1117. }
  1118.  
  1119.  
  1120. void
  1121. dissolve_pixels (const unsigned char *src,
  1122.          unsigned char *dest,
  1123.          int            x,
  1124.          int            y,
  1125.          int            opacity,
  1126.          int            length,
  1127.          int            sb,
  1128.          int            db,
  1129.          int            has_alpha)
  1130. {
  1131.   int alpha, b;
  1132.   int rand_val;
  1133.   
  1134. #if defined(ENABLE_MP) && defined(__GLIBC__)
  1135.   /* The glibc 2.1 documentation recommends using the SVID random functions
  1136.    * instead of rand_r
  1137.    */
  1138.   struct drand48_data seed;
  1139.   long temp_val;
  1140.  
  1141.   srand48_r (random_table[y % RANDOM_TABLE_SIZE], &seed);
  1142.   for (b = 0; b < x; b++)
  1143.     lrand48_r (&seed, &temp_val);
  1144. #elif defined(ENABLE_MP) && !defined(__GLIBC__)
  1145.   /* If we are running with multiple threads rand_r give _much_ better
  1146.    * performance than rand
  1147.    */
  1148.   unsigned int seed;
  1149.   seed = random_table[y % RANDOM_TABLE_SIZE];
  1150.   for (b = 0; b < x; b++)
  1151.     rand_r (&seed);
  1152. #else
  1153.   /* Set up the random number generator */
  1154.   srand (random_table[y % RANDOM_TABLE_SIZE]);
  1155.   for (b = 0; b < x; b++)
  1156.     rand ();
  1157. #endif
  1158.  
  1159.   alpha = db - 1;
  1160.  
  1161.   while (length--)
  1162.     {
  1163.       /*  preserve the intensity values  */
  1164.       for (b = 0; b < alpha; b++)
  1165.     dest[b] = src[b];
  1166.  
  1167.       /*  dissolve if random value is > opacity  */
  1168. #if defined(ENABLE_MP) && defined(__GLIBC__)
  1169.       lrand48_r (&seed, &temp_val);
  1170.       rand_val = temp_val & 0xff;
  1171. #elif defined(ENABLE_MP) && !defined(__GLIBC__)
  1172.       rand_val = (rand_r (&seed) & 0xff);
  1173. #else
  1174.       rand_val = (rand () & 0xff);
  1175. #endif
  1176.       if (has_alpha)
  1177.     dest[alpha] = (rand_val > src[alpha]) ? 0 : src[alpha];
  1178.       else
  1179.     dest[alpha] = (rand_val > opacity) ? 0 : OPAQUE_OPACITY;
  1180.  
  1181.       dest += db;
  1182.       src  += sb;
  1183.     }
  1184. }
  1185.  
  1186. void
  1187. replace_pixels (unsigned char *src1,
  1188.         unsigned char *src2,
  1189.         unsigned char *dest,
  1190.         unsigned char *mask,
  1191.         int            length,
  1192.         int            opacity,
  1193.         int           *affect,
  1194.         int            bytes1,
  1195.         int            bytes2)
  1196. {
  1197.   int alpha;
  1198.   int b;
  1199.   double a_val, a_recip, mask_val;
  1200.   double norm_opacity;
  1201.   int s1_a, s2_a;
  1202.   int new_val;
  1203.  
  1204.   if (bytes1 != bytes2)
  1205.     {
  1206.       g_warning ("replace_pixels only works on commensurate pixel regions");
  1207.       return;
  1208.     }
  1209.  
  1210.   alpha = bytes1 - 1;
  1211.   norm_opacity = opacity * (1.0 / 65536.0);
  1212.  
  1213.   while (length --)
  1214.     {
  1215.       mask_val = mask[0] * norm_opacity;
  1216.       /* calculate new alpha first. */
  1217.       s1_a = src1[alpha];
  1218.       s2_a = src2[alpha];
  1219.       a_val = s1_a + mask_val * (s2_a - s1_a);
  1220.       if (a_val == 0) /* In any case, write out versions of the blending function */
  1221.                       /* that result when combinations of s1_a, s2_a, and         */
  1222.                   /* mask_val --> 0 (or mask_val -->1)                        */
  1223.         {
  1224.           /* Case 1: s1_a, s2_a, AND mask_val all approach 0+:               */
  1225.       /* Case 2: s1_a AND s2_a both approach 0+, regardless of mask_val: */
  1226.  
  1227.           if(s1_a + s2_a == 0.0)
  1228.             {
  1229.               for (b = 0; b < alpha; b++)
  1230.             {
  1231.                   new_val = 0.5 + (double)src1[b] + mask_val*((double)src2[b] - (double)src1[b]); 
  1232.                   dest[b] = affect[b] ? MIN (new_val, 255) : src1[b];
  1233.                 }
  1234.             }
  1235.  
  1236.       /* Case 3: mask_val AND s1_a both approach 0+, regardless of s2_a  */
  1237.           else if(s1_a + mask_val == 0.0)
  1238.             {
  1239.               for (b = 0; b < alpha; b++)
  1240.             {
  1241.                   dest[b] = src1[b]; 
  1242.                 }
  1243.             }
  1244.  
  1245.       /* Case 4: mask_val -->1 AND s2_a -->0, regardless of s1_a         */
  1246.           else if(1.0 - mask_val + s2_a == 0.0)
  1247.             {
  1248.               for (b = 0; b < alpha; b++)
  1249.             {
  1250.                   dest[b] = affect[b] ? src2[b] : src1[b]; 
  1251.                 }
  1252.             }
  1253.     }
  1254.       else
  1255.     {
  1256.       a_recip = 1.0 / a_val;
  1257.           /* possible optimization: fold a_recip into s1_a and s2_a              */
  1258.           for (b = 0; b < alpha; b++)
  1259.         {
  1260.           new_val = 0.5 + a_recip * (src1[b] * s1_a + mask_val *
  1261.                          (src2[b] * s2_a - src1[b] * s1_a));
  1262.           dest[b] = affect[b] ? MIN (new_val, 255) : src1[b];
  1263.             }
  1264.         }
  1265.       dest[alpha] = affect[alpha] ? a_val + 0.5: s1_a;
  1266.       src1 += bytes1;
  1267.       src2 += bytes2;
  1268.       dest += bytes2;
  1269.       mask++;
  1270.     }
  1271. }
  1272.  
  1273.  
  1274. void
  1275. swap_pixels (unsigned char *src,
  1276.          unsigned char *dest,
  1277.          int            length)
  1278. {
  1279.   while (length--)
  1280.     {
  1281.       *src = *src ^ *dest;
  1282.       *dest = *dest ^ *src;
  1283.       *src = *src ^ *dest;
  1284.       src++;
  1285.       dest++;
  1286.     }
  1287. }
  1288.  
  1289.  
  1290. void
  1291. scale_pixels (const unsigned char *src,
  1292.           unsigned char *dest,
  1293.           int            length,
  1294.           int            scale)
  1295. {
  1296.   int tmp;
  1297.   while (length --)
  1298.   {
  1299.     *dest++ = (unsigned char) INT_MULT(*src,scale,tmp);
  1300.     src++;
  1301.   }
  1302. }
  1303.  
  1304.  
  1305. void
  1306. add_alpha_pixels (const unsigned char *src,
  1307.           unsigned char *dest,
  1308.           int            length,
  1309.           int            bytes)
  1310. {
  1311.   int alpha, b;
  1312.  
  1313.   alpha = bytes + 1;
  1314.   while (length --)
  1315.     {
  1316.       for (b = 0; b < bytes; b++)
  1317.     dest[b] = src[b];
  1318.  
  1319.       dest[b] = OPAQUE_OPACITY;
  1320.  
  1321.       src += bytes;
  1322.       dest += alpha;
  1323.     }
  1324. }
  1325.  
  1326.  
  1327. void
  1328. flatten_pixels (const unsigned char *src,
  1329.         unsigned char *dest,
  1330.         const unsigned char *bg,
  1331.         int            length,
  1332.         int            bytes)
  1333. {
  1334.   int alpha, b;
  1335.   int t1, t2;
  1336.  
  1337.   alpha = bytes - 1;
  1338.   while (length --)
  1339.     {
  1340.       for (b = 0; b < alpha; b++)
  1341.     dest[b] = INT_MULT (src[b], src[alpha], t1) + INT_MULT (bg[b], (255 - src[alpha]), t2);
  1342.  
  1343.       src += bytes;
  1344.       dest += alpha;
  1345.     }
  1346. }
  1347.  
  1348.  
  1349. void
  1350. gray_to_rgb_pixels (const unsigned char *src,
  1351.             unsigned char *dest,
  1352.             int            length,
  1353.             int            bytes)
  1354. {
  1355.   int b;
  1356.   int dest_bytes;
  1357.   int has_alpha;
  1358.  
  1359.   has_alpha = (bytes == 2) ? 1 : 0;
  1360.   dest_bytes = (has_alpha) ? 4 : 3;
  1361.  
  1362.   while (length --)
  1363.     {
  1364.       for (b = 0; b < bytes; b++)
  1365.     dest[b] = src[0];
  1366.  
  1367.       if (has_alpha)
  1368.     dest[3] = src[1];
  1369.  
  1370.       src += bytes;
  1371.       dest += dest_bytes;
  1372.     }
  1373. }
  1374.  
  1375.  
  1376. void
  1377. apply_mask_to_alpha_channel (unsigned char *src,
  1378.                  const unsigned char *mask,
  1379.                  int            opacity,
  1380.                  int            length,
  1381.                  int            bytes)
  1382. {
  1383.   long tmp;
  1384.   src += bytes - 1;
  1385.   if (opacity == 255)
  1386.     while (length --)
  1387.     {
  1388.       *src = INT_MULT(*src, *mask, tmp);
  1389.       mask++;
  1390.       src += bytes;
  1391.     }
  1392.   else
  1393.     while (length --)
  1394.     {
  1395.       *src = INT_MULT3(*src, *mask, opacity, tmp);
  1396.       mask++;
  1397.       src += bytes;
  1398.     }
  1399. }
  1400.  
  1401.  
  1402. void
  1403. combine_mask_and_alpha_channel (unsigned char *src,
  1404.                 const unsigned char *mask,
  1405.                 int            opacity,
  1406.                 int            length,
  1407.                 int            bytes)
  1408. {
  1409.   int mask_val;
  1410.   int alpha;
  1411.   int tmp;
  1412.   alpha = bytes - 1;
  1413.   src += alpha;
  1414.  
  1415.   if (opacity != 255)
  1416.     while (length --)
  1417.     {
  1418.       mask_val = INT_MULT(*mask, opacity, tmp);
  1419.       mask++;
  1420.       *src = *src + INT_MULT((255 - *src) , mask_val, tmp);
  1421.       src += bytes;
  1422.     }
  1423.   else
  1424.     while (length --)
  1425.     {
  1426.       *src = *src + INT_MULT((255 - *src) , *mask, tmp);
  1427.       src += bytes;
  1428.       mask++;
  1429.     }
  1430. }
  1431.  
  1432.  
  1433. void
  1434. copy_gray_to_inten_a_pixels (const unsigned char *src,
  1435.                  unsigned char *dest,
  1436.                  int            length,
  1437.                  int            bytes)
  1438. {
  1439.   int b;
  1440.   int alpha;
  1441.  
  1442.   alpha = bytes - 1;
  1443.   while (length --)
  1444.     {
  1445.       for (b = 0; b < alpha; b++)
  1446.     dest[b] = *src;
  1447.       dest[b] = OPAQUE_OPACITY;
  1448.  
  1449.       src ++;
  1450.       dest += bytes;
  1451.     }
  1452. }
  1453.  
  1454.  
  1455. void
  1456. initial_channel_pixels (const unsigned char *src,
  1457.             unsigned char *dest,
  1458.             int            length,
  1459.             int            bytes)
  1460. {
  1461.   int alpha, b;
  1462.  
  1463.   alpha = bytes - 1;
  1464.   while (length --)
  1465.     {
  1466.       for (b = 0; b < alpha; b++)
  1467.     dest[b] = src[0];
  1468.  
  1469.       dest[alpha] = OPAQUE_OPACITY;
  1470.  
  1471.       dest += bytes;
  1472.       src ++;
  1473.     }
  1474. }
  1475.  
  1476.  
  1477. void
  1478. initial_indexed_pixels (const unsigned char *src,
  1479.             unsigned char *dest,
  1480.             const unsigned char *cmap,
  1481.             int            length)
  1482. {
  1483.   int col_index;
  1484.  
  1485.   /*  This function assumes always that we're mapping from
  1486.    *  an RGB colormap to an RGBA image...
  1487.    */
  1488.   while (length--)
  1489.     {
  1490.       col_index = *src++ * 3;
  1491.       *dest++ = cmap[col_index++];
  1492.       *dest++ = cmap[col_index++];
  1493.       *dest++ = cmap[col_index++];
  1494.       *dest++ = OPAQUE_OPACITY;
  1495.     }
  1496. }
  1497.  
  1498.  
  1499. void
  1500. initial_indexed_a_pixels (const unsigned char *src,
  1501.               unsigned char *dest,
  1502.               const unsigned char *mask,
  1503.               const unsigned char *cmap,
  1504.               int            opacity,
  1505.               int            length)
  1506. {
  1507.   int col_index;
  1508.   unsigned char new_alpha;
  1509.   const unsigned char * m;
  1510.   long tmp;
  1511.   if (mask)
  1512.     m = mask;
  1513.   else
  1514.     m = &no_mask;
  1515.  
  1516.   while (length --)
  1517.     {
  1518.       col_index = *src++ * 3;
  1519.       new_alpha = INT_MULT3(*src, *m, opacity, tmp);
  1520.       src++;
  1521.       *dest++ = cmap[col_index++];
  1522.       *dest++ = cmap[col_index++];
  1523.       *dest++ = cmap[col_index++];
  1524.       /*  Set the alpha channel  */
  1525.       *dest++ = (new_alpha > 127) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
  1526.  
  1527.       if (mask)
  1528.     m++;
  1529.     }
  1530. }
  1531.  
  1532.  
  1533. void
  1534. initial_inten_pixels (const unsigned char *src,
  1535.               unsigned char *dest,
  1536.               const unsigned char *mask,
  1537.               int            opacity,
  1538.               const int     *affect,
  1539.               int            length,
  1540.               int            bytes)
  1541. {
  1542.   int b;
  1543.   const unsigned char * m;
  1544.   int tmp;
  1545.   int l;
  1546.   unsigned char *destp;
  1547.   const unsigned char *srcp;
  1548.   const int dest_bytes = bytes + 1;
  1549.  
  1550.   if (mask)
  1551.   {
  1552.     m = mask;
  1553.     
  1554.     /*  This function assumes the source has no alpha channel and
  1555.      *  the destination has an alpha channel.  So dest_bytes = bytes + 1
  1556.      */
  1557.    
  1558.     if (bytes == 3 && affect[0] && affect[1] && affect[2])
  1559.     {
  1560.       if (!affect[bytes])
  1561.     opacity = 0;
  1562.       destp = dest + bytes;
  1563.       if (opacity != 0)
  1564.     while(length--)
  1565.     {
  1566.       dest[0] = src[0];
  1567.       dest[1] = src[1];
  1568.       dest[2] = src[2];
  1569.       dest[3] = INT_MULT(opacity, *m, tmp);
  1570.       src  += bytes;
  1571.       dest += dest_bytes;
  1572.       m++;
  1573.     }
  1574.       else
  1575.     while(length--)
  1576.     {
  1577.       dest[0] = src[0];
  1578.       dest[1] = src[1];
  1579.       dest[2] = src[2];
  1580.       dest[3] = opacity;
  1581.       src  += bytes;
  1582.       dest += dest_bytes;
  1583.     }
  1584.       return;
  1585.     }
  1586.     for (b =0; b < bytes; b++)
  1587.     {
  1588.       destp = dest + b;
  1589.       srcp = src + b;
  1590.       l = length;
  1591.       if (affect[b])
  1592.     while(l--)
  1593.     {
  1594.       *destp = *srcp;
  1595.       srcp  += bytes;
  1596.       destp += dest_bytes;
  1597.     }
  1598.       else
  1599.     while(l--)
  1600.     {
  1601.       *destp = 0;
  1602.       destp += dest_bytes;
  1603.     }
  1604.     }
  1605.  
  1606.     /* fill the alpha channel */ 
  1607.     if (!affect[bytes])
  1608.       opacity = 0;
  1609.     destp = dest + bytes;
  1610.     if (opacity != 0)
  1611.       while (length--)
  1612.       {
  1613.     *destp = INT_MULT(opacity , *m, tmp);
  1614.     destp += dest_bytes;
  1615.     m++;
  1616.       }
  1617.     else
  1618.       while (length--)
  1619.       {
  1620.     *destp = opacity;
  1621.     destp += dest_bytes;
  1622.       }
  1623.   }
  1624.  
  1625.   /* If no mask */
  1626.   else
  1627.   {
  1628.     m = &no_mask;
  1629.  
  1630.     /*  This function assumes the source has no alpha channel and
  1631.      *  the destination has an alpha channel.  So dest_bytes = bytes + 1
  1632.      */
  1633.     
  1634.     if (bytes == 3 && affect[0] && affect[1] && affect[2])
  1635.       {
  1636.     if (!affect[bytes])
  1637.       opacity = 0;
  1638.     destp = dest + bytes;
  1639.     while(length--)
  1640.       {
  1641.         dest[0] = src[0];
  1642.         dest[1] = src[1];
  1643.         dest[2] = src[2];
  1644.         dest[3] = opacity;
  1645.         src  += bytes;
  1646.         dest += dest_bytes;
  1647.       }
  1648.     return;
  1649.       }
  1650.     
  1651.     for (b =0; b < bytes; b++)
  1652.       {
  1653.     destp = dest + b;
  1654.     srcp = src + b;
  1655.     l = length;
  1656.     if (affect[b])
  1657.       while(l--)
  1658.         {
  1659.           *destp = *srcp;
  1660.           srcp  += bytes;
  1661.           destp += dest_bytes;
  1662.         }
  1663.     else
  1664.       while(l--)
  1665.         {
  1666.           *destp = 0;
  1667.           destp += dest_bytes;
  1668.         }
  1669.       }
  1670.  
  1671.     /* fill the alpha channel */ 
  1672.     if (!affect[bytes])
  1673.       opacity = 0;
  1674.     destp = dest + bytes;
  1675.     while (length--)
  1676.       {
  1677.     *destp = opacity;
  1678.     destp += dest_bytes;
  1679.       }
  1680.   }
  1681. }
  1682.  
  1683.  
  1684. void
  1685. initial_inten_a_pixels (const unsigned char *src,
  1686.             unsigned char       *dest,
  1687.             const unsigned char *mask,
  1688.             int                  opacity,
  1689.             const int           *affect,
  1690.             int                  length,
  1691.             int                  bytes)
  1692. {
  1693.   int alpha, b;
  1694.   const unsigned char * m;
  1695.   long tmp;
  1696.  
  1697.   alpha = bytes - 1;
  1698.   if (mask)
  1699.     {
  1700.       m = mask;
  1701.       while (length --)
  1702.     {
  1703.       for (b = 0; b < alpha; b++)
  1704.         dest[b] = src[b] * affect[b];
  1705.       
  1706.       /*  Set the alpha channel  */
  1707.       dest[alpha] = affect [alpha] ? INT_MULT3(opacity, src[alpha], *m, tmp)
  1708.         : 0;
  1709.       
  1710.       m++;
  1711.       
  1712.       dest += bytes;
  1713.       src += bytes;
  1714.     }
  1715.     }
  1716.   else
  1717.     {
  1718.       while (length --)
  1719.     {
  1720.       for (b = 0; b < alpha; b++)
  1721.         dest[b] = src[b] * affect[b];
  1722.       
  1723.       /*  Set the alpha channel  */
  1724.       dest[alpha] = affect [alpha] ? INT_MULT(opacity , src[alpha], tmp) : 0;
  1725.       
  1726.       dest += bytes;
  1727.       src += bytes;
  1728.     }
  1729.     }
  1730. }
  1731.  
  1732.  
  1733. void
  1734. combine_indexed_and_indexed_pixels (const unsigned char *src1,
  1735.                     const unsigned char *src2,
  1736.                     unsigned char       *dest,
  1737.                     const unsigned char *mask,
  1738.                     int                  opacity,
  1739.                     const int           *affect,
  1740.                     int                  length,
  1741.                     int                  bytes)
  1742. {
  1743.   int b;
  1744.   unsigned char new_alpha;
  1745.   const unsigned char * m;
  1746.   int tmp;
  1747.   if (mask)
  1748.     {
  1749.       m = mask;
  1750.       while (length --)
  1751.     {
  1752.       new_alpha = INT_MULT(*m , opacity, tmp);
  1753.       
  1754.       for (b = 0; b < bytes; b++)
  1755.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1756.       
  1757.       m++;
  1758.       
  1759.       src1 += bytes;
  1760.       src2 += bytes;
  1761.       dest += bytes;
  1762.     }
  1763.     }
  1764.   else
  1765.     {
  1766.       while (length --)
  1767.     {
  1768.       new_alpha = opacity;
  1769.       
  1770.       for (b = 0; b < bytes; b++)
  1771.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1772.       
  1773.       src1 += bytes;
  1774.       src2 += bytes;
  1775.       dest += bytes;
  1776.     }
  1777.     }
  1778. }
  1779.  
  1780.  
  1781. void
  1782. combine_indexed_and_indexed_a_pixels (const unsigned char *src1,
  1783.                       const unsigned char *src2,
  1784.                       unsigned char       *dest,
  1785.                       const unsigned char *mask,
  1786.                       int                  opacity,
  1787.                       const int           *affect,
  1788.                       int                  length,
  1789.                       int                  bytes)
  1790. {
  1791.   int b, alpha;
  1792.   unsigned char new_alpha;
  1793.   const unsigned char * m;
  1794.   int src2_bytes;
  1795.   long tmp;
  1796.   alpha = 1;
  1797.   src2_bytes = 2;
  1798.  
  1799.   if (mask)
  1800.     {
  1801.       m = mask;
  1802.       while (length --)
  1803.     {
  1804.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  1805.  
  1806.       for (b = 0; b < bytes; b++)
  1807.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1808.  
  1809.       m++;
  1810.  
  1811.       src1 += bytes;
  1812.       src2 += src2_bytes;
  1813.       dest += bytes;
  1814.     }
  1815.     }
  1816.   else
  1817.     {
  1818.       while (length --)
  1819.     {
  1820.       new_alpha = INT_MULT(src2[alpha], opacity, tmp);
  1821.  
  1822.       for (b = 0; b < bytes; b++)
  1823.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1824.  
  1825.       src1 += bytes;
  1826.       src2 += src2_bytes;
  1827.       dest += bytes;
  1828.     }
  1829.     }
  1830. }
  1831.  
  1832.  
  1833. void
  1834. combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1,
  1835.                     const unsigned char *src2,
  1836.                     unsigned char       *dest,
  1837.                     const unsigned char *mask,
  1838.                     int                  opacity,
  1839.                     const int           *affect,
  1840.                     int                  length,
  1841.                     int                  bytes)
  1842. {
  1843.   int b, alpha;
  1844.   unsigned char new_alpha;
  1845.   const unsigned char * m;
  1846.   long tmp;
  1847.  
  1848.   alpha = 1;
  1849.  
  1850.   if (mask)
  1851.     {
  1852.       m = mask;
  1853.       while (length --)
  1854.     {
  1855.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  1856.  
  1857.       for (b = 0; b < alpha; b++)
  1858.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1859.  
  1860.       dest[alpha] = (affect[alpha] && new_alpha > 127) ? OPAQUE_OPACITY : src1[alpha];
  1861.  
  1862.       m++;
  1863.  
  1864.       src1 += bytes;
  1865.       src2 += bytes;
  1866.       dest += bytes;
  1867.     }
  1868.     }
  1869.   else
  1870.     {
  1871.       while (length --)
  1872.     {
  1873.       new_alpha = INT_MULT(src2[alpha], opacity, tmp);
  1874.  
  1875.       for (b = 0; b < alpha; b++)
  1876.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1877.  
  1878.       dest[alpha] = (affect[alpha] && new_alpha > 127) ? OPAQUE_OPACITY : src1[alpha];
  1879.  
  1880.       src1 += bytes;
  1881.       src2 += bytes;
  1882.       dest += bytes;
  1883.     }
  1884.     }
  1885. }
  1886.  
  1887.  
  1888. void
  1889. combine_inten_a_and_indexed_a_pixels (const unsigned char *src1,
  1890.                       const unsigned char *src2,
  1891.                       unsigned char       *dest,
  1892.                       const unsigned char *mask,
  1893.                       const unsigned char *cmap,
  1894.                       int                  opacity,
  1895.                       int                  length,
  1896.                       int                  bytes)
  1897. {
  1898.   int b, alpha;
  1899.   unsigned char new_alpha;
  1900.   int src2_bytes;
  1901.   int index;
  1902.   long tmp;
  1903.  
  1904.   alpha = 1;
  1905.   src2_bytes = 2;
  1906.  
  1907.   if (mask)
  1908.     {
  1909.       const unsigned char *m = mask;
  1910.       while (length --)
  1911.     {
  1912.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  1913.  
  1914.       index = src2[0] * 3;
  1915.  
  1916.       for (b = 0; b < bytes-1; b++)
  1917.         dest[b] = (new_alpha > 127) ? cmap[index + b] : src1[b];
  1918.  
  1919.       dest[b] = (new_alpha > 127) ? OPAQUE_OPACITY : src1[b];  /*  alpha channel is opaque  */
  1920.  
  1921.       m++;
  1922.  
  1923.       src1 += bytes;
  1924.       src2 += src2_bytes;
  1925.       dest += bytes;
  1926.     }
  1927.     }
  1928.   else
  1929.     {
  1930.       while (length --)
  1931.     {
  1932.       new_alpha = INT_MULT(src2[alpha], opacity, tmp);
  1933.  
  1934.       index = src2[0] * 3;
  1935.  
  1936.       for (b = 0; b < bytes-1; b++)
  1937.         dest[b] = (new_alpha > 127) ? cmap[index + b] : src1[b];
  1938.  
  1939.       dest[b] = (new_alpha > 127) ? OPAQUE_OPACITY : src1[b];  /*  alpha channel is opaque  */
  1940.  
  1941.       /* m++; /Per */
  1942.  
  1943.       src1 += bytes;
  1944.       src2 += src2_bytes;
  1945.       dest += bytes;
  1946.     }
  1947.     }
  1948. }
  1949.  
  1950.  
  1951. void
  1952. combine_inten_and_inten_pixels (const unsigned char *src1,
  1953.                 const unsigned char *src2,
  1954.                 unsigned char       *dest,
  1955.                 const unsigned char *mask,
  1956.                 int                  opacity,
  1957.                 const int           *affect,
  1958.                 int                  length,
  1959.                 int                  bytes)
  1960. {
  1961.   int b;
  1962.   unsigned char new_alpha;
  1963.   const unsigned char * m;
  1964.   int tmp;
  1965.   if (mask)
  1966.     {
  1967.       m = mask;
  1968.       while (length --)
  1969.     {
  1970.       new_alpha = INT_MULT(*m, opacity, tmp);
  1971.  
  1972.       for (b = 0; b < bytes; b++)
  1973.         dest[b] = (affect[b]) ?
  1974.           INT_BLEND(src2[b], src1[b], new_alpha, tmp) :
  1975.         src1[b];
  1976.  
  1977.       m++;
  1978.  
  1979.       src1 += bytes;
  1980.       src2 += bytes;
  1981.       dest += bytes;
  1982.     }
  1983.     }
  1984.   else
  1985.     {
  1986.       while (length --)
  1987.     {
  1988.  
  1989.       for (b = 0; b < bytes; b++)
  1990.         dest[b] = (affect[b]) ?
  1991.           INT_BLEND(src2[b], src1[b], opacity, tmp) :
  1992.         src1[b];
  1993.  
  1994.       src1 += bytes;
  1995.       src2 += bytes;
  1996.       dest += bytes;
  1997.     }
  1998.     }
  1999. }
  2000.  
  2001.  
  2002. void
  2003. combine_inten_and_inten_a_pixels (const unsigned char *src1,
  2004.                   const unsigned char *src2,
  2005.                   unsigned char       *dest,
  2006.                   const unsigned char *mask,
  2007.                   int                  opacity,
  2008.                   const int           *affect,
  2009.                   int                  length,
  2010.                   int                  bytes)
  2011. {
  2012.   int alpha, b;
  2013.   int src2_bytes;
  2014.   unsigned char new_alpha;
  2015.   const unsigned char * m;
  2016.   register long t1;
  2017.   alpha = bytes;
  2018.   src2_bytes = bytes + 1;
  2019.  
  2020.   if (mask)
  2021.     {
  2022.       m = mask;
  2023.       while (length --)
  2024.     {
  2025.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, t1);
  2026.  
  2027.       for (b = 0; b < bytes; b++)
  2028.         dest[b] = (affect[b]) ?
  2029.           INT_BLEND(src2[b], src1[b], new_alpha, t1) :
  2030.           src1[b];
  2031.  
  2032.       m++;
  2033.       src1 += bytes;
  2034.       src2 += src2_bytes;
  2035.       dest += bytes;
  2036.     }
  2037.     }
  2038.   else
  2039.     {
  2040.       if (bytes == 3 && affect[0] && affect[1] && affect[2])
  2041.     while (length --)
  2042.     {
  2043.       new_alpha = INT_MULT(src2[alpha],opacity,t1);
  2044.       dest[0] = INT_BLEND(src2[0] , src1[0] , new_alpha, t1);
  2045.       dest[1] = INT_BLEND(src2[1] , src1[1] , new_alpha, t1);
  2046.       dest[2] = INT_BLEND(src2[2] , src1[2] , new_alpha, t1);
  2047.       src1 += bytes;
  2048.       src2 += src2_bytes;
  2049.       dest += bytes;
  2050.     }
  2051.       else
  2052.     while (length --)
  2053.     {
  2054.       new_alpha = INT_MULT(src2[alpha],opacity,t1);
  2055.       for (b = 0; b < bytes; b++)
  2056.         dest[b] = (affect[b]) ?
  2057.           INT_BLEND(src2[b] , src1[b] , new_alpha, t1) :
  2058.         src1[b];
  2059.  
  2060.       src1 += bytes;
  2061.       src2 += src2_bytes;
  2062.       dest += bytes;
  2063.     }
  2064.     }
  2065. }
  2066.  
  2067. /*orig #define alphify(src2_alpha,new_alpha) \
  2068.     if (new_alpha == 0 || src2_alpha == 0)                            \
  2069.       {                                            \
  2070.         for (b = 0; b < alpha; b++)                                \
  2071.           dest[b] = src1 [b];                                \
  2072.       }                                            \
  2073.     else if (src2_alpha == new_alpha){                            \
  2074.       for (b = 0; b < alpha; b++)                                \
  2075.         dest [b] = affect [b] ? src2 [b] : src1 [b];                    \
  2076.     } else {                                        \
  2077.       ratio = (float) src2_alpha / new_alpha;                        \
  2078.       compl_ratio = 1.0 - ratio;                                \
  2079.                                                   \
  2080.       for (b = 0; b < alpha; b++)                                \
  2081.         dest[b] = affect[b] ?                                \
  2082.           (unsigned char) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];    \
  2083.     }*/
  2084.  
  2085. /*shortened #define alphify(src2_alpha,new_alpha) \
  2086.     if (src2_alpha != 0 && new_alpha != 0)                            \
  2087.       {                                            \
  2088.         if (src2_alpha == new_alpha){                            \
  2089.           for (b = 0; b < alpha; b++)                            \
  2090.           dest [b] = affect [b] ? src2 [b] : src1 [b];                    \
  2091.         } else {                                        \
  2092.           ratio = (float) src2_alpha / new_alpha;                        \
  2093.           compl_ratio = 1.0 - ratio;                            \
  2094.                                                   \
  2095.           for (b = 0; b < alpha; b++)                            \
  2096.             dest[b] = affect[b] ?                                \
  2097.               (unsigned char) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];\
  2098.         }                                                                                   \
  2099.       }*/
  2100.  
  2101. #define alphify(src2_alpha,new_alpha) \
  2102.     if (src2_alpha != 0 && new_alpha != 0)                            \
  2103.       {                                            \
  2104.             b = alpha; \
  2105.         if (src2_alpha == new_alpha){                            \
  2106.           do { \
  2107.           b--; dest [b] = affect [b] ? src2 [b] : src1 [b];} while (b);    \
  2108.         } else {                                        \
  2109.           ratio = (float) src2_alpha / new_alpha;                        \
  2110.           compl_ratio = 1.0 - ratio;                            \
  2111.                                                   \
  2112.               do { b--; \
  2113.             dest[b] = affect[b] ?                                \
  2114.               (unsigned char) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];\
  2115.                } while (b); \
  2116.         }    \
  2117.       }
  2118.  
  2119. /*special #define alphify4(src2_alpha,new_alpha) \
  2120.     if (src2_alpha != 0 && new_alpha != 0)                            \
  2121.       {                                            \
  2122.         if (src2_alpha == new_alpha){                            \
  2123.           dest [0] = affect [0] ? src2 [0] : src1 [0];                    \
  2124.           dest [1] = affect [1] ? src2 [1] : src1 [1];                    \
  2125.           dest [2] = affect [2] ? src2 [2] : src1 [2];                    \
  2126.         } else {                                        \
  2127.           ratio = (float) src2_alpha / new_alpha;                        \
  2128.           compl_ratio = 1.0 - ratio;                            \
  2129.                                                   \
  2130.           dest[0] = affect[0] ?                                \
  2131.             (unsigned char) (src2[0] * ratio + src1[0] * compl_ratio + EPSILON) : src1[0];  \
  2132.           dest[1] = affect[1] ?                                \
  2133.             (unsigned char) (src2[1] * ratio + src1[1] * compl_ratio + EPSILON) : src1[1];  \
  2134.           dest[2] = affect[2] ?                                \
  2135.             (unsigned char) (src2[2] * ratio + src1[2] * compl_ratio + EPSILON) : src1[2];  \
  2136.         }                                                                                   \
  2137.       }*/
  2138.     
  2139. void
  2140. combine_inten_a_and_inten_pixels (const unsigned char *src1,
  2141.                   const unsigned char *src2,
  2142.                   unsigned char       *dest,
  2143.                   const unsigned char *mask,
  2144.                   int                  opacity,
  2145.                   const int           *affect,
  2146.                   int                  mode_affect,  /*  how does the combination mode affect alpha?  */
  2147.                   int                  length,
  2148.                   int                  bytes)  /*  4 or 2 depending on RGBA or GRAYA  */
  2149. {
  2150.   int alpha, b;
  2151.   int src2_bytes;
  2152.   unsigned char src2_alpha;
  2153.   unsigned char new_alpha;
  2154.   const unsigned char * m;
  2155.   float ratio, compl_ratio;
  2156.   long tmp;
  2157.  
  2158.   src2_bytes = bytes - 1;
  2159.   alpha = bytes - 1;
  2160.  
  2161.   if (mask)
  2162.     {
  2163.       m = mask;
  2164.       if (opacity == OPAQUE_OPACITY) /* HAS MASK, FULL OPACITY */
  2165.     {
  2166.       while (length--)
  2167.         {
  2168.           src2_alpha = *m;
  2169.           new_alpha = src1[alpha] +
  2170.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2171.           alphify (src2_alpha, new_alpha);
  2172.           
  2173.           if (mode_affect)
  2174.         {
  2175.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2176.         }
  2177.           else
  2178.         {
  2179.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2180.             (affect[alpha] ? new_alpha : src1[alpha]);
  2181.         }
  2182.         
  2183.           m++;
  2184.           src1 += bytes;
  2185.           src2 += src2_bytes;
  2186.           dest += bytes;
  2187.         }
  2188.     }
  2189.       else /* HAS MASK, SEMI-OPACITY */
  2190.     {
  2191.       while (length--)
  2192.         {
  2193.           src2_alpha = INT_MULT(*m, opacity, tmp);
  2194.           new_alpha = src1[alpha] +
  2195.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2196.           alphify (src2_alpha, new_alpha);
  2197.           
  2198.           if (mode_affect)
  2199.         {
  2200.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2201.         }
  2202.           else
  2203.         {
  2204.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2205.             (affect[alpha] ? new_alpha : src1[alpha]);
  2206.         }
  2207.         
  2208.           m++;
  2209.           src1 += bytes;
  2210.           src2 += src2_bytes;
  2211.           dest += bytes;
  2212.         }
  2213.     }
  2214.     }
  2215.   else /* NO MASK */
  2216.     {
  2217.       while (length --)
  2218.     {
  2219.       src2_alpha = opacity;
  2220.       new_alpha = src1[alpha] +
  2221.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2222.       alphify (src2_alpha, new_alpha);
  2223.       
  2224.       if (mode_affect)
  2225.         dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2226.       else
  2227.         dest[alpha] = (src1[alpha]) ? src1[alpha] : (affect[alpha] ? new_alpha : src1[alpha]);
  2228.  
  2229.         src1 += bytes;
  2230.         src2 += src2_bytes;
  2231.         dest += bytes;
  2232.     }
  2233.     }
  2234. }
  2235.  
  2236.  
  2237. void
  2238. combine_inten_a_and_inten_a_pixels (const unsigned char *src1,
  2239.                     const unsigned char *src2,
  2240.                     unsigned char       *dest,
  2241.                     const unsigned char *mask,
  2242.                     int                 opacity,
  2243.                     const int          *affect,
  2244.                     int                 mode_affect,  /*  how does the combination mode affect alpha?  */
  2245.                     int                 length,
  2246.                     int                 bytes)  /*  4 or 2 depending on RGBA or GRAYA  */
  2247. {
  2248.   int b;
  2249.   unsigned char src2_alpha;
  2250.   unsigned char new_alpha;
  2251.   const unsigned char * m;
  2252.   float ratio, compl_ratio;
  2253.   long tmp;
  2254.   const int alpha = bytes - 1;
  2255.  
  2256.   if (mask)
  2257.     {
  2258.       m = mask;
  2259.  
  2260.       if (opacity == OPAQUE_OPACITY) /* HAS MASK, FULL OPACITY */
  2261.     {
  2262.       const int* mask_ip;
  2263.       int i,j;
  2264.  
  2265.       if (length >= sizeof(int))
  2266.         {
  2267.           /* HEAD */
  2268.           i =  (((int)m) & (sizeof(int)-1));
  2269.           if (i != 0)
  2270.         {
  2271.           i = sizeof(int) - i;
  2272.           length -= i;
  2273.           while (i--)
  2274.             {
  2275.               /* GUTS */
  2276.               src2_alpha = INT_MULT(src2[alpha], *m, tmp);
  2277.               new_alpha = src1[alpha] +
  2278.             INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2279.           
  2280.               alphify (src2_alpha, new_alpha);
  2281.           
  2282.               if (mode_affect)
  2283.             {
  2284.               dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2285.             }
  2286.               else
  2287.             {
  2288.               dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2289.                 (affect[alpha] ? new_alpha : src1[alpha]);      
  2290.             }
  2291.           
  2292.               m++;
  2293.               src1 += bytes;
  2294.               src2 += bytes;
  2295.               dest += bytes;    
  2296.               /* GUTS END */
  2297.             }
  2298.         }
  2299.  
  2300.           /* BODY */
  2301.           mask_ip = (int*)m;
  2302.           i = length / sizeof(int);
  2303.           length %= sizeof(int);
  2304.           while (i--)
  2305.         {
  2306.           if (*mask_ip)
  2307.             {
  2308.               m = (const unsigned char*)mask_ip;
  2309.               j = sizeof(int);
  2310.               while (j--)
  2311.             {
  2312.               /* GUTS */
  2313.               src2_alpha = INT_MULT(src2[alpha], *m, tmp);
  2314.               new_alpha = src1[alpha] +
  2315.                 INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2316.           
  2317.               alphify (src2_alpha, new_alpha);
  2318.           
  2319.               if (mode_affect)
  2320.                 {
  2321.                   dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2322.                 }
  2323.               else
  2324.                 {
  2325.                   dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2326.                 (affect[alpha] ? new_alpha : src1[alpha]);      
  2327.                 }
  2328.           
  2329.               m++;
  2330.               src1 += bytes;
  2331.               src2 += bytes;
  2332.               dest += bytes;    
  2333.               /* GUTS END */
  2334.             }
  2335.             }
  2336.           else
  2337.             {
  2338.               j = bytes * sizeof(int);
  2339.               src2 += j;
  2340.               while (j--)
  2341.             {
  2342.               *(dest++) = *(src1++);
  2343.             }
  2344.             }
  2345.           mask_ip++;
  2346.         }
  2347.  
  2348.           m = (const unsigned char*)mask_ip;
  2349.         }
  2350.  
  2351.       /* TAIL */
  2352.       while (length--)
  2353.         {
  2354.           /* GUTS */
  2355.           src2_alpha = INT_MULT(src2[alpha], *m, tmp);
  2356.           new_alpha = src1[alpha] +
  2357.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2358.           
  2359.           alphify (src2_alpha, new_alpha);
  2360.           
  2361.           if (mode_affect)
  2362.         {
  2363.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2364.         }
  2365.           else
  2366.         {
  2367.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2368.             (affect[alpha] ? new_alpha : src1[alpha]);      
  2369.         }
  2370.           
  2371.           m++;
  2372.           src1 += bytes;
  2373.           src2 += bytes;
  2374.           dest += bytes;    
  2375.           /* GUTS END */
  2376.         }
  2377.     }
  2378.       else /* HAS MASK, SEMI-OPACITY */
  2379.     {
  2380.       const int* mask_ip;
  2381.       int i,j;
  2382.  
  2383.       if (length >= sizeof(int))
  2384.         {
  2385.           /* HEAD */
  2386.           i = (((int)m) & (sizeof(int)-1));
  2387.           if (i != 0)
  2388.         {
  2389.           i = sizeof(int) - i;
  2390.           length -= i;
  2391.           while (i--)
  2392.             {
  2393.               /* GUTS */
  2394.               src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2395.               new_alpha = src1[alpha] +
  2396.             INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2397.           
  2398.               alphify (src2_alpha, new_alpha);
  2399.           
  2400.               if (mode_affect)
  2401.             {
  2402.               dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2403.             }
  2404.               else
  2405.             {
  2406.               dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2407.                 (affect[alpha] ? new_alpha : src1[alpha]);
  2408.             }
  2409.           
  2410.               m++;
  2411.               src1 += bytes;
  2412.               src2 += bytes;
  2413.               dest += bytes;
  2414.               /* GUTS END */
  2415.             }
  2416.         }
  2417.       
  2418.           /* BODY */
  2419.           mask_ip = (int*)m;
  2420.           i = length / sizeof(int);
  2421.           length %= sizeof(int);
  2422.           while (i--)
  2423.         {
  2424.           if (*mask_ip)
  2425.             {
  2426.               m = (const unsigned char*)mask_ip;
  2427.               j = sizeof(int);
  2428.               while (j--)
  2429.             {
  2430.               /* GUTS */
  2431.               src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2432.               new_alpha = src1[alpha] +
  2433.                 INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2434.               
  2435.               alphify (src2_alpha, new_alpha);
  2436.               
  2437.               if (mode_affect)
  2438.                 {
  2439.                   dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2440.                 }
  2441.               else
  2442.                 {
  2443.                   dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2444.                 (affect[alpha] ? new_alpha : src1[alpha]);
  2445.                 }
  2446.  
  2447.               m++;
  2448.               src1 += bytes;
  2449.               src2 += bytes;
  2450.               dest += bytes;
  2451.               /* GUTS END */
  2452.             }
  2453.             }
  2454.           else
  2455.             {
  2456.               j = bytes * sizeof(int);
  2457.               src2 += j;
  2458.               while (j--)
  2459.             {
  2460.               *(dest++) = *(src1++);
  2461.             }
  2462.             }
  2463.           mask_ip++;
  2464.         }
  2465.  
  2466.           m = (const unsigned char*)mask_ip;
  2467.         }
  2468.     
  2469.       /* TAIL */
  2470.       while (length--)
  2471.         {
  2472.           /* GUTS */
  2473.           src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2474.           new_alpha = src1[alpha] +
  2475.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2476.           
  2477.           alphify (src2_alpha, new_alpha);
  2478.           
  2479.           if (mode_affect)
  2480.         {
  2481.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2482.         }
  2483.           else
  2484.         {
  2485.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2486.             (affect[alpha] ? new_alpha : src1[alpha]);
  2487.         }
  2488.           
  2489.           m++;
  2490.           src1 += bytes;
  2491.           src2 += bytes;
  2492.           dest += bytes;
  2493.           /* GUTS END */
  2494.         }
  2495.     }
  2496.     }
  2497.   else
  2498.     {
  2499.       if (opacity == OPAQUE_OPACITY) /* NO MASK, FULL OPACITY */
  2500.     {
  2501.       while (length --)
  2502.         {
  2503.           src2_alpha = src2[alpha];
  2504.           new_alpha = src1[alpha] +
  2505.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2506.           
  2507.           alphify (src2_alpha, new_alpha);
  2508.           
  2509.           if (mode_affect)
  2510.         {
  2511.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2512.         }
  2513.           else
  2514.         {
  2515.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2516.             (affect[alpha] ? new_alpha : src1[alpha]);
  2517.         }
  2518.         
  2519.           src1 += bytes;
  2520.           src2 += bytes;
  2521.           dest += bytes;
  2522.         }
  2523.     }
  2524.       else /* NO MASK, SEMI OPACITY */
  2525.     {
  2526.       while (length --)
  2527.         {
  2528.           src2_alpha = INT_MULT(src2[alpha], opacity, tmp);
  2529.           new_alpha = src1[alpha] +
  2530.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2531.           
  2532.           alphify (src2_alpha, new_alpha);
  2533.           
  2534.           if (mode_affect)
  2535.         {
  2536.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2537.         }
  2538.           else
  2539.         {
  2540.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2541.             (affect[alpha] ? new_alpha : src1[alpha]);
  2542.         }
  2543.         
  2544.           src1 += bytes;
  2545.           src2 += bytes;
  2546.           dest += bytes;      
  2547.         }
  2548.     }
  2549.     }
  2550. }
  2551. #undef alphify
  2552.  
  2553. void
  2554. combine_inten_a_and_channel_mask_pixels (const unsigned char *src,
  2555.                      const unsigned char *channel,
  2556.                      unsigned char       *dest,
  2557.                      const unsigned char *col,
  2558.                      int                  opacity,
  2559.                      int                  length,
  2560.                      int                  bytes)
  2561. {
  2562.   int alpha, b;
  2563.   unsigned char channel_alpha;
  2564.   unsigned char new_alpha;
  2565.   unsigned char compl_alpha;
  2566.   int t, s;
  2567.  
  2568.   alpha = bytes - 1;
  2569.   while (length --)
  2570.     {
  2571.       channel_alpha = INT_MULT (255 - *channel, opacity, t);
  2572.       if (channel_alpha)
  2573.     {
  2574.       new_alpha = src[alpha] + INT_MULT ((255 - src[alpha]), channel_alpha, t);
  2575.  
  2576.       if (new_alpha != 255)
  2577.         channel_alpha = (channel_alpha * 255) / new_alpha;
  2578.       compl_alpha = 255 - channel_alpha;
  2579.  
  2580.       for (b = 0; b < alpha; b++)
  2581.         dest[b] = INT_MULT (col[b], channel_alpha, t) +
  2582.           INT_MULT (src[b], compl_alpha, s);
  2583.       dest[b] = new_alpha;
  2584.     }
  2585.       else
  2586.     memcpy(dest, src, bytes);
  2587.  
  2588.       /*  advance pointers  */
  2589.       src+=bytes;
  2590.       dest+=bytes;
  2591.       channel++;
  2592.     }
  2593. }
  2594.  
  2595.  
  2596. void
  2597. combine_inten_a_and_channel_selection_pixels (const unsigned char *src,
  2598.                           const unsigned char *channel,
  2599.                           unsigned char       *dest,
  2600.                           const unsigned char *col,
  2601.                           int                  opacity,
  2602.                           int                  length,
  2603.                           int                  bytes)
  2604. {
  2605.   int alpha, b;
  2606.   unsigned char channel_alpha;
  2607.   unsigned char new_alpha;
  2608.   unsigned char compl_alpha;
  2609.   int t, s;
  2610.  
  2611.   alpha = bytes - 1;
  2612.   while (length --)
  2613.     {
  2614.       channel_alpha = INT_MULT (*channel, opacity, t);
  2615.       if (channel_alpha)
  2616.     {
  2617.       new_alpha = src[alpha] + INT_MULT ((255 - src[alpha]), channel_alpha, t);
  2618.  
  2619.       if (new_alpha != 255)
  2620.         channel_alpha = (channel_alpha * 255) / new_alpha;
  2621.       compl_alpha = 255 - channel_alpha;
  2622.  
  2623.       for (b = 0; b < alpha; b++)
  2624.         dest[b] = INT_MULT (col[b], channel_alpha, t) +
  2625.           INT_MULT (src[b], compl_alpha, s);
  2626.       dest[b] = new_alpha;
  2627.     }
  2628.       else
  2629.     memcpy(dest, src, bytes);
  2630.  
  2631.       /*  advance pointers  */
  2632.       src+=bytes;
  2633.       dest+=bytes;
  2634.       channel++;
  2635.     }
  2636. }
  2637.  
  2638.  
  2639. void
  2640. behind_inten_pixels (const unsigned char *src1,
  2641.              const unsigned char *src2,
  2642.              unsigned char       *dest,
  2643.              const unsigned char *mask,
  2644.              int                  opacity,
  2645.              const int           *affect,
  2646.              int                  length,
  2647.              int                  bytes1,
  2648.              int                  bytes2,
  2649.              int                  has_alpha1,
  2650.              int                  has_alpha2)
  2651. {
  2652.   int alpha, b;
  2653.   unsigned char src1_alpha;
  2654.   unsigned char src2_alpha;
  2655.   unsigned char new_alpha;
  2656.   const unsigned char * m;
  2657.   float ratio, compl_ratio;
  2658.   long tmp;
  2659.   if (mask)
  2660.     m = mask;
  2661.   else
  2662.     m = &no_mask;
  2663.  
  2664.   /*  the alpha channel  */
  2665.   alpha = bytes1 - 1;
  2666.  
  2667.   while (length --)
  2668.     {
  2669.       src1_alpha = src1[alpha];
  2670.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2671.       new_alpha = src2_alpha +
  2672.     INT_MULT((255 - src2_alpha), src1_alpha, tmp);
  2673.       if (new_alpha)
  2674.     ratio = (float) src1_alpha / new_alpha;
  2675.       else
  2676.     ratio = 0.0;
  2677.       compl_ratio = 1.0 - ratio;
  2678.  
  2679.       for (b = 0; b < alpha; b++)
  2680.     dest[b] = (affect[b]) ?
  2681.       (unsigned char) (src1[b] * ratio + src2[b] * compl_ratio + EPSILON) :
  2682.     src1[b];
  2683.  
  2684.       dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2685.  
  2686.       if (mask)
  2687.     m++;
  2688.  
  2689.       src1 += bytes1;
  2690.       src2 += bytes2;
  2691.       dest += bytes1;
  2692.     }
  2693. }
  2694.  
  2695.  
  2696. void
  2697. behind_indexed_pixels (const unsigned char *src1,
  2698.                const unsigned char *src2,
  2699.                unsigned char       *dest,
  2700.                const unsigned char *mask,
  2701.                int                  opacity,
  2702.                const int           *affect,
  2703.                int                  length,
  2704.                int                  bytes1,
  2705.                int                  bytes2,
  2706.                int                  has_alpha1,
  2707.                int                  has_alpha2)
  2708. {
  2709.   int alpha, b;
  2710.   unsigned char src1_alpha;
  2711.   unsigned char src2_alpha;
  2712.   unsigned char new_alpha;
  2713.   const unsigned char * m;
  2714.   long tmp;
  2715.  
  2716.   if (mask)
  2717.     m = mask;
  2718.   else
  2719.     m = &no_mask;
  2720.  
  2721.   /*  the alpha channel  */
  2722.   alpha = bytes1 - 1;
  2723.  
  2724.   while (length --)
  2725.     {
  2726.       src1_alpha = src1[alpha];
  2727.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2728.       new_alpha = (src2_alpha > 127) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
  2729.  
  2730.       for (b = 0; b < bytes1; b++)
  2731.     dest[b] = (affect[b] && new_alpha == OPAQUE_OPACITY && (src1_alpha > 127)) ?
  2732.       src2[b] : src1[b];
  2733.  
  2734.       if (mask)
  2735.     m++;
  2736.  
  2737.       src1 += bytes1;
  2738.       src2 += bytes2;
  2739.       dest += bytes1;
  2740.     }
  2741. }
  2742.  
  2743.  
  2744. void
  2745. replace_inten_pixels (const unsigned char *src1,
  2746.               const unsigned char *src2,
  2747.               unsigned char       *dest,
  2748.               const unsigned char *mask,
  2749.               int                  opacity,
  2750.               const int           *affect,
  2751.               int                  length,
  2752.               int                  bytes1,
  2753.               int                  bytes2,
  2754.               int                  has_alpha1,
  2755.               int                  has_alpha2)
  2756. {
  2757.   int b;
  2758.   int tmp;
  2759.   const int bytes = MIN (bytes1, bytes2);
  2760.  
  2761.   if (mask)
  2762.     {
  2763.       unsigned char mask_alpha;
  2764.       const unsigned char *m = mask;
  2765.       while (length --)
  2766.         {
  2767.       mask_alpha = INT_MULT(*m, opacity, tmp);
  2768.       
  2769.       for (b = 0; b < bytes; b++)
  2770.         dest[b] = (affect[b]) ?
  2771.           INT_BLEND(src2[b], src1[b], mask_alpha, tmp) :
  2772.           src1[b];
  2773.  
  2774.       if (has_alpha1 && !has_alpha2)
  2775.         dest[b] = src1[b];
  2776.  
  2777.       m++;
  2778.  
  2779.       src1 += bytes1;
  2780.       src2 += bytes2;
  2781.       dest += bytes1;
  2782.     }
  2783.     }
  2784.   else
  2785.     {
  2786.       static const unsigned char mask_alpha = OPAQUE_OPACITY ;
  2787.  
  2788.       while (length --)
  2789.         {
  2790.       for (b = 0; b < bytes; b++)
  2791.         dest[b] = (affect[b]) ?
  2792.           INT_BLEND(src2[b], src1[b], mask_alpha, tmp) :
  2793.           src1[b];
  2794.  
  2795.       if (has_alpha1 && !has_alpha2)
  2796.         dest[b] = src1[b];
  2797.  
  2798.       src1 += bytes1;
  2799.       src2 += bytes2;
  2800.       dest += bytes1;
  2801.     }
  2802.     }
  2803. }
  2804.  
  2805.  
  2806. void
  2807. replace_indexed_pixels (const unsigned char *src1,
  2808.             const unsigned char *src2,
  2809.             unsigned char       *dest,
  2810.             const unsigned char *mask,
  2811.             int                  opacity,
  2812.             const int           *affect,
  2813.             int                  length,
  2814.             int                  bytes1,
  2815.             int                  bytes2,
  2816.             int                  has_alpha1,
  2817.             int                  has_alpha2)
  2818. {
  2819.   int bytes, b;
  2820.   unsigned char mask_alpha;
  2821.   const unsigned char * m;
  2822.   int tmp;
  2823.   if (mask)
  2824.     m = mask;
  2825.   else
  2826.     m = &no_mask;
  2827.  
  2828.   bytes = MIN (bytes1, bytes2);
  2829.   while (length --)
  2830.     {
  2831.       mask_alpha = INT_MULT(*m, opacity, tmp);
  2832.  
  2833.       for (b = 0; b < bytes; b++)
  2834.     dest[b] = (affect[b] && mask_alpha) ?
  2835.       src2[b] : src1[b];
  2836.  
  2837.       if (has_alpha1 && !has_alpha2)
  2838.     dest[b] = src1[b];
  2839.  
  2840.       if (mask)
  2841.     m++;
  2842.  
  2843.       src1 += bytes1;
  2844.       src2 += bytes2;
  2845.       dest += bytes1;
  2846.     }
  2847. }
  2848.  
  2849.  
  2850. void
  2851. erase_inten_pixels (const unsigned char *src1,
  2852.             const unsigned char *src2,
  2853.             unsigned char       *dest,
  2854.             const unsigned char *mask,
  2855.             int                  opacity,
  2856.             const int           *affect,
  2857.             int                  length,
  2858.             int                  bytes)
  2859. {
  2860.   int b;
  2861.   unsigned char src2_alpha;
  2862.   long tmp;
  2863.   const int alpha = bytes - 1;
  2864.  
  2865.   if (mask)
  2866.     {
  2867.       const unsigned char *m = mask;
  2868.  
  2869.       while (length --)
  2870.         {
  2871.       for (b = 0; b < alpha; b++)
  2872.         dest[b] = src1[b];
  2873.  
  2874.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2875.       dest[alpha] = src1[alpha] - INT_MULT(src1[alpha], src2_alpha, tmp);
  2876.  
  2877.       m++;
  2878.  
  2879.       src1 += bytes;
  2880.       src2 += bytes;
  2881.       dest += bytes;
  2882.     }
  2883.     }
  2884.   else
  2885.     {
  2886.       unsigned char *m = &no_mask;
  2887.  
  2888.       while (length --)
  2889.         {
  2890.       for (b = 0; b < alpha; b++)
  2891.         dest[b] = src1[b];
  2892.  
  2893.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2894.       dest[alpha] = src1[alpha] - INT_MULT(src1[alpha], src2_alpha, tmp);
  2895.  
  2896.       src1 += bytes;
  2897.       src2 += bytes;
  2898.       dest += bytes;
  2899.     }
  2900.     }
  2901. }
  2902.  
  2903.  
  2904. void
  2905. erase_indexed_pixels (const unsigned char *src1,
  2906.               const unsigned char *src2,
  2907.               unsigned char       *dest,
  2908.               const unsigned char *mask,
  2909.               int                  opacity,
  2910.               const int           *affect,
  2911.               int                  length,
  2912.               int                  bytes)
  2913. {
  2914.   int alpha, b;
  2915.   unsigned char src2_alpha;
  2916.   const unsigned char * m;
  2917.   long tmp;
  2918.   if (mask)
  2919.     m = mask;
  2920.   else
  2921.     m = &no_mask;
  2922.  
  2923.   alpha = bytes - 1;
  2924.   while (length --)
  2925.     {
  2926.       for (b = 0; b < alpha; b++)
  2927.     dest[b] = src1[b];
  2928.  
  2929.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2930.       dest[alpha] = (src2_alpha > 127) ? TRANSPARENT_OPACITY : src1[alpha];
  2931.  
  2932.       if (mask)
  2933.     m++;
  2934.  
  2935.       src1 += bytes;
  2936.       src2 += bytes;
  2937.       dest += bytes;
  2938.     }
  2939. }
  2940.  
  2941. void
  2942. anti_erase_inten_pixels (const unsigned char *src1,
  2943.              const unsigned char *src2,
  2944.              unsigned char       *dest,
  2945.              const unsigned char *mask,
  2946.              int                  opacity,
  2947.              const int           *affect,
  2948.              int                  length,
  2949.              int                  bytes)
  2950. {
  2951.   int alpha, b;
  2952.   unsigned char src2_alpha;
  2953.   const unsigned char * m;
  2954.   long tmp;
  2955.  
  2956.   if (mask)
  2957.     m = mask;
  2958.   else
  2959.     m = &no_mask;
  2960.  
  2961.   alpha = bytes - 1;
  2962.   while (length --)
  2963.     {
  2964.       for (b = 0; b < alpha; b++)
  2965.     dest[b] = src1[b];
  2966.  
  2967.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2968.       dest[alpha] = src1[alpha] + INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2969.  
  2970.       if (mask)
  2971.     m++;
  2972.  
  2973.       src1 += bytes;
  2974.       src2 += bytes;
  2975.       dest += bytes;
  2976.     }
  2977. }
  2978.  
  2979. void
  2980. anti_erase_indexed_pixels (const unsigned char *src1,
  2981.                const unsigned char *src2,
  2982.                unsigned char       *dest,
  2983.                const unsigned char *mask,
  2984.                int                  opacity,
  2985.                const int           *affect,
  2986.                int                  length,
  2987.                int                  bytes)
  2988. {
  2989.   int alpha, b;
  2990.   unsigned char src2_alpha;
  2991.   const unsigned char * m;
  2992.   long tmp;
  2993.   if (mask)
  2994.     m = mask;
  2995.   else
  2996.     m = &no_mask;
  2997.  
  2998.   alpha = bytes - 1;
  2999.   while (length --)
  3000.     {
  3001.       for (b = 0; b < alpha; b++)
  3002.     dest[b] = src1[b];
  3003.  
  3004.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  3005.       dest[alpha] = (src2_alpha > 127) ? OPAQUE_OPACITY : src1[alpha];
  3006.  
  3007.       if (mask)
  3008.     m++;
  3009.  
  3010.       src1 += bytes;
  3011.       src2 += bytes;
  3012.       dest += bytes;
  3013.     }
  3014. }
  3015.  
  3016.  
  3017. void
  3018. extract_from_inten_pixels (unsigned char *src,
  3019.                unsigned char       *dest,
  3020.                const unsigned char *mask,
  3021.                const unsigned char *bg,
  3022.                int                  cut,
  3023.                int                  length,
  3024.                int                  bytes,
  3025.                int                  has_alpha)
  3026. {
  3027.   int b, alpha;
  3028.   int dest_bytes;
  3029.   const unsigned char * m;
  3030.   int tmp;
  3031.   if (mask)
  3032.     m = mask;
  3033.   else
  3034.     m = &no_mask;
  3035.  
  3036.   alpha = (has_alpha) ? bytes - 1 : bytes;
  3037.   dest_bytes = (has_alpha) ? bytes : bytes + 1;
  3038.   while (length --)
  3039.     {
  3040.       for (b = 0; b < alpha; b++)
  3041.     dest[b] = src[b];
  3042.  
  3043.       if (has_alpha)
  3044.     {
  3045.       dest[alpha] = INT_MULT(*m, src[alpha], tmp);
  3046.       if (cut)
  3047.         src[alpha] = INT_MULT((255 - *m), src[alpha], tmp);
  3048.     }
  3049.       else
  3050.     {
  3051.       dest[alpha] = *m;
  3052.       if (cut)
  3053.         for (b = 0; b < bytes; b++)
  3054.           src[b] = INT_BLEND(bg[b], src[b], *m, tmp);
  3055.     }
  3056.  
  3057.       if (mask)
  3058.     m++;
  3059.  
  3060.       src += bytes;
  3061.       dest += dest_bytes;
  3062.     }
  3063. }
  3064.  
  3065.  
  3066. void
  3067. extract_from_indexed_pixels (unsigned char       *src,
  3068.                  unsigned char       *dest,
  3069.                  const unsigned char *mask,
  3070.                  const unsigned char *cmap,
  3071.                  const unsigned char *bg,
  3072.                  int                  cut,
  3073.                  int                  length,
  3074.                  int                  bytes,
  3075.                  int                  has_alpha)
  3076. {
  3077.   int b;
  3078.   int index;
  3079.   const unsigned char * m;
  3080.   int t;
  3081.  
  3082.   if (mask)
  3083.     m = mask;
  3084.   else
  3085.     m = &no_mask;
  3086.  
  3087.   while (length --)
  3088.     {
  3089.       index = src[0] * 3;
  3090.       for (b = 0; b < 3; b++)
  3091.     dest[b] = cmap[index + b];
  3092.  
  3093.       if (has_alpha)
  3094.     {
  3095.       dest[3] = INT_MULT (*m, src[1], t);
  3096.       if (cut)
  3097.         src[1] = INT_MULT ((255 - *m), src[1], t);
  3098.     }
  3099.       else
  3100.     {
  3101.       dest[3] = *m;
  3102.       if (cut)
  3103.         src[0] = (*m > 127) ? bg[0] : src[0];
  3104.     }
  3105.  
  3106.       if (mask)
  3107.     m++;
  3108.  
  3109.       src += bytes;
  3110.       dest += 4;
  3111.     }
  3112. }
  3113.  
  3114.  
  3115. void
  3116. map_to_color (int                  src_type,
  3117.           const unsigned char *cmap,
  3118.           const unsigned char *src,
  3119.           unsigned char       *rgb)
  3120. {
  3121.   switch (src_type)
  3122.     {
  3123.     case 0:  /*  RGB      */
  3124.       /*  Straight copy  */
  3125.       *rgb++ = *src++;
  3126.       *rgb++ = *src++;
  3127.       *rgb   = *src;
  3128.       break;
  3129.     case 1:  /*  GRAY     */
  3130.       *rgb++ = *src;
  3131.       *rgb++ = *src;
  3132.       *rgb   = *src;
  3133.       break;
  3134.     case 2:  /*  INDEXED  */
  3135.       {
  3136.     int index = *src * 3;
  3137.     *rgb++ = cmap [index++];
  3138.     *rgb++ = cmap [index++];
  3139.     *rgb   = cmap [index++];
  3140.       }
  3141.       break;
  3142.     }
  3143. }
  3144.  
  3145.  
  3146. int
  3147. map_rgb_to_indexed (const unsigned char *cmap,
  3148.             int            num_cols,
  3149.             GimpImage*     gimage,
  3150.             int            r,
  3151.             int            g,
  3152.             int            b)
  3153. {
  3154.   unsigned int pixel;
  3155.   int hash_index;
  3156.   int cmap_index;
  3157.  
  3158.   pixel = (r << 16) | (g << 8) | b;
  3159.   hash_index = pixel % HASH_TABLE_SIZE;
  3160.  
  3161.   /*  Hash table lookup hit  */
  3162.   if (color_hash_table[hash_index].gimage == gimage &&
  3163.       color_hash_table[hash_index].pixel == pixel)
  3164.     {
  3165.       cmap_index = color_hash_table[hash_index].index;
  3166.       color_hash_hits++;
  3167.     }
  3168.   /*  Hash table lookup miss  */
  3169.   else
  3170.     {
  3171.       const unsigned char *col;
  3172.       int diff, sum, max;
  3173.       int i;
  3174.  
  3175.       max = MAXDIFF;
  3176.       cmap_index = 0;
  3177.  
  3178.       col = cmap;
  3179.       for (i = 0; i < num_cols; i++)
  3180.     {
  3181.       diff = r - *col++;
  3182.       sum = diff * diff;
  3183.       diff = g - *col++;
  3184.       sum += diff * diff;
  3185.       diff = b - *col++;
  3186.       sum += diff * diff;
  3187.  
  3188.       if (sum < max)
  3189.         {
  3190.           cmap_index = i;
  3191.           max = sum;
  3192.         }
  3193.     }
  3194.  
  3195.       /*  update the hash table  */
  3196.       color_hash_table[hash_index].pixel = pixel;
  3197.       color_hash_table[hash_index].index = cmap_index;
  3198.       color_hash_table[hash_index].gimage = gimage;
  3199.       color_hash_misses++;
  3200.     }
  3201.  
  3202.   return cmap_index;
  3203. }
  3204.  
  3205.  
  3206.  
  3207. /**************************************************/
  3208. /*    REGION FUNCTIONS                            */
  3209. /**************************************************/
  3210.  
  3211. void
  3212. color_region (PixelRegion   *dest,
  3213.           const unsigned char *col)
  3214. {
  3215.   int h;
  3216.   unsigned char * s;
  3217.   void * pr;
  3218.  
  3219.   for (pr = pixel_regions_register (1, dest); pr != NULL; pr = pixel_regions_process (pr))
  3220.     {
  3221.       h = dest->h;
  3222.       s = dest->data;
  3223.  
  3224.       if (dest->w*dest->bytes == dest->rowstride)
  3225.       {
  3226.     /* do it all in one function call if we can */
  3227.     /* this hasn't been tested to see if it is a
  3228.        signifigant speed gain yet */
  3229.     color_pixels (s, col, dest->w*h, dest->bytes);
  3230.       }
  3231.       else
  3232.       {
  3233.     while (h--)
  3234.     {
  3235.       color_pixels (s, col, dest->w, dest->bytes);
  3236.       s += dest->rowstride;
  3237.     }
  3238.       }
  3239.     }
  3240. }
  3241.  
  3242.  
  3243. void
  3244. blend_region (PixelRegion *src1,
  3245.           PixelRegion *src2,
  3246.           PixelRegion *dest,
  3247.           int          blend)
  3248. {
  3249.   int h;
  3250.   unsigned char *s1, *s2, * d;
  3251.   void * pr;
  3252.  
  3253.   for (pr = pixel_regions_register (3, src1, src2, dest); pr != NULL; pr = pixel_regions_process (pr))
  3254.     {
  3255.       s1 = src1->data;
  3256.       s2 = src2->data;
  3257.       d = dest->data;
  3258.       h = src1->h;
  3259.  
  3260.       while (h --)
  3261.     {
  3262.           blend_pixels (s1, s2, d, blend, src1->w, src1->bytes, FALSE);
  3263.       s1 += src1->rowstride;
  3264.       s2 += src2->rowstride;
  3265.       d += dest->rowstride;
  3266.     }
  3267.     }
  3268. }
  3269.  
  3270.  
  3271. void
  3272. shade_region (PixelRegion   *src,
  3273.           PixelRegion   *dest,
  3274.           unsigned char *col,
  3275.           int            blend)
  3276. {
  3277.   int h;
  3278.   unsigned char * s, * d;
  3279.  
  3280.   s = src->data;
  3281.   d = dest->data;
  3282.   h = src->h;
  3283.  
  3284.   while (h --)
  3285.     {
  3286. /*      blend_pixels (s, d, col, blend, src->w, src->bytes);*/
  3287.       s += src->rowstride;
  3288.       d += dest->rowstride;
  3289.     }
  3290. }
  3291.  
  3292.  
  3293.  
  3294. void
  3295. copy_region (PixelRegion *src,
  3296.          PixelRegion *dest)
  3297. {
  3298.   int h;
  3299.   int pixelwidth;
  3300.   unsigned char * s, * d;
  3301.   void * pr;
  3302.  
  3303. #ifdef COWSHOW
  3304.   fputc('[',stderr);
  3305. #endif
  3306.   for (pr = pixel_regions_register (2, src, dest);
  3307.        pr != NULL;
  3308.        pr = pixel_regions_process (pr))
  3309.     {
  3310.       if (src->tiles && dest->tiles &&
  3311.       src->curtile && dest->curtile &&
  3312.       src->offx == 0 && dest->offx == 0 &&
  3313.       src->offy == 0 && dest->offy == 0 &&
  3314.       src->w == (src->curtile->ewidth) && 
  3315.       dest->w == (dest->curtile->ewidth) &&
  3316.       src->h == tile_eheight(src->curtile) && 
  3317.       dest->h == tile_eheight(dest->curtile)) 
  3318.     {
  3319. #ifdef COWSHOW
  3320.       fputc('!',stderr);
  3321. #endif
  3322.       tile_manager_map_over_tile (dest->tiles, dest->curtile, src->curtile);
  3323.     }
  3324.       else 
  3325.     {
  3326. #ifdef COWSHOW
  3327.       fputc('.',stderr);
  3328. #endif
  3329.       pixelwidth = src->w * src->bytes;
  3330.       s = src->data;
  3331.       d = dest->data;
  3332.       h = src->h;
  3333.       
  3334.       while (h --)
  3335.         {
  3336.           memcpy (d, s, pixelwidth);
  3337.           s += src->rowstride;
  3338.           d += dest->rowstride;
  3339.         }
  3340.     }
  3341.     }
  3342. #ifdef COWSHOW
  3343.   fputc(']',stderr);
  3344.   fputc('\n',stderr);
  3345. #endif
  3346. }
  3347.  
  3348.  
  3349. void
  3350. add_alpha_region (PixelRegion *src,
  3351.           PixelRegion *dest)
  3352. {
  3353.   int h;
  3354.   unsigned char * s, * d;
  3355.   void * pr;
  3356.  
  3357.   for (pr = pixel_regions_register (2, src, dest); pr != NULL; pr = pixel_regions_process (pr))
  3358.     {
  3359.       s = src->data;
  3360.       d = dest->data;
  3361.       h = src->h;
  3362.  
  3363.       while (h --)
  3364.     {
  3365.       add_alpha_pixels (s, d, src->w, src->bytes);
  3366.       s += src->rowstride;
  3367.       d += dest->rowstride;
  3368.     }
  3369.     }
  3370. }
  3371.  
  3372.  
  3373. void
  3374. flatten_region (PixelRegion   *src,
  3375.         PixelRegion   *dest,
  3376.         unsigned char *bg)
  3377. {
  3378.   int h;
  3379.   unsigned char * s, * d;
  3380.  
  3381.   s = src->data;
  3382.   d = dest->data;
  3383.   h = src->h;
  3384.  
  3385.   while (h --)
  3386.     {
  3387.       flatten_pixels (s, d, bg, src->w, src->bytes);
  3388.       s += src->rowstride;
  3389.       d += dest->rowstride;
  3390.     }
  3391. }
  3392.  
  3393.  
  3394. void
  3395. extract_alpha_region (PixelRegion *src,
  3396.               PixelRegion *mask,
  3397.               PixelRegion *dest)
  3398. {
  3399.   int h;
  3400.   unsigned char * s, * m, * d;
  3401.   void * pr;
  3402.  
  3403.   for (pr = pixel_regions_register (3, src, mask, dest); pr != NULL; pr = pixel_regions_process (pr))
  3404.     {
  3405.       s = src->data;
  3406.       d = dest->data;
  3407.       if (mask)
  3408.     m = mask->data;
  3409.       else
  3410.     m = NULL;
  3411.  
  3412.       h = src->h;
  3413.       while (h --)
  3414.     {
  3415.       extract_alpha_pixels (s, m, d, src->w, src->bytes);
  3416.       s += src->rowstride;
  3417.       d += dest->rowstride;
  3418.       if (mask)
  3419.         m += mask->rowstride;
  3420.     }
  3421.     }
  3422. }
  3423.  
  3424.  
  3425. void
  3426. extract_from_region (PixelRegion   *src,
  3427.              PixelRegion   *dest,
  3428.              PixelRegion   *mask,
  3429.              unsigned char *cmap,
  3430.              unsigned char *bg,
  3431.              int            type,
  3432.              int            has_alpha,
  3433.              int            cut)
  3434. {
  3435.   int h;
  3436.   unsigned char * s, * d, * m;
  3437.   void * pr;
  3438.  
  3439.   for (pr = pixel_regions_register (3, src, dest, mask); pr != NULL; pr = pixel_regions_process (pr))
  3440.     {
  3441.       s = src->data;
  3442.       d = dest->data;
  3443.       m = (mask) ? mask->data : NULL;
  3444.       h = src->h;
  3445.  
  3446.       while (h --)
  3447.     {
  3448.       switch (type)
  3449.         {
  3450.         case 0:  /*  RGB      */
  3451.         case 1:  /*  GRAY     */
  3452.           extract_from_inten_pixels (s, d, m, bg, cut, src->w,
  3453.                      src->bytes, has_alpha);
  3454.           break;
  3455.         case 2:  /*  INDEXED  */
  3456.           extract_from_indexed_pixels (s, d, m, cmap, bg, cut, src->w,
  3457.                        src->bytes, has_alpha);
  3458.           break;
  3459.         }
  3460.  
  3461.       s += src->rowstride;
  3462.       d += dest->rowstride;
  3463.       if (mask)
  3464.         m += mask->rowstride;
  3465.     }
  3466.     }
  3467. }
  3468.  
  3469.  
  3470. void
  3471. convolve_region (PixelRegion    *srcR,
  3472.          PixelRegion    *destR,
  3473.          int        *matrix,
  3474.          int         size,
  3475.          int         divisor,
  3476.          ConvolutionType mode)
  3477. {
  3478.   /*  Convolve the src image using the convolution matrix, writing to dest  */
  3479.   /*  Convolve is not tile-enabled--use accordingly  */
  3480.   unsigned char *src, *s_row, * s;
  3481.   unsigned char *dest, * d;
  3482.   int * m;
  3483.   int total [4];
  3484.   int b, bytes;
  3485.   int length;
  3486.   int wraparound;
  3487.   int margin;      /*  margin imposed by size of conv. matrix  */
  3488.   int i, j;
  3489.   int x, y;
  3490.   int offset;
  3491.  
  3492.   /*  If the mode is NEGATIVE_CONVOL, the offset should be 128  */
  3493.   if (mode == NEGATIVE_CONVOL)
  3494.     {
  3495.       offset = 128;
  3496.       mode = NORMAL_CONVOL;
  3497.     }
  3498.   else
  3499.     offset = 0;
  3500.  
  3501.   /*  check for the boundary cases  */
  3502.   if (srcR->w < (size - 1) || srcR->h < (size - 1))
  3503.     return;
  3504.  
  3505.   /*  Initialize some values  */
  3506.   bytes = srcR->bytes;
  3507.   length = bytes * srcR->w;
  3508.   margin = size / 2;
  3509.   src = srcR->data;
  3510.   dest = destR->data;
  3511.  
  3512.   /*  calculate the source wraparound value  */
  3513.   wraparound = srcR->rowstride - size * bytes;
  3514.  
  3515.   /* copy the first (size / 2) scanlines of the src image... */
  3516.   for (i = 0; i < margin; i++)
  3517.     {
  3518.       memcpy (dest, src, length);
  3519.       src += srcR->rowstride;
  3520.       dest += destR->rowstride;
  3521.     }
  3522.  
  3523.   src = srcR->data;
  3524.  
  3525.   for (y = margin; y < srcR->h - margin; y++)
  3526.     {
  3527.       s_row = src;
  3528.       s = s_row + srcR->rowstride*margin;
  3529.       d = dest;
  3530.  
  3531.       /* handle the first margin pixels... */
  3532.       b = bytes * margin;
  3533.       while (b --)
  3534.     *d++ = *s++;
  3535.  
  3536.       /* now, handle the center pixels */
  3537.       x = srcR->w - margin*2;
  3538.       while (x--)
  3539.     {
  3540.       s = s_row;
  3541.  
  3542.       m = matrix;
  3543.       total [0] = total [1] = total [2] = total [3] = 0;
  3544.       i = size;
  3545.       while (i --)
  3546.         {
  3547.           j = size;
  3548.           while (j --)
  3549.         {
  3550.           for (b = 0; b < bytes; b++)
  3551.             total [b] += *m * *s++;
  3552.           m ++;
  3553.         }
  3554.  
  3555.           s += wraparound;
  3556.         }
  3557.  
  3558.       for (b = 0; b < bytes; b++)
  3559.         {
  3560.           total [b] = total [b] / divisor + offset;
  3561.  
  3562.           if (total [b] < 0 && mode != NORMAL_CONVOL)
  3563.         total [b] = - total [b];
  3564.  
  3565.           if (total [b] < 0)
  3566.         *d++ = 0;
  3567.           else
  3568.         *d++ = (total [b] > 255) ? 255 : (unsigned char) total [b];
  3569.         }
  3570.  
  3571.       s_row += bytes;
  3572.  
  3573.     }
  3574.  
  3575.       /* handle the last pixel... */
  3576.       s = s_row + (srcR->rowstride + bytes) * margin;
  3577.       b = bytes * margin;
  3578.       while (b --)
  3579.     *d++ = *s++;
  3580.  
  3581.       /* set the memory pointers */
  3582.       src += srcR->rowstride;
  3583.       dest += destR->rowstride;
  3584.     }
  3585.  
  3586.   src += srcR->rowstride*margin;
  3587.  
  3588.   /* copy the last (margin) scanlines of the src image... */
  3589.   for (i = 0; i < margin; i++)
  3590.     {
  3591.       memcpy (dest, src, length);
  3592.       src += srcR->rowstride;
  3593.       dest += destR->rowstride;
  3594.     }
  3595. }
  3596.  
  3597. /* Convert from separated alpha to premultiplied alpha. Only works on
  3598.    non-tiled regions! */
  3599. void
  3600. multiply_alpha_region (PixelRegion *srcR)
  3601. {
  3602.   unsigned char *src, *s;
  3603.   int x, y;
  3604.   int width, height;
  3605.   int b, bytes;
  3606.   double alpha_val;
  3607.  
  3608.   width = srcR->w;
  3609.   height = srcR->h;
  3610.   bytes = srcR->bytes;
  3611.  
  3612.   src = srcR->data;
  3613.  
  3614.   for (y = 0; y < height; y++)
  3615.     {
  3616.       s = src;
  3617.       for (x = 0; x < width; x++)
  3618.     {
  3619.       alpha_val = s[bytes - 1] * (1.0 / 255.0);
  3620.       for (b = 0; b < bytes - 1; b++)
  3621.         s[b] = 0.5 + s[b] * alpha_val;
  3622.       s += bytes;
  3623.     }
  3624.       src += srcR->rowstride;
  3625.     }
  3626. }
  3627.  
  3628. /* Convert from premultiplied alpha to separated alpha. Only works on
  3629.    non-tiled regions! */
  3630. void
  3631. separate_alpha_region (PixelRegion *srcR)
  3632. {
  3633.   unsigned char *src, *s;
  3634.   int x, y;
  3635.   int width, height;
  3636.   int b, bytes;
  3637.   double alpha_recip;
  3638.   int new_val;
  3639.  
  3640.   width = srcR->w;
  3641.   height = srcR->h;
  3642.   bytes = srcR->bytes;
  3643.  
  3644.   src = srcR->data;
  3645.  
  3646.   for (y = 0; y < height; y++)
  3647.     {
  3648.       s = src;
  3649.       for (x = 0; x < width; x++)
  3650.     {
  3651.       /* predicate is equivalent to:
  3652.          (((s[bytes - 1] - 1) & 255) + 2) & 256
  3653.          */
  3654.       if (s[bytes - 1] != 0 && s[bytes - 1] != 255)
  3655.         {
  3656.           alpha_recip = 255.0 / s[bytes - 1];
  3657.           for (b = 0; b < bytes - 1; b++)
  3658.         {
  3659.           new_val = 0.5 + s[b] * alpha_recip;
  3660.           new_val = MIN (new_val, 255);
  3661.           s[b] = new_val;
  3662.         }
  3663.         }
  3664.       s += bytes;
  3665.     }
  3666.       src += srcR->rowstride;
  3667.     }
  3668. }
  3669.  
  3670. void
  3671. gaussian_blur_region (PixelRegion *srcR,
  3672.               double       radius_x,
  3673.               double       radius_y)
  3674. {
  3675.   double std_dev;
  3676.   long width, height;
  3677.   int bytes;
  3678.   unsigned char *src, *sp;
  3679.   unsigned char *dest, *dp;
  3680.   unsigned char *data;
  3681.   int *buf, *b;
  3682.   int pixels;
  3683.   int total;
  3684.   int i, row, col;
  3685.   int start, end;
  3686.   int *curve;
  3687.   int *sum;
  3688.   int val;
  3689.   int length;
  3690.   int alpha;
  3691.   int initial_p, initial_m;
  3692.  
  3693.   if (radius_x == 0.0 && radius_y == 0.0) return;    /* zero blur is a no-op */
  3694.  
  3695.   /*  allocate the result buffer  */
  3696.   length = MAX (srcR->w, srcR->h) * srcR->bytes;
  3697.   data = paint_funcs_get_buffer (length * 2);
  3698.   src = data;
  3699.   dest = data + length;
  3700.  
  3701.   width = srcR->w;
  3702.   height = srcR->h;
  3703.   bytes = srcR->bytes;
  3704.   alpha = bytes - 1;
  3705.  
  3706.   buf = g_malloc (sizeof (int) * MAX (width, height) * 2);
  3707.  
  3708.   if (radius_y != 0.0)
  3709.     {
  3710.       std_dev = sqrt (-(radius_y * radius_y) / (2 * log (1.0 / 255.0)));
  3711.       curve = make_curve (std_dev, &length);
  3712.       sum = g_malloc (sizeof (int) * (2 * length + 1));
  3713.       sum[0] = 0;
  3714.  
  3715.       for (i = 1; i <= length*2; i++)
  3716.     sum[i] = curve[i-length-1] + sum[i-1];
  3717.       sum += length;
  3718.  
  3719.       total = sum[length] - sum[-length];
  3720.  
  3721.       for (col = 0; col < width; col++)
  3722.     {
  3723.       pixel_region_get_col (srcR, col + srcR->x, srcR->y, height, src, 1);
  3724.       sp = src + alpha;
  3725.  
  3726.       initial_p = sp[0];
  3727.       initial_m = sp[(height-1) * bytes];
  3728.  
  3729.       /*  Determine a run-length encoded version of the column  */
  3730.       run_length_encode (sp, buf, height, bytes);
  3731.  
  3732.       for (row = 0; row < height; row++)
  3733.         {
  3734.           start = (row < length) ? -row : -length;
  3735.           end = (height <= (row + length)) ? (height - row - 1) : length;
  3736.  
  3737.           val = 0;
  3738.           i = start;
  3739.           b = buf + (row + i) * 2;
  3740.  
  3741.           if (start != -length)
  3742.         val += initial_p * (sum[start] - sum[-length]);
  3743.  
  3744.           while (i < end)
  3745.         {
  3746.           pixels = b[0];
  3747.           i += pixels;
  3748.           if (i > end)
  3749.             i = end;
  3750.           val += b[1] * (sum[i] - sum[start]);
  3751.           b += (pixels * 2);
  3752.           start = i;
  3753.         }
  3754.  
  3755.           if (end != length)
  3756.         val += initial_m * (sum[length] - sum[end]);
  3757.  
  3758.           sp[row * bytes] = val / total;
  3759.         }
  3760.  
  3761.       pixel_region_set_col (srcR, col + srcR->x, srcR->y, height, src);
  3762.     }
  3763.  
  3764.       g_free (sum - length);
  3765.       g_free (curve - length);
  3766.     }
  3767.  
  3768.   if (radius_x != 0.0)
  3769.     {
  3770.       std_dev = sqrt (-(radius_x * radius_x) / (2 * log (1.0 / 255.0)));
  3771.       curve = make_curve (std_dev, &length);
  3772.       sum = g_malloc (sizeof (int) * (2 * length + 1));
  3773.       sum[0] = 0;
  3774.  
  3775.       for (i = 1; i <= length*2; i++)
  3776.     sum[i] = curve[i-length-1] + sum[i-1];
  3777.       sum += length;
  3778.  
  3779.       total = sum[length] - sum[-length];
  3780.  
  3781.       for (row = 0; row < height; row++)
  3782.     {
  3783.       pixel_region_get_row (srcR, srcR->x, row + srcR->y, width, src, 1);
  3784.       sp = src + alpha;
  3785.       dp = dest + alpha;
  3786.  
  3787.       initial_p = sp[0];
  3788.       initial_m = sp[(width-1) * bytes];
  3789.  
  3790.       /*  Determine a run-length encoded version of the row  */
  3791.       run_length_encode (sp, buf, width, bytes);
  3792.  
  3793.       for (col = 0; col < width; col++)
  3794.         {
  3795.           start = (col < length) ? -col : -length;
  3796.           end = (width <= (col + length)) ? (width - col - 1) : length;
  3797.  
  3798.           val = 0;
  3799.           i = start;
  3800.           b = buf + (col + i) * 2;
  3801.  
  3802.           if (start != -length)
  3803.         val += initial_p * (sum[start] - sum[-length]);
  3804.  
  3805.           while (i < end)
  3806.         {
  3807.           pixels = b[0];
  3808.           i += pixels;
  3809.           if (i > end)
  3810.             i = end;
  3811.           val += b[1] * (sum[i] - sum[start]);
  3812.           b += (pixels * 2);
  3813.           start = i;
  3814.         }
  3815.  
  3816.           if (end != length)
  3817.         val += initial_m * (sum[length] - sum[end]);
  3818.  
  3819.           val = val / total;
  3820.  
  3821.           dp[col * bytes] = val;
  3822.         }
  3823.       
  3824.       pixel_region_set_row (srcR, srcR->x, row + srcR->y, width, dest);
  3825.     }
  3826.  
  3827.       g_free (sum - length);
  3828.       g_free (curve - length);
  3829.     }
  3830.  
  3831.   g_free (buf);
  3832. }
  3833.  
  3834.  
  3835. /* non-interpolating scale_region.  [adam]
  3836.  */
  3837. void
  3838. scale_region_no_resample (PixelRegion *srcPR,
  3839.               PixelRegion *destPR)
  3840. {
  3841.   int * x_src_offsets;
  3842.   int * y_src_offsets;
  3843.   unsigned char * src;
  3844.   unsigned char * dest;
  3845.   int width, height, orig_width, orig_height;
  3846.   int last_src_y;
  3847.   int row_bytes;
  3848.   int x,y,b;
  3849.   char bytes;
  3850.  
  3851.   orig_width = srcPR->w;
  3852.   orig_height = srcPR->h;
  3853.  
  3854.   width = destPR->w;
  3855.   height = destPR->h;
  3856.  
  3857.   bytes = srcPR->bytes;
  3858.  
  3859.   /*  the data pointers...  */
  3860.   x_src_offsets = (int *) g_malloc (width * bytes * sizeof(int));
  3861.   y_src_offsets = (int *) g_malloc (height * sizeof(int));
  3862.   src  = (unsigned char *) g_malloc (orig_width * bytes);
  3863.   dest = (unsigned char *) g_malloc (width * bytes);
  3864.   
  3865.   /*  pre-calc the scale tables  */
  3866.   for (b = 0; b < bytes; b++)
  3867.     {
  3868.       for (x = 0; x < width; x++)
  3869.     {
  3870.       x_src_offsets [b + x * bytes] = b + bytes * ((x * orig_width + orig_width / 2) / width);
  3871.     }
  3872.     }
  3873.   for (y = 0; y < height; y++)
  3874.     {
  3875.       y_src_offsets [y] = (y * orig_height + orig_height / 2) / height;
  3876.     }
  3877.   
  3878.   /*  do the scaling  */
  3879.   row_bytes = width * bytes;
  3880.   last_src_y = -1;
  3881.   for (y = 0; y < height; y++)
  3882.     {
  3883.       /* if the source of this line was the same as the source
  3884.        *  of the last line, there's no point in re-rescaling.
  3885.        */
  3886.       if (y_src_offsets[y] != last_src_y)
  3887.     {
  3888.       pixel_region_get_row (srcPR, 0, y_src_offsets[y], orig_width, src, 1);
  3889.       for (x = 0; x < row_bytes ; x++)
  3890.         {
  3891.           dest[x] = src[x_src_offsets[x]];
  3892.         }
  3893.       last_src_y = y_src_offsets[y];
  3894.     }
  3895.  
  3896.       pixel_region_set_row (destPR, 0, y, width, dest);
  3897.     }
  3898.   
  3899.   g_free (x_src_offsets);
  3900.   g_free (y_src_offsets);
  3901.   g_free (src);
  3902.   g_free (dest);
  3903. }
  3904.  
  3905.  
  3906. static void
  3907. get_premultiplied_double_row(PixelRegion *srcPR, int x, int y,
  3908.                  int w, double *row, guchar *tmp_src, int n)
  3909. {
  3910.   int b;
  3911.   int bytes = srcPR->bytes;
  3912.   pixel_region_get_row (srcPR, x, y, w, tmp_src, n);
  3913.   if (pixel_region_has_alpha(srcPR))
  3914.   { /* premultiply the alpha into the double array */
  3915.     double *irow = row;
  3916.     int alpha = bytes - 1;
  3917.     double mod_alpha;
  3918.     for (x = 0; x < w; x++)
  3919.     {
  3920.       mod_alpha = tmp_src[alpha] / 255.0;
  3921.       for (b = 0; b < alpha; b++)
  3922.     irow[b] = mod_alpha * tmp_src[b];
  3923.       irow[b] = tmp_src[alpha];
  3924.       irow += bytes;
  3925.       tmp_src += bytes;
  3926.     }
  3927.   }
  3928.   else /* no alpha */
  3929.   {
  3930.     for (x = 0; x <  w*bytes; x++)
  3931.       row[x] = tmp_src[x];
  3932.   }
  3933.  
  3934.   /* set the off edge pixels to their nearest neighbor */
  3935.   for (b = 0; b < 2 * bytes; b++)
  3936.     row[-2*bytes + b] = row[(b%bytes)];
  3937.   for (b = 0; b < bytes * 2; b++)
  3938.     row[w*bytes + b] = row[(w - 1) * bytes + (b%bytes)];
  3939. }
  3940.  
  3941.  
  3942. static
  3943. void expand_line(double *dest, double *src, int bytes,
  3944.          int old_width, int width, InterpolationType interp)
  3945. {
  3946.   double ratio;
  3947.   int x,b;
  3948.   int src_col;
  3949.   double frac;
  3950.   double *s;
  3951.   ratio = old_width/(double)width;
  3952.  
  3953. /* this could be opimized much more by precalculating the coeficients for
  3954.    each x */
  3955.   switch(interp)
  3956.   {
  3957.     case CUBIC_INTERPOLATION:
  3958.       for (x = 0; x < width; x++)
  3959.       {
  3960.     src_col = ((int)((x) * ratio  + 2.0 - 0.5)) - 2;
  3961.     /* +2, -2 is there because (int) rounds towards 0 and we need 
  3962.        to round down */
  3963.     frac =          ((x) * ratio - 0.5) - src_col;
  3964.     s = &src[src_col * bytes];
  3965.     for (b = 0; b < bytes; b++)
  3966.       dest[b] = cubic (frac, s[b - bytes], s[b], s[b+bytes], s[b+bytes*2]);
  3967.     dest += bytes;
  3968.       }
  3969.       break;
  3970.     case LINEAR_INTERPOLATION:
  3971.       for (x = 0; x < width; x++)
  3972.       {
  3973.     src_col = ((int)((x) * ratio + 2.0 - 0.5)) - 2;
  3974.     /* +2, -2 is there because (int) rounds towards 0 and we need 
  3975.        to round down */
  3976.     frac =          ((x) * ratio - 0.5) - src_col;
  3977.     s = &src[src_col * bytes];
  3978.     for (b = 0; b < bytes; b++)
  3979.       dest[b] = ((s[b + bytes] - s[b]) * frac + s[b]);
  3980.     dest += bytes;
  3981.       }
  3982.       break;
  3983.    case NEAREST_NEIGHBOR_INTERPOLATION:
  3984.      g_error("sampling_type can't be "
  3985.          "NEAREST_NEIGHBOR_INTERPOLATION");
  3986.   }
  3987. }
  3988.  
  3989.  
  3990. static void shrink_line(double *dest, double *src, int bytes,
  3991.             int old_width, int width, InterpolationType interp)
  3992. {
  3993.   int x, b;
  3994.   double *source, *destp;
  3995.   register double accum;
  3996.   register unsigned int max;
  3997.   register double mant, tmp;
  3998.   register const double step = old_width/(double)width;
  3999.   register const double inv_step = 1.0/step;
  4000.   double position;
  4001.   for (b = 0; b < bytes; b++)
  4002.   {
  4003.     
  4004.     source = &src[b];
  4005.     destp = &dest[b];
  4006.     position = -1;
  4007.  
  4008.     mant = *source;
  4009.  
  4010.     for (x = 0; x < width; x++)
  4011.     {
  4012.       source+= bytes;
  4013.       accum = 0;
  4014.       max = ((int)(position+step)) - ((int)(position));
  4015.       max--;
  4016.       while (max)
  4017.       {
  4018.     accum += *source;
  4019.     source += bytes;
  4020.     max--;
  4021.       }
  4022.       tmp = accum + mant;
  4023.       mant = ((position+step) - (int)(position + step));
  4024.       mant *= *source;
  4025.       tmp += mant;
  4026.       tmp *= inv_step;
  4027.       mant = *source - mant;
  4028.       *(destp) = tmp;
  4029.       destp += bytes;
  4030.       position += step;
  4031.     
  4032.     }
  4033.   }
  4034. }
  4035.  
  4036. static void
  4037. get_scaled_row(void **src, int y, int new_width, PixelRegion *srcPR, double *row,
  4038.            guchar *src_tmp)
  4039. {
  4040. /* get the necesary lines from the source image, scale them,
  4041.    and put them into src[] */
  4042.   rotate_pointers(src, 4);
  4043.   if (y < 0)
  4044.     y = 0;
  4045.   if (y < srcPR->h)
  4046.   {
  4047.     get_premultiplied_double_row(srcPR, 0, y, srcPR->w,
  4048.                  row, src_tmp, 1);
  4049.     if (new_width > srcPR->w)
  4050.       expand_line(src[3], row, srcPR->bytes, 
  4051.           srcPR->w, new_width, interpolation_type);
  4052.     else if (srcPR->w > new_width)
  4053.       shrink_line(src[3], row, srcPR->bytes, 
  4054.           srcPR->w, new_width, interpolation_type);
  4055.     else /* no scailing needed */
  4056.       memcpy(src[3], row, sizeof (double) * new_width * srcPR->bytes);
  4057.   }
  4058.   else
  4059.     memcpy(src[3], src[2], sizeof (double) * new_width * srcPR->bytes);
  4060. }
  4061. void
  4062. scale_region (PixelRegion *srcPR,
  4063.           PixelRegion *destPR)
  4064. {
  4065.   double  *src[4];
  4066.   guchar * src_tmp;
  4067.   guchar * dest;
  4068.   double * row, *accum;
  4069.   int bytes, b;
  4070.   int width, height;
  4071.   int orig_width, orig_height;
  4072.   double y_rat;
  4073.   int i;
  4074.   int old_y = -4, new_y;
  4075.   int x, y;
  4076.  
  4077.   if (interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION)
  4078.   {
  4079.     scale_region_no_resample (srcPR, destPR);
  4080.     return;
  4081.    }
  4082.  
  4083.   orig_width = srcPR->w;
  4084.   orig_height = srcPR->h;
  4085.  
  4086.   width = destPR->w;
  4087.   height = destPR->h;
  4088.  
  4089.   /*  find the ratios of old y to new y  */
  4090.   y_rat = (double) orig_height / (double) height;
  4091.  
  4092.   bytes = destPR->bytes;
  4093.  
  4094.   /*  the data pointers...  */
  4095.   for (i = 0; i < 4; i++)
  4096.     src[i]    = g_new (double, (width) * bytes);
  4097.   dest   = g_new (guchar, width * bytes);
  4098.  
  4099.   src_tmp = g_new (guchar, orig_width * bytes);
  4100.  
  4101.  /* offset the row pointer by 2*bytes so the range of the array 
  4102.     is [-2*bytes] to [(orig_width + 2)*bytes] */
  4103.   row = g_new(double, (orig_width + 2*2) * bytes);
  4104.   row += bytes*2;
  4105.  
  4106.   accum = g_new(double, (width) * bytes);
  4107.  
  4108.   /*  Scale the selected region  */
  4109.   
  4110.   for (y = 0; y < height;  y++)
  4111.   {
  4112.     if (height < orig_height)
  4113.     {
  4114.       int max;
  4115.       double frac;
  4116.       const double inv_ratio = 1.0 / y_rat;
  4117.       if (y == 0) /* load the first row if this it the first time through  */
  4118.     get_scaled_row((void **)&src[0], 0, width, srcPR, row,
  4119.                src_tmp);
  4120.       new_y = (int)((y) * y_rat);
  4121.       frac = 1.0 - (y*y_rat - new_y);
  4122.       for (x  = 0; x < width*bytes; x++)
  4123.     accum[x] = src[3][x] * frac;
  4124.  
  4125.       max = ((int)((y+1) *y_rat)) - (new_y);
  4126.       max--;
  4127.  
  4128.       get_scaled_row((void **)&src[0], ++new_y, width, srcPR, row,
  4129.              src_tmp);
  4130.       
  4131.       while (max > 0)
  4132.       {
  4133.     for (x  = 0; x < width*bytes; x++)
  4134.       accum[x] += src[3][x];
  4135.     get_scaled_row((void **)&src[0], ++new_y, width, srcPR, row,
  4136.                src_tmp);
  4137.     max--;
  4138.       }
  4139.       frac = (y + 1)*y_rat - ((int)((y + 1)*y_rat));
  4140.       for (x  = 0; x < width*bytes; x++)
  4141.       {
  4142.     accum[x] += frac * src[3][x];
  4143.     accum[x] *= inv_ratio;
  4144.       }
  4145.     }      
  4146.     else if (height > orig_height)
  4147.     {
  4148.       new_y = floor((y) * y_rat - .5);
  4149.     
  4150.       while (old_y <= new_y)
  4151.       { /* get the necesary lines from the source image, scale them,
  4152.        and put them into src[] */
  4153.     get_scaled_row((void **)&src[0], old_y + 2, width, srcPR, row,
  4154.                src_tmp);
  4155.     old_y++;
  4156.       }
  4157.       switch(interpolation_type)
  4158.       {
  4159.        case CUBIC_INTERPOLATION:
  4160.        {
  4161.      double p0, p1, p2, p3;
  4162.      double dy = ((y) * y_rat - .5) - new_y;
  4163.      p0 = cubic(dy, 1, 0, 0, 0);
  4164.      p1 = cubic(dy, 0, 1, 0, 0);
  4165.      p2 = cubic(dy, 0, 0, 1, 0);
  4166.      p3 = cubic(dy, 0, 0, 0, 1);
  4167.      for (x = 0; x < width * bytes; x++)
  4168.        accum[x] = p0 * src[0][x] + p1 * src[1][x] +
  4169.          p2 * src[2][x] + p3 * src[3][x];
  4170.        } break;
  4171.        case LINEAR_INTERPOLATION:
  4172.        {
  4173.      double idy = ((y) * y_rat - 0.5) - new_y;
  4174.      double dy = 1.0 - idy;
  4175.      for (x = 0; x < width * bytes; x++)
  4176.        accum[x] = dy * src[1][x] + idy * src[2][x];
  4177.        } break;
  4178.        case NEAREST_NEIGHBOR_INTERPOLATION:
  4179.      g_error("sampling_type can't be "
  4180.          "NEAREST_NEIGHBOR_INTERPOLATION");
  4181.  
  4182.       }
  4183.     }
  4184.     else /* height == orig_height */
  4185.     {
  4186.       get_scaled_row((void **)&src[0], y, width, srcPR, row,
  4187.              src_tmp);
  4188.       memcpy(accum, src[3], sizeof(double) * width * bytes);
  4189.     }
  4190.     if (pixel_region_has_alpha(srcPR))
  4191.     { /* unmultiply the alpha */
  4192.       double inv_alpha;
  4193.       double *p = accum;
  4194.       int alpha = bytes - 1;
  4195.       int result;
  4196.       guchar *d = dest;
  4197.       for (x = 0; x < width; x++)
  4198.       {
  4199.     if (p[alpha] > 0.001)
  4200.     {
  4201.       inv_alpha = 255.0 / p[alpha];
  4202.       for (b = 0; b < alpha; b++)
  4203.       {
  4204.         result = RINT(inv_alpha * p[b]);
  4205.         if (result < 0)
  4206.           d[b] = 0;
  4207.         else if (result > 255)
  4208.           d[b] = 255;
  4209.         else
  4210.           d[b] = result;
  4211.       }
  4212.       result = RINT(p[alpha]);
  4213.       if (result > 255)
  4214.         d[alpha] = 255;
  4215.       else
  4216.         d[alpha] = result;
  4217.     }
  4218.     else /* alpha <= 0 */
  4219.       for (b = 0; b <= alpha; b++)
  4220.         d[b] = 0;
  4221.     d += bytes;
  4222.     p += bytes;
  4223.  
  4224.       }
  4225.     }
  4226.     else
  4227.     {
  4228.       int w = width * bytes;
  4229.       for (x = 0; x < w; x++)
  4230.       {
  4231.     if (accum[x] < 0.0)
  4232.       dest[x] = 0;
  4233.     else if (accum[x] > 255.0)
  4234.       dest[x] = 255;
  4235.     else
  4236.       dest[x] = RINT(accum[x]);
  4237.       }
  4238.     }
  4239.     pixel_region_set_row (destPR, 0, y, width, dest);
  4240.   }
  4241.  
  4242.   /*  free up temporary arrays  */
  4243.   g_free (accum);
  4244.   for (i = 0; i < 4; i++)
  4245.     g_free (src[i]);
  4246.   g_free (src_tmp);
  4247.   g_free (dest);
  4248.   row -= 2*bytes;
  4249.   g_free (row);
  4250. }
  4251.  
  4252. void
  4253. subsample_region (PixelRegion *srcPR,
  4254.           PixelRegion *destPR,
  4255.           int          subsample)
  4256. {
  4257.   unsigned char * src, * s;
  4258.   unsigned char * dest, * d;
  4259.   double * row, * r;
  4260.   int destwidth;
  4261.   int src_row, src_col;
  4262.   int bytes, b;
  4263.   int width, height;
  4264.   int orig_width, orig_height;
  4265.   double x_rat, y_rat;
  4266.   double x_cum, y_cum;
  4267.   double x_last, y_last;
  4268.   double * x_frac, y_frac, tot_frac;
  4269.   int i, j;
  4270.   int frac;
  4271.   int advance_dest;
  4272.  
  4273.   orig_width = srcPR->w / subsample;
  4274.   orig_height = srcPR->h / subsample;
  4275.   width = destPR->w;
  4276.   height = destPR->h;
  4277.  
  4278.   /*  Some calculations...  */
  4279.   bytes = destPR->bytes;
  4280.   destwidth = destPR->rowstride;
  4281.  
  4282.   /*  the data pointers...  */
  4283.   src = (unsigned char *) g_malloc (orig_width * bytes);
  4284.   dest = destPR->data;
  4285.  
  4286.   /*  find the ratios of old x to new x and old y to new y  */
  4287.   x_rat = (double) orig_width / (double) width;
  4288.   y_rat = (double) orig_height / (double) height;
  4289.  
  4290.   /*  allocate an array to help with the calculations  */
  4291.   row    = (double *) g_malloc (sizeof (double) * width * bytes);
  4292.   x_frac = (double *) g_malloc (sizeof (double) * (width + orig_width));
  4293.  
  4294.   /*  initialize the pre-calculated pixel fraction array  */
  4295.   src_col = 0;
  4296.   x_cum = (double) src_col;
  4297.   x_last = x_cum;
  4298.  
  4299.   for (i = 0; i < width + orig_width; i++)
  4300.     {
  4301.       if (x_cum + x_rat <= (src_col + 1 + EPSILON))
  4302.     {
  4303.       x_cum += x_rat;
  4304.       x_frac[i] = x_cum - x_last;
  4305.     }
  4306.       else
  4307.     {
  4308.       src_col ++;
  4309.       x_frac[i] = src_col - x_last;
  4310.     }
  4311.       x_last += x_frac[i];
  4312.     }
  4313.  
  4314.   /*  clear the "row" array  */
  4315.   memset (row, 0, sizeof (double) * width * bytes);
  4316.  
  4317.   /*  counters...  */
  4318.   src_row = 0;
  4319.   y_cum = (double) src_row;
  4320.   y_last = y_cum;
  4321.  
  4322.   pixel_region_get_row (srcPR, 0, src_row * subsample, orig_width * subsample, src, subsample);
  4323.  
  4324.   /*  Scale the selected region  */
  4325.   for (i = 0; i < height; )
  4326.     {
  4327.       src_col = 0;
  4328.       x_cum = (double) src_col;
  4329.  
  4330.       /* determine the fraction of the src pixel we are using for y */
  4331.       if (y_cum + y_rat <= (src_row + 1 + EPSILON))
  4332.     {
  4333.       y_cum += y_rat;
  4334.       y_frac = y_cum - y_last;
  4335.       advance_dest = TRUE;
  4336.     }
  4337.       else
  4338.     {
  4339.       src_row ++;
  4340.       y_frac = src_row - y_last;
  4341.       advance_dest = FALSE;
  4342.     }
  4343.  
  4344.       y_last += y_frac;
  4345.  
  4346.       s = src;
  4347.       r = row;
  4348.  
  4349.       frac = 0;
  4350.       j = width;
  4351.  
  4352.       while (j)
  4353.     {
  4354.       tot_frac = x_frac[frac++] * y_frac;
  4355.  
  4356.       for (b = 0; b < bytes; b++)
  4357.         r[b] += s[b] * tot_frac;
  4358.  
  4359.       /*  increment the destination  */
  4360.       if (x_cum + x_rat <= (src_col + 1 + EPSILON))
  4361.         {
  4362.           r += bytes;
  4363.           x_cum += x_rat;
  4364.           j--;
  4365.         }
  4366.  
  4367.       /* increment the source */
  4368.       else
  4369.         {
  4370.           s += bytes;
  4371.           src_col++;
  4372.         }
  4373.     }
  4374.  
  4375.       if (advance_dest)
  4376.     {
  4377.       tot_frac = 1.0 / (x_rat * y_rat);
  4378.  
  4379.       /*  copy "row" to "dest"  */
  4380.       d = dest;
  4381.       r = row;
  4382.  
  4383.       j = width;
  4384.       while (j--)
  4385.         {
  4386.           b = bytes;
  4387.           while (b--)
  4388.         *d++ = (unsigned char) (*r++ * tot_frac + 0.5);
  4389.         }
  4390.  
  4391.       dest += destwidth;
  4392.  
  4393.       /*  clear the "row" array  */
  4394.       memset (row, 0, sizeof (double) * destwidth);
  4395.  
  4396.       i++;
  4397.     }
  4398.       else
  4399.     pixel_region_get_row (srcPR, 0, src_row * subsample, orig_width * subsample, src, subsample);
  4400.     }
  4401.  
  4402.   /*  free up temporary arrays  */
  4403.   g_free (row);
  4404.   g_free (x_frac);
  4405.   g_free (src);
  4406. }
  4407.  
  4408.  
  4409. float
  4410. shapeburst_region (PixelRegion *srcPR,
  4411.            PixelRegion *distPR)
  4412. {
  4413.   Tile *tile;
  4414.   unsigned char *tile_data;
  4415.   float max_iterations;
  4416.   float *distp_cur;
  4417.   float *distp_prev;
  4418.   float *tmp;
  4419.   float min_prev;
  4420.   float float_tmp;
  4421.   int min;
  4422.   int min_left;
  4423.   int length;
  4424.   int i, j, k;
  4425.   int src;
  4426.   int fraction;
  4427.   int prev_frac;
  4428.   int x, y;
  4429.   int end;
  4430.   int boundary;
  4431.   int inc;
  4432.  
  4433.   src = 0;
  4434.  
  4435.   max_iterations = 0.0;
  4436.  
  4437.   length = distPR->w + 1;
  4438.   distp_prev = (float *) paint_funcs_get_buffer (sizeof (float) * length * 2);
  4439.   for (i = 0; i < length; i++)
  4440.     distp_prev[i] = 0.0;
  4441.  
  4442.   distp_prev += 1;
  4443.   distp_cur = distp_prev + length;
  4444.  
  4445.   for (i = 0; i < srcPR->h; i++)
  4446.     {
  4447.       /*  set the current dist row to 0's  */
  4448.       memset(distp_cur - 1, 0, sizeof(float) * (length - 1));
  4449.  
  4450.       for (j = 0; j < srcPR->w; j++)
  4451.     {
  4452.       min_prev = MIN (distp_cur[j-1], distp_prev[j]);
  4453.       min_left = MIN ((srcPR->w - j - 1), (srcPR->h - i - 1));
  4454.       min = (int) MIN (min_left, min_prev);
  4455.       fraction = 255;
  4456.  
  4457.       /*  This might need to be changed to 0 instead of k = (min) ? (min - 1) : 0  */
  4458.       for (k = (min) ? (min - 1) : 0; k <= min; k++)
  4459.         {
  4460.           x = j;
  4461.           y = i + k;
  4462.           end = y - k;
  4463.  
  4464.           while (y >= end)
  4465.         {
  4466.           tile = tile_manager_get_tile (srcPR->tiles, x, y, TRUE, FALSE);
  4467.           tile_data = tile_data_pointer (tile, x%TILE_WIDTH, y%TILE_HEIGHT);
  4468.           boundary = MIN ((y % TILE_HEIGHT),
  4469.                   (tile->ewidth - (x % TILE_WIDTH) - 1));
  4470.           boundary = MIN (boundary, (y - end)) + 1;
  4471.           inc = 1 - (tile->ewidth);
  4472.  
  4473.           while (boundary--)
  4474.             {
  4475.               src = *tile_data;
  4476.               if (src == 0)
  4477.             {
  4478.               min = k;
  4479.               y = -1;
  4480.               break;
  4481.             }
  4482.               if (src < fraction)
  4483.             fraction = src;
  4484.  
  4485.               x++;
  4486.               y--;
  4487.               tile_data += inc;
  4488.             }
  4489.  
  4490.           tile_release (tile, FALSE);
  4491.         }
  4492.         }
  4493.  
  4494.       if (src != 0)
  4495.         {
  4496.           /*  If min_left != min_prev use the previous fraction
  4497.            *   if it is less than the one found
  4498.            */
  4499.           if (min_left != min)
  4500.         {
  4501.           prev_frac = (int) (255 * (min_prev - min));
  4502.           if (prev_frac == 255)
  4503.             prev_frac = 0;
  4504.           fraction = MIN (fraction, prev_frac);
  4505.         }
  4506.           min++;
  4507.         }
  4508.  
  4509.       float_tmp = distp_cur[j] = min + fraction / 256.0;
  4510.  
  4511.       if (float_tmp > max_iterations)
  4512.         max_iterations = float_tmp;
  4513.     }
  4514.  
  4515.       /*  set the dist row  */
  4516.       pixel_region_set_row (distPR, distPR->x, distPR->y + i, distPR->w, (unsigned char *) distp_cur);
  4517.  
  4518.       /*  swap pointers around  */
  4519.       tmp = distp_prev;
  4520.       distp_prev = distp_cur;
  4521.       distp_cur = tmp;
  4522.     }
  4523.  
  4524.   return max_iterations;
  4525. }
  4526.  
  4527. static void
  4528. rotate_pointers(void **p, guint32 n)
  4529. {
  4530.   guint32 i;
  4531.   void *tmp;
  4532.   tmp = p[0];
  4533.   for (i = 0; i < n-1; i++)
  4534.   {
  4535.     p[i] = p[i+1];
  4536.   }
  4537.   p[i] = tmp;
  4538. }
  4539.  
  4540. static void
  4541. compute_border(gint16 *circ, guint16 xradius, guint16 yradius)
  4542. {
  4543.   gint32 i;
  4544.   gint32 diameter = xradius*2 +1;
  4545.   gdouble tmp;
  4546.   for (i = 0; i < diameter; i++)
  4547.   {
  4548.     if (i > xradius)
  4549.       tmp = (i - xradius) - .5;
  4550.     else if (i < xradius)
  4551.       tmp = (xradius - i) - .5;
  4552.     else
  4553.       tmp = 0.0;
  4554.     circ[i] = RINT(yradius/(double)xradius *
  4555.            sqrt((xradius)*(xradius) - (tmp)*(tmp)));
  4556.   }
  4557. }
  4558.  
  4559. void
  4560. fatten_region(PixelRegion *src, gint16 xradius, gint16 yradius)
  4561. {
  4562. /*
  4563.   Any bugs in this fuction are probably also in thin_region  
  4564.   Blame all bugs in this function on jaycox@gimp.org
  4565. */
  4566.   register gint32 i, j, x, y;
  4567.   guchar **buf; /* caches the region's pixel data */
  4568.   guchar *out;  /* holds the new scan line we are computing */
  4569.   guchar **max; /* caches the largest values for each column */
  4570.   gint16 *circ; /* holds the y coords of the filter's mask */
  4571.   gint16 last_max, last_index;
  4572.  
  4573.   guchar *buffer;
  4574.  
  4575.   if (xradius <= 0 || yradius <= 0)
  4576.     return;
  4577.  
  4578.   max = (guchar **)g_malloc ((src->w + 2*xradius) * sizeof(void *));
  4579.   buf = (guchar **)g_malloc((yradius + 1) * sizeof(void *));
  4580.   for (i = 0; i < yradius+1; i++)
  4581.   {
  4582.     buf[i] = (guchar *)g_malloc(src->w * sizeof(guchar));
  4583.   }
  4584.   buffer = g_malloc((src->w + 2*xradius)*(yradius + 1) * sizeof(guchar));
  4585.   for (i = 0; i < src->w + 2*xradius; i++)
  4586.   {
  4587.     if (i < xradius)
  4588.       max[i] = buffer;
  4589.     else if (i < src->w + xradius)
  4590.       max[i] = &buffer[(yradius+1)*(i - xradius)];
  4591.     else
  4592.       max[i] = &buffer[(yradius+1)*(src->w + xradius - 1)];
  4593.  
  4594.     for (j = 0 ; j < xradius + 1; j++)
  4595.       max[i][j] = 0;
  4596.   }
  4597.  /* offset the max pointer by xradius so the range of the array 
  4598.     is [-xradius] to [src->w + xradius] */
  4599.   max += xradius;
  4600.  
  4601.   out =  (guchar *)g_malloc (src->w * sizeof(guchar));
  4602.  
  4603.   circ = (short *)g_malloc ((2*xradius + 1) * sizeof(gint16));
  4604.   compute_border (circ, xradius, yradius);
  4605.  
  4606.  /* offset the circ pointer by xradius so the range of the array 
  4607.     is [-xradius] to [xradius] */
  4608.   circ += xradius;
  4609.  
  4610.   memset (buf[0], 0, src->w);
  4611.   for (i = 0; i < yradius && i < src->h; i++) /* load top of image */
  4612.     pixel_region_get_row (src, src->x, src->y + i, src->w, buf[i+1], 1);
  4613.  
  4614.   for (x = 0; x < src->w; x++) /* set up max for top of image */
  4615.   {
  4616.     max[x][0] = buf[0][x];
  4617.     for (j = 1; j < yradius+1; j++)
  4618.       if (max[x][j] < buf[j][x])
  4619.     max[x][j] = buf[j][x];
  4620.       else
  4621.     max[x][j] = max[x][j-1];
  4622.   }
  4623.   for (y = 0; y < src->h; y++)
  4624.   {
  4625.     rotate_pointers((void **)buf, yradius+1);
  4626.     if (y < src->h - (yradius))
  4627.       pixel_region_get_row (src, src->x, src->y + y + yradius, src->w,
  4628.                 buf[yradius], 1);
  4629.     else
  4630.       memset (buf[yradius], 0, src->w);
  4631.     for (x = 0 ; x < src->w; x++) /* update max array */
  4632.     {
  4633.       for (i = yradius; i > 0; i--)
  4634.       {
  4635.     max[x][i] = (MAX (MAX (max[x][i - 1], buf[i-1][x]), buf[i][x]));
  4636.       }
  4637.       max[x][0] = buf[0][x];
  4638.     }
  4639.     last_max =  max[0][circ[-1]];
  4640.     last_index = 1;
  4641.     for (x = 0 ; x < src->w; x++) /* render scan line */
  4642.     {
  4643.       last_index--;
  4644.       if (last_index >= 0)
  4645.       {
  4646.     if (last_max == 255)
  4647.       out[x] = 255;
  4648.     else
  4649.     {
  4650.       last_max = 0;
  4651.       for (i = xradius; i >= 0; i--)
  4652.         if (last_max < max[x+i][circ[i]])
  4653.         {
  4654.           last_max = max[x+i][circ[i]];
  4655.           last_index = i;
  4656.         }
  4657.       out[x] = last_max;
  4658.     }
  4659.       }
  4660.       else
  4661.       {
  4662.     last_index = xradius;
  4663.     last_max = max[x+xradius][circ[xradius]];
  4664.     for (i = xradius-1; i >= -xradius; i--)
  4665.       if (last_max < max[x+i][circ[i]])
  4666.       {
  4667.         last_max = max[x+i][circ[i]];
  4668.         last_index = i;
  4669.       }
  4670.     out[x] = last_max;
  4671.       }
  4672.     }
  4673.     pixel_region_set_row (src, src->x, src->y + y, src->w, out);
  4674.   }
  4675.   /* undo the offsets to the pointers so we can free the malloced memmory */
  4676.   circ -= xradius;
  4677.   max -= xradius;
  4678.  
  4679.   g_free (circ);
  4680.   g_free (buffer);
  4681.   g_free (max);
  4682.   for (i = 0; i < yradius + 1; i++)
  4683.     g_free (buf[i]);
  4684.   g_free (buf);
  4685.   g_free (out);
  4686. }
  4687.  
  4688. void
  4689. thin_region(PixelRegion *src, gint16 xradius, gint16 yradius, int edge_lock)
  4690. {
  4691. /*
  4692.   pretty much the same as fatten_region only different
  4693.   blame all bugs in this function on jaycox@gimp.org
  4694. */
  4695.   /* If edge_lock is true  we assume that pixels outside the region
  4696.      we are passed are identical to the edge pixels.
  4697.      If edge_lock is false, we assume that pixels outside the region are 0
  4698.   */
  4699.   register gint32 i, j, x, y;
  4700.   guchar **buf; /* caches the the region's pixels */
  4701.   guchar *out;  /* holds the new scan line we are computing */
  4702.   guchar **max; /* caches the smallest values for each column */
  4703.   gint16 *circ; /* holds the y coords of the filter's mask */
  4704.   gint16 last_max, last_index;
  4705.  
  4706.   guchar *buffer;
  4707.  
  4708.   if (xradius <= 0 || yradius <= 0)
  4709.     return;
  4710.  
  4711.   max = (guchar **)g_malloc ((src->w+2*xradius) * sizeof(void *));
  4712.   buf = (guchar **)g_malloc ((yradius+1) * sizeof(void *));
  4713.   for (i = 0; i < yradius+1; i++)
  4714.   {
  4715.     buf[i] = (guchar *)g_malloc (src->w * sizeof(guchar));
  4716.   }
  4717.   buffer = g_malloc ((src->w+2*xradius + 1)*(yradius+1));
  4718.   if (edge_lock)
  4719.     memset(buffer, 255, (src->w+2*xradius + 1)*(yradius+1));
  4720.   else
  4721.     memset(buffer, 0, (src->w+2*xradius + 1)*(yradius+1));
  4722.   for (i = 0; i < src->w+2*xradius; i++)
  4723.   {
  4724.     if (i < xradius)
  4725.       if (edge_lock)
  4726.     max[i] = buffer;
  4727.       else
  4728.     max[i] = &buffer[(yradius+1)*(src->w + xradius)];
  4729.     else if (i < src->w + xradius)
  4730.       max[i] = &buffer[(yradius+1)*(i - xradius)];
  4731.     else
  4732.       if (edge_lock)
  4733.     max[i] = &buffer[(yradius+1)*(src->w + xradius - 1)];
  4734.       else
  4735.     max[i] = &buffer[(yradius+1)*(src->w + xradius)];
  4736.   }
  4737.   if (!edge_lock)
  4738.     for (j = 0 ; j < xradius+1; j++)
  4739.       max[0][j] = 0;
  4740.  
  4741.  /* offset the max pointer by xradius so the range of the array 
  4742.     is [-xradius] to [src->w + xradius] */
  4743.   max += xradius;
  4744.  
  4745.   out = (guchar *)g_malloc(src->w);
  4746.  
  4747.   circ = (short *)g_malloc((2*xradius + 1)*sizeof(gint16));
  4748.   compute_border(circ, xradius, yradius);
  4749.  
  4750.  /* offset the circ pointer by xradius so the range of the array 
  4751.     is [-xradius] to [xradius] */
  4752.   circ += xradius;
  4753.  
  4754.   for (i = 0; i < yradius && i < src->h; i++) /* load top of image */
  4755.     pixel_region_get_row (src, src->x, src->y + i, src->w, buf[i+1], 1);
  4756.   if (edge_lock)
  4757.     memcpy (buf[0], buf[1], src->w);
  4758.   else
  4759.     memset (buf[0], 0, src->w);
  4760.   for (x = 0; x < src->w; x++) /* set up max for top of image */
  4761.   {
  4762.     max[x][0] = buf[0][x];
  4763.     for (j = 1; j < yradius+1; j++)
  4764.       if (max[x][j] > buf[j][x])
  4765.     max[x][j] = buf[j][x];
  4766.       else
  4767.     max[x][j] = max[x][j-1];
  4768.   }
  4769.   for (y = 0; y < src->h; y++)
  4770.   {
  4771.     rotate_pointers ((void **)buf, yradius+1);
  4772.     if (y < src->h - (yradius))
  4773.       pixel_region_get_row (src, src->x, src->y + y + yradius, src->w,
  4774.                 buf[yradius], 1);
  4775.     else if (edge_lock)
  4776.       memcpy (buf[yradius], buf[yradius -1], src->w);
  4777.     else
  4778.       memset (buf[yradius], 0, src->w);
  4779.     for (x = 0 ; x < src->w; x++) /* update max array */
  4780.     {
  4781.       for (i = yradius; i > 0; i--)
  4782.       {
  4783.     max[x][i] = (MIN (MIN (max[x][i - 1], buf[i-1][x]), buf[i][x]));
  4784.       }
  4785.       max[x][0] = buf[0][x];
  4786.     }
  4787.     last_max =  max[0][circ[-1]];
  4788.     last_index = 0;
  4789.     for (x = 0 ; x < src->w; x++) /* render scan line */
  4790.     {
  4791.       last_index--;
  4792.       if (last_index >= 0)
  4793.       {
  4794.     if (last_max == 0)
  4795.       out[x] = 0;
  4796.     else
  4797.     {
  4798.       last_max = 255;
  4799.       for (i = xradius; i >= 0; i--)
  4800.         if (last_max > max[x+i][circ[i]])
  4801.         {
  4802.           last_max = max[x+i][circ[i]];
  4803.           last_index = i;
  4804.         }
  4805.       out[x] = last_max;
  4806.     }
  4807.       }
  4808.       else
  4809.       {
  4810.     last_index = xradius;
  4811.     last_max = max[x+xradius][circ[xradius]];
  4812.     for (i = xradius-1; i >= -xradius; i--)
  4813.       if (last_max > max[x+i][circ[i]])
  4814.       {
  4815.         last_max = max[x+i][circ[i]];
  4816.         last_index = i;
  4817.       }
  4818.     out[x] = last_max;
  4819.       }
  4820.     }
  4821.     pixel_region_set_row (src, src->x, src->y + y, src->w, out);
  4822.   }
  4823.   /* undo the offsets to the pointers so we can free the malloced memmory */
  4824.   circ -= xradius;
  4825.   max -= xradius;
  4826.   /* free the memmory */
  4827.   g_free (circ);
  4828.   g_free (buffer);
  4829.   g_free (max);
  4830.   for (i = 0; i < yradius + 1; i++)
  4831.     g_free (buf[i]);
  4832.   g_free (buf);
  4833.   g_free (out);
  4834. }
  4835.  
  4836. static void
  4837. compute_transition(guchar *transition, guchar **buf, gint32 width)
  4838. {
  4839.   register gint32 x = 0;
  4840.   if (width == 1)
  4841.   {
  4842.     if (buf[1][x] > 127 && (buf[0][x] < 128 || buf[2][x] < 128))
  4843.       transition[x] = 255;
  4844.     else
  4845.       transition[x] = 0;
  4846.     return;
  4847.   }
  4848.   if (buf[1][x] > 127)
  4849.   {
  4850.     if ( buf[0][x] < 128 || buf[0][x+1] < 128 ||
  4851.                         buf[1][x+1] < 128 ||
  4852.      buf[2][x] < 128 || buf[2][x+1] < 128 )
  4853.       transition[x] = 255;
  4854.     else
  4855.       transition[x] = 0;
  4856.   }
  4857.   else
  4858.     transition[x] = 0;
  4859.   for (x = 1; x < width - 1; x++)
  4860.   {
  4861.     if (buf[1][x] >= 128)
  4862.     {
  4863.       if (buf[0][x-1] < 128 || buf[0][x] < 128 || buf[0][x+1] < 128 ||
  4864.       buf[1][x-1] < 128           ||          buf[1][x+1] < 128 ||
  4865.       buf[2][x-1] < 128 || buf[2][x] < 128 || buf[2][x+1] < 128)
  4866.     transition[x] = 255;
  4867.       else
  4868.     transition[x] = 0;
  4869.     }
  4870.     else
  4871.       transition[x] = 0;
  4872.   }
  4873.   if (buf[1][x] >= 128)
  4874.   {
  4875.     if ( buf[0][x-1] < 128 || buf[0][x] < 128 ||
  4876.      buf[1][x-1] < 128 ||
  4877.      buf[2][x-1] < 128 || buf[2][x] < 128)
  4878.       transition[x] = 255;
  4879.     else
  4880.       transition[x] = 0;
  4881.   }
  4882.   else
  4883.     transition[x] = 0;
  4884. }
  4885.  
  4886. void
  4887. border_region(PixelRegion *src, gint16 xradius, gint16 yradius)
  4888. {
  4889. /*
  4890.   This function has no bugs, but if you imagine some you can
  4891.   blame them on jaycox@gimp.org
  4892. */
  4893.   register gint32 i, j, x, y;
  4894.   guchar **buf, *out;
  4895.   gint16 *max;
  4896.   guchar **density;
  4897.   guchar **transition;
  4898.   guchar last_max;
  4899.   gint16 last_index;
  4900.  
  4901.   if (xradius < 0 || yradius < 0)
  4902.   {
  4903.     g_warning ("border_region: negative radius specified.");
  4904.     return;
  4905.   }
  4906.   if (xradius == 0 || yradius == 0)
  4907.   {
  4908.     unsigned char color[] = "\0\0\0\0";
  4909.     color_region(src, color);
  4910.     return;
  4911.   }
  4912.   if (xradius == 1 && yradius == 1) /* optimize this case specifically */
  4913.   {
  4914.     guchar *transition;
  4915.     guchar *source[3];
  4916.     for (i = 0; i < 3; i++)
  4917.       source[i] = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4918.  
  4919.     transition = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4920.  
  4921.     pixel_region_get_row (src, src->x, src->y + 0, src->w, source[0], 1);
  4922.     memcpy (source[1], source[0], src->w);
  4923.     if (src->h > 1)
  4924.       pixel_region_get_row (src, src->x, src->y + 1, src->w, source[2], 1);
  4925.     else
  4926.       memcpy (source[2], source[1], src->w);
  4927.  
  4928.     compute_transition (transition, source, src->w);
  4929.     pixel_region_set_row (src, src->x, src->y , src->w, transition);
  4930.     
  4931.     for (y = 1; y < src->h; y++)
  4932.     {
  4933.       rotate_pointers ((void **)source, 3);
  4934.       if (y +1 < src->h)
  4935.     pixel_region_get_row (src, src->x, src->y +y +1, src->w, source[2], 1);
  4936.       else
  4937.     memcpy(source[2], source[1], src->w);
  4938.       compute_transition (transition, source, src->w);
  4939.       pixel_region_set_row (src, src->x, src->y + y, src->w, transition);
  4940.       
  4941.     }
  4942.     for (i = 0; i < 3; i++)
  4943.       g_free(source[i]);
  4944.     g_free(transition);
  4945.     return;
  4946.   } /* end of if (xradius == 1 && yradius == 1) */
  4947.   max = (gint16 *)g_malloc ((src->w+2*xradius)*sizeof(gint16 *));
  4948.   for (i = 0; i < (src->w+2*xradius); i++)
  4949.     max[i] = yradius+2;
  4950.   max += xradius;
  4951.  
  4952.   buf = (guchar **)g_malloc ((3)*sizeof(void *));
  4953.   for (i = 0; i < 3; i++)
  4954.   {
  4955.     buf[i] = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4956.   }
  4957.   transition = (guchar **)g_malloc ((yradius+1)*sizeof(void*));
  4958.   for (i = 0; i < yradius +1; i++)
  4959.   {
  4960.     transition[i] = (guchar *)g_malloc (src->w+2*xradius);
  4961.     memset(transition[i], 0, src->w+2*xradius);
  4962.     transition[i] += xradius;
  4963.   }
  4964.   out = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4965.   density = (guchar **)g_malloc ((2*xradius + 1)*sizeof(void *));
  4966.   density += xradius;
  4967.  
  4968.   for (x = 0; x < (xradius+1); x++) /* allocate density[][] */
  4969.   {
  4970.     density[ x]  = (guchar *)g_malloc (2*yradius +1);
  4971.     density[ x] += yradius;
  4972.     density[-x]  = density[x];
  4973.   }
  4974.   for (x = 0; x < (xradius+1); x++) /* compute density[][] */
  4975.   {
  4976.     register double tmpx, tmpy, dist;
  4977.     guchar a;
  4978.     if (x > 0)
  4979.       tmpx = x - 0.5;
  4980.     else if (x < 0)
  4981.       tmpx = x + 0.5;
  4982.     else
  4983.       tmpx = 0.0;
  4984.     for (y = 0; y < (yradius+1); y++)
  4985.     {
  4986.       if (y > 0)
  4987.     tmpy = y - 0.5;
  4988.       else if (y < 0)
  4989.     tmpy = y + 0.5;
  4990.       else
  4991.     tmpy = 0.0;
  4992.       dist = (tmpy*tmpy)/(yradius*yradius) + (tmpx*tmpx)/(xradius*xradius);
  4993.       if (dist < 1.0)
  4994.     a = 255*(1.0 - sqrt (dist));
  4995.       else
  4996.     a = 0;
  4997.       density[ x][ y] = a;
  4998.       density[ x][-y] = a;
  4999.       density[-x][ y] = a;
  5000.       density[-x][-y] = a;
  5001.     }
  5002.   }
  5003.   pixel_region_get_row (src, src->x, src->y + 0, src->w, buf[0], 1);
  5004.   memcpy (buf[1], buf[0], src->w);
  5005.   if (src->h > 1)
  5006.     pixel_region_get_row (src, src->x, src->y + 1, src->w, buf[2], 1);
  5007.   else
  5008.     memcpy (buf[2], buf[1], src->w);
  5009.   compute_transition (transition[1], buf, src->w);
  5010.  
  5011.   for (y = 1; y < yradius && y + 1< src->h; y++) /* set up top of image */
  5012.   {
  5013.     rotate_pointers ((void **)buf, 3);
  5014.     pixel_region_get_row (src, src->x, src->y + y + 1, src->w, buf[2], 1);
  5015.     compute_transition (transition[y + 1], buf, src->w);
  5016.   }
  5017.   for (x = 0; x < src->w; x++) /* set up max[] for top of image */
  5018.   {
  5019.     max[x] = -(yradius+7); 
  5020.     for (j = 1; j < yradius+1; j++)
  5021.       if (transition[j][x])
  5022.       {
  5023.     max[x] = j;
  5024.     break;
  5025.       }
  5026.   }
  5027.   for (y = 0; y < src->h; y++) /* main calculation loop */
  5028.   {
  5029.     rotate_pointers ((void **)buf, 3);
  5030.     rotate_pointers ((void **)transition, yradius + 1);
  5031.     if (y < src->h - (yradius+1))
  5032.     {
  5033.       pixel_region_get_row (src, src->x, src->y + y + yradius + 1, src->w,
  5034.                 buf[2], 1);
  5035.       compute_transition (transition[yradius], buf, src->w);
  5036.     }
  5037.     else
  5038.       memcpy (transition[yradius], transition[yradius - 1], src->w);
  5039.  
  5040.     for (x = 0; x < src->w; x++) /* update max array */
  5041.     {
  5042.       if (max[x] < 1)
  5043.       {
  5044.     if (max[x] <= -yradius)
  5045.     {
  5046.       if (transition[yradius][x])
  5047.         max[x] = yradius;
  5048.       else
  5049.         max[x]--;
  5050.     }
  5051.     else
  5052.       if (transition[-max[x]][x])
  5053.         max[x] = -max[x];
  5054.       else if (transition[-max[x]+1][x])
  5055.         max[x] = -max[x]+1;
  5056.       else
  5057.         max[x]--;
  5058.       }
  5059.       else
  5060.     max[x]--;
  5061.       if (max[x] < -yradius - 1)
  5062.     max[x] = -yradius -1;
  5063.     }
  5064.     last_max =  max[0][density[-1]];
  5065.     last_index = 1;
  5066.     for (x = 0 ; x < src->w; x++) /* render scan line */
  5067.     {
  5068.       last_index--;
  5069.       if (last_index >= 0)
  5070.       {
  5071.     last_max = 0;
  5072.     for (i = xradius; i >= 0; i--)
  5073.       if (max[x+i] <= yradius && max[x+i] >= -yradius &&
  5074.           density[i][max[x+i]] > last_max)
  5075.       {
  5076.         last_max = density[i][max[x+i]];
  5077.         last_index = i;
  5078.       }
  5079.     out[x] = last_max;
  5080.       }
  5081.       else
  5082.       {
  5083.     last_max = 0;
  5084.     for (i = xradius; i >= -xradius; i--)
  5085.       if (max[x+i] <= yradius && max[x+i] >= -yradius &&
  5086.           density[i][max[x+i]] > last_max)
  5087.       {
  5088.         last_max = density[i][max[x+i]];
  5089.         last_index = i;
  5090.       }
  5091.     out[x] = last_max;
  5092.       }
  5093.       if (last_max == 0)
  5094.       {
  5095.     for (i = x+1; i < src->w; i++)
  5096.     {
  5097.       if (max[i] >= -yradius)
  5098.         break;
  5099.     }
  5100.     if (i - x > xradius)
  5101.     {
  5102.       for (; x < i - xradius; x++)
  5103.         out[x] = 0;
  5104.       x--;
  5105.     }
  5106.     last_index = xradius;
  5107.       }
  5108.     }
  5109.     pixel_region_set_row (src, src->x, src->y + y, src->w, out);
  5110.   }
  5111.   g_free(out);
  5112.  
  5113.   for (i = 0; i < 3; i++)
  5114.     g_free(buf[i]);
  5115.  
  5116.   g_free (buf);
  5117.   max -= xradius;
  5118.   g_free (max);
  5119.  
  5120.   for (i = 0; i < yradius +1; i++)
  5121.   {
  5122.     transition[i] -= xradius;
  5123.     g_free (transition[i]);
  5124.   }
  5125.   g_free (transition);
  5126.  
  5127.   for (i = 0; i < xradius +1 ; i++)
  5128.   {
  5129.     density[i]-= yradius;
  5130.     g_free(density[i]);
  5131.   }
  5132.   density -= xradius;
  5133.   g_free(density);
  5134. }
  5135.  
  5136. void
  5137. swap_region (PixelRegion *src,
  5138.          PixelRegion *dest)
  5139. {
  5140.   int h;
  5141.   int length;
  5142.   unsigned char * s, * d;
  5143.   void * pr;
  5144.  
  5145.   for (pr = pixel_regions_register (2, src, dest); pr != NULL; pr = pixel_regions_process (pr))
  5146.     {
  5147.       s = src->data;
  5148.       h = src->h;
  5149.       d = dest->data;
  5150.       length = src->w * src->bytes;
  5151.  
  5152.       while (h --)
  5153.     {
  5154.       swap_pixels (s, d, length);
  5155.       s += src->rowstride;
  5156.       d += dest->rowstride;
  5157.     }
  5158.     }
  5159. }
  5160.  
  5161.  
  5162. static void
  5163. apply_mask_to_sub_region (int *opacityp,
  5164.               PixelRegion *src,
  5165.               PixelRegion *mask)
  5166. {
  5167.   int h;
  5168.   unsigned char * s, * m;
  5169.   int opacity = *opacityp;
  5170.   
  5171.   s = src->data;
  5172.   m = mask->data;
  5173.   h = src->h;
  5174.  
  5175.   while (h --)
  5176.   {
  5177.     apply_mask_to_alpha_channel (s, m, opacity, src->w, src->bytes);
  5178.     s += src->rowstride;
  5179.     m += mask->rowstride;
  5180.   }
  5181. }
  5182.  
  5183. void
  5184. apply_mask_to_region (PixelRegion *src,
  5185.               PixelRegion *mask,
  5186.               int          opacity)
  5187. {
  5188.   pixel_regions_process_parallel ((p_func)apply_mask_to_sub_region,
  5189.                   &opacity, 2, src, mask);
  5190. }
  5191.  
  5192.  
  5193. static void
  5194. combine_mask_and_sub_region (int *opacityp,
  5195.                  PixelRegion *src,
  5196.                  PixelRegion *mask)
  5197. {
  5198.   int h;
  5199.   unsigned char * s, * m;
  5200.   int opacity = *opacityp;
  5201.   
  5202.   s = src->data;
  5203.   m = mask->data;
  5204.   h = src->h;
  5205.  
  5206.   while (h --)
  5207.   {
  5208.     combine_mask_and_alpha_channel (s, m, opacity, src->w, src->bytes);
  5209.     s += src->rowstride;
  5210.     m += mask->rowstride;
  5211.   }
  5212. }
  5213.  
  5214. void
  5215. combine_mask_and_region (PixelRegion *src,
  5216.              PixelRegion *mask,
  5217.              int          opacity)
  5218. {
  5219.  
  5220.   pixel_regions_process_parallel ((p_func)combine_mask_and_sub_region,
  5221.                   &opacity, 2, src, mask);
  5222. }
  5223.  
  5224.  
  5225. void
  5226. copy_gray_to_region (PixelRegion *src,
  5227.              PixelRegion *dest)
  5228. {
  5229.   int h;
  5230.   unsigned char * s, * d;
  5231.   void * pr;
  5232.  
  5233.   for (pr = pixel_regions_register (2, src, dest); pr != NULL; pr = pixel_regions_process (pr))
  5234.     {
  5235.       s = src->data;
  5236.       d = dest->data;
  5237.       h = src->h;
  5238.  
  5239.       while (h --)
  5240.     {
  5241.       copy_gray_to_inten_a_pixels (s, d, src->w, dest->bytes);
  5242.       s += src->rowstride;
  5243.       d += dest->rowstride;
  5244.     }
  5245.     }
  5246. }
  5247.  
  5248.  
  5249. struct initial_regions_struct
  5250. {
  5251.   int opacity;
  5252.   LayerModeEffects mode;
  5253.   int *affect;
  5254.   int type;
  5255.   unsigned char *data;
  5256. };
  5257.  
  5258. void
  5259. initial_sub_region(struct initial_regions_struct *st, 
  5260.            PixelRegion   *src,
  5261.            PixelRegion   *dest,
  5262.            PixelRegion   *mask)
  5263. {
  5264.   int h;
  5265.   unsigned char * s, * d, * m;
  5266.   unsigned char    buf[512];
  5267.   unsigned char   *data;
  5268.   int              opacity;
  5269.   LayerModeEffects mode;
  5270.   int             *affect;
  5271.   int              type;
  5272.  
  5273.   data = st->data;
  5274.   opacity = st->opacity;
  5275.   mode = st->mode;
  5276.   affect = st->affect;
  5277.   type = st->type;
  5278.  
  5279.   if (src->w * (src->bytes + 1) > 512)
  5280.     fprintf(stderr, "initial_sub_region:: error :: src->w * (src->bytes + 1) > 512\n");
  5281.  
  5282.   s = src->data;
  5283.   d = dest->data;
  5284.   m = (mask) ? mask->data : NULL;
  5285.  
  5286.   for (h = 0; h < src->h; h++)
  5287.   {
  5288.     /*  based on the type of the initial image...  */
  5289.     switch (type)
  5290.     {
  5291.      case INITIAL_CHANNEL_MASK:
  5292.      case INITIAL_CHANNEL_SELECTION:
  5293.        initial_channel_pixels (s, d, src->w, dest->bytes);
  5294.        break;
  5295.  
  5296.      case INITIAL_INDEXED:
  5297.        initial_indexed_pixels (s, d, data, src->w);
  5298.        break;
  5299.  
  5300.      case INITIAL_INDEXED_ALPHA:
  5301.        initial_indexed_a_pixels (s, d, m, data, opacity, src->w);
  5302.        break;
  5303.  
  5304.      case INITIAL_INTENSITY:
  5305.        if (mode == DISSOLVE_MODE)
  5306.        {
  5307.      dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
  5308.               src->bytes + 1, 0);
  5309.      initial_inten_pixels (buf, d, m, opacity, affect,
  5310.                    src->w, src->bytes);
  5311.        }
  5312.        else
  5313.      initial_inten_pixels (s, d, m, opacity, affect, src->w, src->bytes);
  5314.        break;
  5315.  
  5316.      case INITIAL_INTENSITY_ALPHA:
  5317.        if (mode == DISSOLVE_MODE)
  5318.        {
  5319.      dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
  5320.               src->bytes, 1);
  5321.      initial_inten_a_pixels (buf, d, m, opacity, affect,
  5322.                  src->w, src->bytes);
  5323.        }
  5324.        else
  5325.      initial_inten_a_pixels (s, d, m, opacity, affect, src->w, src->bytes);
  5326.        break;
  5327.     }
  5328.  
  5329.     s += src->rowstride;
  5330.     d += dest->rowstride;
  5331.     if (mask)
  5332.       m += mask->rowstride;
  5333.   }
  5334. }
  5335.  
  5336. void
  5337. initial_region (PixelRegion    *src,
  5338.         PixelRegion    *dest,
  5339.         PixelRegion    *mask,
  5340.         unsigned char    *data,
  5341.         int         opacity,
  5342.         LayerModeEffects mode,
  5343.         int        *affect,
  5344.         int         type)
  5345. {
  5346.   struct initial_regions_struct st;
  5347.  
  5348.   st.opacity = opacity;
  5349.   st.mode = mode;
  5350.   st.affect = affect;
  5351.   st.type = type;
  5352.   st.data = data;
  5353.   
  5354.   pixel_regions_process_parallel ((p_func)initial_sub_region, &st, 3,
  5355.                     src, dest, mask);
  5356. }
  5357.  
  5358. struct combine_regions_struct
  5359. {
  5360.   int opacity;
  5361.   LayerModeEffects mode;
  5362.   int *affect;
  5363.   int type;
  5364.   unsigned char *data;
  5365.   int has_alpha1, has_alpha2;
  5366.   gboolean opacity_quickskip_possible;
  5367.   gboolean transparency_quickskip_possible;
  5368. };
  5369.  
  5370.  
  5371.  
  5372. void
  5373. combine_sub_region(struct combine_regions_struct *st,
  5374.            PixelRegion *src1, PixelRegion *src2,
  5375.            PixelRegion *dest, PixelRegion *mask)
  5376. {
  5377.   unsigned char   *data;
  5378.   int              opacity;
  5379.   LayerModeEffects mode;
  5380.   int             *affect;
  5381.   int              type;
  5382.   int h;
  5383.   int has_alpha1, has_alpha2;
  5384.   int combine = 0;
  5385.   int mode_affect;
  5386.   unsigned char * s, * s1, * s2;
  5387.   unsigned char * d, * m;
  5388.   unsigned char buf[512];
  5389.   gboolean opacity_quickskip_possible;
  5390.   gboolean transparency_quickskip_possible;
  5391.   TileRowHint hint;
  5392.  
  5393.   opacity = st->opacity;
  5394.   mode = st->mode;
  5395.   affect = st->affect;
  5396.   type = st->type;
  5397.   data = st->data;
  5398.   has_alpha1 = st->has_alpha1;
  5399.   has_alpha2 = st->has_alpha2;
  5400.  
  5401.   opacity_quickskip_possible = (st->opacity_quickskip_possible &&
  5402.                 src2->tiles);
  5403.   transparency_quickskip_possible = (st->transparency_quickskip_possible &&
  5404.                      src2->tiles);
  5405.  
  5406.   s1 = src1->data;
  5407.   s2 = src2->data;
  5408.   d = dest->data;
  5409.   m = (mask) ? mask->data : NULL;
  5410.  
  5411.   if (src1->w > 128)
  5412.     g_error("combine_sub_region::src1->w = %d\n", src1->w);
  5413.  
  5414.   if (transparency_quickskip_possible || opacity_quickskip_possible)
  5415.     {
  5416. #ifdef HINTS_SANITY
  5417.       if (src1->h != src2->h)
  5418.     g_error("HEIGHTS SUCK!!");
  5419.       if (src1->offy != dest->offy)
  5420.     g_error("SRC1 OFFSET != DEST OFFSET");
  5421. #endif
  5422.       update_tile_rowhints (src2->curtile,
  5423.                 src2->offy, src2->offy + (src1->h - 1));
  5424.     }
  5425.   /* else it's probably a brush-composite */
  5426.  
  5427.   for (h = 0; h < src1->h; h++)
  5428.     {
  5429.       hint = TILEROWHINT_UNDEFINED;
  5430.  
  5431.       if (transparency_quickskip_possible)
  5432.     {
  5433.       hint = tile_get_rowhint (src2->curtile, (src2->offy + h));
  5434.  
  5435.       if (hint == TILEROWHINT_TRANSPARENT)
  5436.         {
  5437.           goto next_row;
  5438.         }
  5439.     }
  5440.       else
  5441.     {
  5442.       if (opacity_quickskip_possible)
  5443.         {
  5444.           hint = tile_get_rowhint (src2->curtile, (src2->offy + h));
  5445.         }
  5446.     }
  5447.       
  5448.       s = buf;
  5449.  
  5450.       /*  apply the paint mode based on the combination type & mode  */
  5451.       switch (type)
  5452.     {
  5453.     case COMBINE_INTEN_A_INDEXED_A:
  5454.     case COMBINE_INTEN_A_CHANNEL_MASK:
  5455.     case COMBINE_INTEN_A_CHANNEL_SELECTION:
  5456.       combine = type;
  5457.       break;
  5458.  
  5459.     case COMBINE_INDEXED_INDEXED:
  5460.     case COMBINE_INDEXED_INDEXED_A:
  5461.     case COMBINE_INDEXED_A_INDEXED_A:
  5462.       /*  Now, apply the paint mode--for indexed images  */
  5463.       combine = apply_indexed_layer_mode (s1, s2, &s, mode,
  5464.                           has_alpha1, has_alpha2);
  5465.       break;
  5466.  
  5467.     case COMBINE_INTEN_INTEN_A:
  5468.     case COMBINE_INTEN_A_INTEN:
  5469.     case COMBINE_INTEN_INTEN:
  5470.     case COMBINE_INTEN_A_INTEN_A:
  5471.       /*  Now, apply the paint mode  */
  5472.       combine = apply_layer_mode (s1, s2, &s, src1->x, src1->y + h,
  5473.                       opacity, src1->w, mode,
  5474.                       src1->bytes, src2->bytes,
  5475.                       has_alpha1, has_alpha2, &mode_affect);
  5476.       break;
  5477.  
  5478.     default:
  5479.       g_warning ("combine_sub_region: unhandled combine-type.");
  5480.       break;
  5481.     }
  5482.  
  5483.       /*  based on the type of the initial image...  */
  5484.       switch (combine)
  5485.     {
  5486.     case COMBINE_INDEXED_INDEXED:
  5487.       combine_indexed_and_indexed_pixels (s1, s2, d, m, opacity,
  5488.                           affect, src1->w,
  5489.                           src1->bytes);
  5490.       break;
  5491.         
  5492.     case COMBINE_INDEXED_INDEXED_A:
  5493.       combine_indexed_and_indexed_a_pixels (s1, s2, d, m, opacity,
  5494.                         affect, src1->w,
  5495.                         src1->bytes);
  5496.       break;
  5497.         
  5498.     case COMBINE_INDEXED_A_INDEXED_A:
  5499.       combine_indexed_a_and_indexed_a_pixels (s1, s2, d, m, opacity,
  5500.                           affect, src1->w,
  5501.                           src1->bytes);
  5502.       break;
  5503.         
  5504.     case COMBINE_INTEN_A_INDEXED_A:
  5505.       /*  assume the data passed to this procedure is the
  5506.        *  indexed layer's colormap
  5507.        */
  5508.       combine_inten_a_and_indexed_a_pixels (s1, s2, d, m, data, opacity,
  5509.                         src1->w, dest->bytes);
  5510.       break;
  5511.         
  5512.     case COMBINE_INTEN_A_CHANNEL_MASK:
  5513.       /*  assume the data passed to this procedure is the
  5514.        *  indexed layer's colormap
  5515.        */
  5516.       combine_inten_a_and_channel_mask_pixels (s1, s2, d, data, opacity,
  5517.                            src1->w, dest->bytes);
  5518.       break;
  5519.         
  5520.     case COMBINE_INTEN_A_CHANNEL_SELECTION:
  5521.       combine_inten_a_and_channel_selection_pixels (s1, s2, d, data,
  5522.                             opacity,
  5523.                             src1->w,
  5524.                             src1->bytes);
  5525.       break;
  5526.         
  5527.     case COMBINE_INTEN_INTEN:
  5528.       if ((hint == TILEROWHINT_OPAQUE) &&
  5529.           opacity_quickskip_possible)
  5530.         {
  5531.           memcpy (d, s, dest->w * dest->bytes);
  5532.         }
  5533.       else
  5534.         combine_inten_and_inten_pixels (s1, s, d, m, opacity,
  5535.                         affect, src1->w, src1->bytes);
  5536.       break;
  5537.         
  5538.     case COMBINE_INTEN_INTEN_A:
  5539.       combine_inten_and_inten_a_pixels (s1, s, d, m, opacity,
  5540.                         affect, src1->w, src1->bytes);
  5541.       break;
  5542.         
  5543.     case COMBINE_INTEN_A_INTEN:
  5544.       combine_inten_a_and_inten_pixels (s1, s, d, m, opacity,
  5545.                         affect, mode_affect, src1->w,
  5546.                         src1->bytes);
  5547.       break;
  5548.         
  5549.     case COMBINE_INTEN_A_INTEN_A:
  5550.       if ((hint == TILEROWHINT_OPAQUE) &&
  5551.           opacity_quickskip_possible)
  5552.         {
  5553.           memcpy (d, s, dest->w * dest->bytes);
  5554.         }
  5555.       else
  5556.         combine_inten_a_and_inten_a_pixels (s1, s, d, m, opacity,
  5557.                         affect, mode_affect,
  5558.                         src1->w, src1->bytes);
  5559.       break;
  5560.         
  5561.     case BEHIND_INTEN:
  5562.       behind_inten_pixels (s1, s, d, m, opacity,
  5563.                    affect, src1->w, src1->bytes,
  5564.                    src2->bytes, has_alpha1, has_alpha2);
  5565.       break;
  5566.         
  5567.     case BEHIND_INDEXED:
  5568.       behind_indexed_pixels (s1, s, d, m, opacity,
  5569.                  affect, src1->w, src1->bytes,
  5570.                  src2->bytes, has_alpha1, has_alpha2);
  5571.       break;
  5572.         
  5573.     case REPLACE_INTEN:
  5574.       replace_inten_pixels (s1, s, d, m, opacity,
  5575.                 affect, src1->w, src1->bytes,
  5576.                 src2->bytes, has_alpha1, has_alpha2);
  5577.       break;
  5578.         
  5579.     case REPLACE_INDEXED:
  5580.       replace_indexed_pixels (s1, s, d, m, opacity,
  5581.                   affect, src1->w, src1->bytes,
  5582.                   src2->bytes, has_alpha1, has_alpha2);
  5583.       break;
  5584.         
  5585.     case ERASE_INTEN:
  5586.       erase_inten_pixels (s1, s, d, m, opacity,
  5587.                   affect, src1->w, src1->bytes);
  5588.       break;
  5589.         
  5590.     case ERASE_INDEXED:
  5591.       erase_indexed_pixels (s1, s, d, m, opacity,
  5592.                 affect, src1->w, src1->bytes);
  5593.       break;
  5594.         
  5595.     case ANTI_ERASE_INTEN:
  5596.       anti_erase_inten_pixels (s1, s, d, m, opacity,
  5597.                    affect, src1->w, src1->bytes);
  5598.       break;
  5599.         
  5600.     case ANTI_ERASE_INDEXED:
  5601.       anti_erase_indexed_pixels (s1, s, d, m, opacity,
  5602.                      affect, src1->w, src1->bytes);
  5603.       break;
  5604.         
  5605.     case NO_COMBINATION:
  5606.       g_warning("NO_COMBINATION");
  5607.       break;
  5608.         
  5609.     default:
  5610.       g_warning("UNKNOWN COMBINATION");
  5611.       break;
  5612.     }
  5613.     
  5614.     next_row:
  5615.       s1 += src1->rowstride;
  5616.       s2 += src2->rowstride;
  5617.       d += dest->rowstride;
  5618.       if (mask)
  5619.     m += mask->rowstride;
  5620.     }
  5621. }
  5622.  
  5623.  
  5624. void
  5625. combine_regions (PixelRegion     *src1,
  5626.          PixelRegion     *src2,
  5627.          PixelRegion        *dest,
  5628.          PixelRegion       *mask,
  5629.          unsigned char     *data,
  5630.          int          opacity,
  5631.          LayerModeEffects mode,
  5632.          int         *affect,
  5633.          int          type)
  5634. {
  5635.   int has_alpha1, has_alpha2;
  5636.   int i;
  5637.   struct combine_regions_struct st;
  5638.  
  5639.   /*  Determine which sources have alpha channels  */
  5640.   switch (type)
  5641.     {
  5642.     case COMBINE_INTEN_INTEN:
  5643.     case COMBINE_INDEXED_INDEXED:
  5644.       has_alpha1 = has_alpha2 = 0;
  5645.       break;
  5646.     case COMBINE_INTEN_A_INTEN:
  5647.       has_alpha1 = 1;
  5648.       has_alpha2 = 0;
  5649.       break;
  5650.     case COMBINE_INTEN_INTEN_A:
  5651.     case COMBINE_INDEXED_INDEXED_A:
  5652.       has_alpha1 = 0;
  5653.       has_alpha2 = 1;
  5654.       break;
  5655.     case COMBINE_INTEN_A_INTEN_A:
  5656.     case COMBINE_INDEXED_A_INDEXED_A:
  5657.       has_alpha1 = has_alpha2 = 1;
  5658.       break;
  5659.     default:
  5660.       has_alpha1 = has_alpha2 = 0;
  5661.     }
  5662.  
  5663.   st.opacity = opacity;
  5664.   st.mode = mode;
  5665.   st.affect = affect;
  5666.   st.type = type;
  5667.   st.data = data;
  5668.   st.has_alpha1 = has_alpha1;
  5669.   st.has_alpha2 = has_alpha2;
  5670.  
  5671.   /* cheap and easy when the row of src2 is completely opaque/transparent
  5672.      and the wind is otherwise blowing in the right direction.
  5673.   */
  5674.  
  5675.   /* First check - we can't do an opacity quickskip if the drawable
  5676.      has a mask, or non-full opacity, or the layer mode dictates
  5677.      that we might gain transparency.
  5678.   */
  5679.   st.opacity_quickskip_possible = ((!mask) && (opacity==255) &&
  5680.                    (!layer_modes[mode].decrease_opacity) &&
  5681.                    (layer_modes[mode].affect_alpha &&
  5682.                     has_alpha1 &&
  5683.                     affect[src1->bytes-1]) );
  5684.  
  5685.   /* Second check - if any single colour channel can't be affected,
  5686.      we can't use the opacity quickskip.
  5687.   */
  5688.   if (st.opacity_quickskip_possible)
  5689.     {
  5690.       for (i=0; i<src1->bytes-1; i++)
  5691.     {
  5692.       if (!affect[i])
  5693.         {
  5694.           st.opacity_quickskip_possible = FALSE;
  5695.           break;
  5696.         }
  5697.     }
  5698.     }
  5699.  
  5700.   /* transparency quickskip is only possible if the layer mode
  5701.      dictates that we cannot possibly gain opacity, or the 'overall'
  5702.      opacity of the layer is set to zero anyway.
  5703.    */
  5704.   st.transparency_quickskip_possible = ((!layer_modes[mode].increase_opacity)
  5705.                     || (opacity==0));
  5706.  
  5707.   /* Start the actual processing.
  5708.    */
  5709.   pixel_regions_process_parallel ((p_func)combine_sub_region, &st, 4,
  5710.                     src1, src2, dest, mask);
  5711. }
  5712.  
  5713. void
  5714. combine_regions_replace (PixelRegion   *src1,
  5715.              PixelRegion   *src2,
  5716.              PixelRegion   *dest,
  5717.              PixelRegion   *mask,
  5718.              unsigned char *data,
  5719.              int            opacity,
  5720.              int           *affect,
  5721.              int            type)
  5722. {
  5723.   int h;
  5724.   unsigned char * s1, * s2;
  5725.   unsigned char * d, * m;
  5726.   void * pr;
  5727.  
  5728.   for (pr = pixel_regions_register (4, src1, src2, dest, mask); pr != NULL; pr = pixel_regions_process (pr))
  5729.     {
  5730.       s1 = src1->data;
  5731.       s2 = src2->data;
  5732.       d = dest->data;
  5733.       m = mask->data;
  5734.  
  5735.       for (h = 0; h < src1->h; h++)
  5736.     {
  5737.  
  5738.       /*  Now, apply the paint mode  */
  5739.       apply_layer_mode_replace (s1, s2, d, m, src1->x, src1->y + h, opacity, src1->w,
  5740.                           src1->bytes, src2->bytes, affect);
  5741.  
  5742.       s1 += src1->rowstride;
  5743.       s2 += src2->rowstride;
  5744.       d += dest->rowstride;
  5745.       m += mask->rowstride;
  5746.     }
  5747.     }
  5748. }
  5749.  
  5750. /************************************/
  5751. /*       apply layer modes          */
  5752. /************************************/
  5753.  
  5754. int
  5755. apply_layer_mode (unsigned char   *src1,
  5756.           unsigned char   *src2,
  5757.           unsigned char  **dest,
  5758.           int              x,
  5759.           int              y,
  5760.           int              opacity,
  5761.           int              length,
  5762.           LayerModeEffects mode,
  5763.           int              bytes1,   /* bytes */
  5764.           int              bytes2,   /* bytes */
  5765.           int              has_alpha1,  /* has alpha */
  5766.           int              has_alpha2,  /* has alpha */
  5767.           int             *mode_affect)
  5768. {
  5769.   int combine;
  5770.  
  5771.   if (!has_alpha1 && !has_alpha2)
  5772.     combine = COMBINE_INTEN_INTEN;
  5773.   else if (!has_alpha1 && has_alpha2)
  5774.     combine = COMBINE_INTEN_INTEN_A;
  5775.   else if (has_alpha1 && !has_alpha2)
  5776.     combine = COMBINE_INTEN_A_INTEN;
  5777.   else
  5778.     combine = COMBINE_INTEN_A_INTEN_A;
  5779.  
  5780.   /*  assumes we're applying src2 TO src1  */
  5781.   switch (mode)
  5782.     {
  5783.     case NORMAL_MODE:
  5784.       *dest = src2;
  5785.       break;
  5786.  
  5787.     case DISSOLVE_MODE:
  5788.       /*  Since dissolve requires an alpha channels...  */
  5789.       if (! has_alpha2)
  5790.     add_alpha_pixels (src2, *dest, length, bytes2);
  5791.  
  5792.       dissolve_pixels (src2, *dest, x, y, opacity, length, bytes2,
  5793.                ((has_alpha2) ? bytes2 : bytes2 + 1), has_alpha2);
  5794.       combine = (has_alpha1) ? COMBINE_INTEN_A_INTEN_A : COMBINE_INTEN_INTEN_A;
  5795.       break;
  5796.  
  5797.     case MULTIPLY_MODE:
  5798.       multiply_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5799.       break;
  5800.  
  5801.     case DIVIDE_MODE:
  5802.       divide_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5803.       break;
  5804.  
  5805.     case SCREEN_MODE:
  5806.       screen_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5807.       break;
  5808.  
  5809.     case OVERLAY_MODE:
  5810.       overlay_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5811.       break;
  5812.  
  5813.     case DIFFERENCE_MODE:
  5814.       difference_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5815.       break;
  5816.  
  5817.     case ADDITION_MODE:
  5818.       add_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5819.       break;
  5820.  
  5821.     case SUBTRACT_MODE:
  5822.       subtract_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5823.       break;
  5824.  
  5825.     case DARKEN_ONLY_MODE:
  5826.       darken_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5827.       break;
  5828.  
  5829.     case LIGHTEN_ONLY_MODE:
  5830.       lighten_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5831.       break;
  5832.  
  5833.     case HUE_MODE: case SATURATION_MODE: case VALUE_MODE:
  5834.       /*  only works on RGB color images  */
  5835.       if (bytes1 > 2)
  5836.     hsv_only_pixels (src1, src2, *dest, mode, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5837.       else
  5838.     *dest = src2;
  5839.       break;
  5840.  
  5841.     case COLOR_MODE:
  5842.       /*  only works on RGB color images  */
  5843.       if (bytes1 > 2)
  5844.     color_only_pixels (src1, src2, *dest, mode, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5845.       else
  5846.     *dest = src2;
  5847.       break;
  5848.  
  5849.     case BEHIND_MODE:
  5850.       *dest = src2;
  5851.       if (has_alpha1)
  5852.     combine = BEHIND_INTEN;
  5853.       else
  5854.     combine = NO_COMBINATION;
  5855.       break;
  5856.  
  5857.     case REPLACE_MODE:
  5858.       *dest = src2;
  5859.       combine = REPLACE_INTEN;
  5860.       break;
  5861.  
  5862.     case ERASE_MODE:
  5863.       *dest = src2;
  5864.       /*  If both sources have alpha channels, call erase function.
  5865.        *  Otherwise, just combine in the normal manner
  5866.        */
  5867.       combine = (has_alpha1 && has_alpha2) ? ERASE_INTEN : combine;
  5868.       break;
  5869.  
  5870.     case ANTI_ERASE_MODE:
  5871.       *dest = src2;
  5872.       combine = (has_alpha1 && has_alpha2) ? ANTI_ERASE_INTEN : combine;
  5873.       break;
  5874.  
  5875.     default :
  5876.       break;
  5877.     }
  5878.  
  5879.   /*  Determine whether the alpha channel of the destination can be affected
  5880.    *  by the specified mode--This keeps consistency with varying opacities
  5881.    */
  5882.   *mode_affect = layer_modes[mode].affect_alpha;
  5883.  
  5884.   return combine;
  5885. }
  5886.  
  5887.  
  5888. int
  5889. apply_indexed_layer_mode (unsigned char   *src1,
  5890.               unsigned char   *src2,
  5891.               unsigned char  **dest,
  5892.               LayerModeEffects mode,
  5893.               int              has_alpha1, /* has alpha */
  5894.               int              has_alpha2) /* has alpha */
  5895. {
  5896.   int combine;
  5897.  
  5898.   if (!has_alpha1 && !has_alpha2)
  5899.     combine = COMBINE_INDEXED_INDEXED;
  5900.   else if (!has_alpha1 && has_alpha2)
  5901.     combine = COMBINE_INDEXED_INDEXED_A;
  5902.   else if (has_alpha1 && has_alpha2)
  5903.     combine = COMBINE_INDEXED_A_INDEXED_A;
  5904.   else
  5905.     combine = NO_COMBINATION;
  5906.  
  5907.   /*  assumes we're applying src2 TO src1  */
  5908.   switch (mode)
  5909.     {
  5910.     case REPLACE_MODE:
  5911.       *dest = src2;
  5912.       combine = REPLACE_INDEXED;
  5913.       break;
  5914.  
  5915.     case BEHIND_MODE:
  5916.       *dest = src2;
  5917.       if (has_alpha1)
  5918.     combine = BEHIND_INDEXED;
  5919.       else
  5920.     combine = NO_COMBINATION;
  5921.       break;
  5922.  
  5923.     case ERASE_MODE:
  5924.       *dest = src2;
  5925.       /*  If both sources have alpha channels, call erase function.
  5926.        *  Otherwise, just combine in the normal manner
  5927.        */
  5928.       combine = (has_alpha1 && has_alpha2) ? ERASE_INDEXED : combine;
  5929.       break;
  5930.  
  5931.     default:
  5932.       break;
  5933.     }
  5934.  
  5935.   return combine;
  5936. }
  5937.  
  5938. static void
  5939. apply_layer_mode_replace (unsigned char  *src1,
  5940.               unsigned char  *src2,
  5941.               unsigned char  *dest,
  5942.               unsigned char  *mask,
  5943.               int             x,
  5944.               int             y,
  5945.               int             opacity,
  5946.               int             length,
  5947.               int             bytes1,   /* bytes */
  5948.               int             bytes2,   /* bytes */
  5949.               int            *affect)
  5950. {
  5951.   replace_pixels (src1, src2, dest, mask, length, opacity, affect, bytes1, bytes2);
  5952. }
  5953.