/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- __imlib_CopyToRGBA
 - __imlib_CopyToRGB
 - __imlib_BlendToRGB
 - __imlib_BlendToRGBA
 - __imlib_AddCopyToRGBA
 - __imlib_AddCopyToRGB
 - __imlib_AddBlendToRGB
 - __imlib_AddBlendToRGBA
 - __imlib_SubCopyToRGBA
 - __imlib_SubCopyToRGB
 - __imlib_SubBlendToRGB
 - __imlib_SubBlendToRGBA
 - __imlib_ReCopyToRGBA
 - __imlib_ReCopyToRGB
 - __imlib_ReBlendToRGB
 - __imlib_ReBlendToRGBA
 - __imlib_CopySpanToRGBA
 - __imlib_CopySpanToRGB
 - __imlib_BlendSpanToRGB
 - __imlib_BlendSpanToRGBA
 - __imlib_AddCopySpanToRGBA
 - __imlib_AddCopySpanToRGB
 - __imlib_AddBlendSpanToRGB
 - __imlib_AddBlendSpanToRGBA
 - __imlib_SubCopySpanToRGBA
 - __imlib_SubCopySpanToRGB
 - __imlib_SubBlendSpanToRGB
 - __imlib_SubBlendSpanToRGBA
 - __imlib_ReCopySpanToRGBA
 - __imlib_ReCopySpanToRGB
 - __imlib_ReBlendSpanToRGB
 - __imlib_ReBlendSpanToRGBA
 - __imlib_CopyShapedSpanToRGBA
 - __imlib_CopyShapedSpanToRGB
 - __imlib_BlendShapedSpanToRGB
 - __imlib_BlendShapedSpanToRGBA
 - __imlib_AddCopyShapedSpanToRGBA
 - __imlib_AddCopyShapedSpanToRGB
 - __imlib_AddBlendShapedSpanToRGB
 - __imlib_AddBlendShapedSpanToRGBA
 - __imlib_SubCopyShapedSpanToRGBA
 - __imlib_SubCopyShapedSpanToRGB
 - __imlib_SubBlendShapedSpanToRGB
 - __imlib_SubBlendShapedSpanToRGBA
 - __imlib_ReCopyShapedSpanToRGBA
 - __imlib_ReCopyShapedSpanToRGB
 - __imlib_ReBlendShapedSpanToRGB
 - __imlib_ReBlendShapedSpanToRGBA
 - __imlib_GetPointDrawFunction
 - __imlib_GetSpanDrawFunction
 - __imlib_GetShapedSpanDrawFunction
 
#include "common.h"
#include "colormod.h"
#include "image.h"
#include "blend.h"
#include "span.h"
#define ADD_COPY(r, g, b, dest) \
do { \
                ADD_COLOR(R_VAL(dest), r, R_VAL(dest)); \
                ADD_COLOR(G_VAL(dest), g, G_VAL(dest)); \
                ADD_COLOR(B_VAL(dest), b, B_VAL(dest)); \
} while (0)
#define SUB_COPY(r, g, b, dest) \
do { \
                SUB_COLOR(R_VAL(dest), r, R_VAL(dest)); \
                SUB_COLOR(G_VAL(dest), g, G_VAL(dest)); \
                SUB_COLOR(B_VAL(dest), b, B_VAL(dest)); \
} while (0)
#define RE_COPY(r, g, b, dest) \
do { \
                RESHADE_COLOR(R_VAL(dest), r, R_VAL(dest)); \
                RESHADE_COLOR(G_VAL(dest), g, G_VAL(dest)); \
                RESHADE_COLOR(B_VAL(dest), b, B_VAL(dest)); \
} while (0)
#define MULT(na, a0, a1, tmp) \
do { \
   tmp = ((a0) * (a1)) + 0x80;   \
   na = (tmp + (tmp >> 8)) >> 8; \
} while (0)
extern DATA8        pow_lut[256][256];
/*   point drawing functions  */
/* COPY OPS */
static void
__imlib_CopyToRGBA(DATA32 color, DATA32 * dst)
{
   *dst = color;
}
static void
__imlib_CopyToRGB(DATA32 color, DATA32 * dst)
{
   *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
}
static void
__imlib_BlendToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
}
static void
__imlib_BlendToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   DATA8               a;
   a = pow_lut[A_VAL(&color)][A_VAL(dst)];
   BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
   BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
}
/* ADD OPS */
static void
__imlib_AddCopyToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   A_VAL(dst) = A_VAL(&color);
   ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
}
static void
__imlib_AddCopyToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
}
static void
__imlib_AddBlendToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
}
static void
__imlib_AddBlendToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   DATA8               a;
   a = pow_lut[A_VAL(&color)][A_VAL(dst)];
   BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
   BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
}
/* SUBTRACT OPS */
static void
__imlib_SubCopyToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   A_VAL(dst) = A_VAL(&color);
   SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
}
static void
__imlib_SubCopyToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
}
static void
__imlib_SubBlendToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
}
static void
__imlib_SubBlendToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   DATA8               a;
   a = pow_lut[A_VAL(&color)][A_VAL(dst)];
   BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
   BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
}
/* RESHADE OPS */
static void
__imlib_ReCopyToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   A_VAL(dst) = A_VAL(&color);
   RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
}
static void
__imlib_ReCopyToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
}
static void
__imlib_ReBlendToRGB(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
}
static void
__imlib_ReBlendToRGBA(DATA32 color, DATA32 * dst)
{
   DATA32              tmp;
   DATA8               a;
   a = pow_lut[A_VAL(&color)][A_VAL(dst)];
   BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
   BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
}
/*  span drawing functions*  */
/* COPY OPS */
static void
__imlib_CopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        *dst = color;
        dst++;
     }
}
static void
__imlib_CopySpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
        dst++;
     }
}
static void
__imlib_BlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_BlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        a = pow_lut[A_VAL(&color)][A_VAL(dst)];
        BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
        BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
        dst++;
     }
}
/* ADD OPS */
static void
__imlib_AddCopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        A_VAL(dst) = A_VAL(&color);
        ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_AddCopySpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_AddBlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color),
                  dst);
        dst++;
     }
}
static void
__imlib_AddBlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        a = pow_lut[A_VAL(&color)][A_VAL(dst)];
        BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
        BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
        dst++;
     }
}
/* SUBTRACT OPS */
static void
__imlib_SubCopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        A_VAL(dst) = A_VAL(&color);
        SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_SubCopySpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_SubBlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color),
                  dst);
        dst++;
     }
}
static void
__imlib_SubBlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        a = pow_lut[A_VAL(&color)][A_VAL(dst)];
        BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
        BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
        dst++;
     }
}
/* RESHADE OPS */
static void
__imlib_ReCopySpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        A_VAL(dst) = A_VAL(&color);
        RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_ReCopySpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
        dst++;
     }
}
static void
__imlib_ReBlendSpanToRGB(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), A_VAL(&color),
                 dst);
        dst++;
     }
}
static void
__imlib_ReBlendSpanToRGBA(DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        a = pow_lut[A_VAL(&color)][A_VAL(dst)];
        BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
        BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
        dst++;
     }
}
/*  shaped span drawing functions*  */
/* COPY OPS */
static void
__imlib_CopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   DATA32              col = color;
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     *dst = color;
                     break;
                  }
               default:
                  {
                     MULT(A_VAL(&col), *src, A_VAL(&color), tmp);
                     *dst = col;
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                *dst = color;
                break;
             }
          default:
             {
                A_VAL(&col) = *src;
                *dst = col;
                break;
             }
          }
        src++;
        dst++;
     }
}
static void
__imlib_CopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        if (*src)
           *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
        src++;
        dst++;
     }
}
static void
__imlib_BlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color),
                           A_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(a, *src, A_VAL(&color), tmp);
                     BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                *dst = (*dst & 0xff000000) | (color & 0x00ffffff);
                break;
             }
          default:
             {
                BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src, dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
static void
__imlib_BlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a, aa;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     a = pow_lut[A_VAL(&color)][A_VAL(dst)];
                     BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
                     BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                     break;
                  }
               default:
                  {
                     MULT(aa, *src, A_VAL(&color), tmp);
                     a = pow_lut[aa][A_VAL(dst)];
                     BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
                     BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                *dst = color;
                break;
             }
          default:
             {
                a = pow_lut[*src][A_VAL(dst)];
                BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
                BLEND(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
/* ADD OPS */
static void
__imlib_AddCopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
                                int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     A_VAL(dst) = A_VAL(&color);
                     ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(A_VAL(dst), *src, A_VAL(&color), tmp);
                     ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        if (*src)
          {
             A_VAL(dst) = *src;
             ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
          }
        src++;
        dst++;
     }
}
static void
__imlib_AddCopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        if (*src)
          {
             ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
          }
        src++;
        dst++;
     }
}
static void
__imlib_AddBlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst,
                                int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color),
                               A_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(a, *src, A_VAL(&color), tmp);
                     BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                               dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                break;
             }
          default:
             {
                BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src,
                          dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
static void
__imlib_AddBlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
                                 int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a, aa;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     a = pow_lut[A_VAL(&color)][A_VAL(dst)];
                     BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
                     BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                               dst);
                     break;
                  }
               default:
                  {
                     MULT(aa, *src, A_VAL(&color), tmp);
                     a = pow_lut[aa][A_VAL(dst)];
                     BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
                     BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                               dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                A_VAL(dst) = 255;
                ADD_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                break;
             }
          default:
             {
                a = pow_lut[*src][A_VAL(dst)];
                BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
                BLEND_ADD(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
/* SUBTRACT OPS */
static void
__imlib_SubCopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
                                int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     A_VAL(dst) = A_VAL(&color);
                     SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(A_VAL(dst), *src, A_VAL(&color), tmp);
                     SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        if (*src)
          {
             A_VAL(dst) = *src;
             SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
          }
        src++;
        dst++;
     }
}
static void
__imlib_SubCopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        if (*src)
          {
             SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
          }
        src++;
        dst++;
     }
}
static void
__imlib_SubBlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst,
                                int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color),
                               A_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(a, *src, A_VAL(&color), tmp);
                     BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                               dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                break;
             }
          default:
             {
                BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src,
                          dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
static void
__imlib_SubBlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
                                 int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a, aa;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     a = pow_lut[A_VAL(&color)][A_VAL(dst)];
                     BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
                     BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                               dst);
                     break;
                  }
               default:
                  {
                     MULT(aa, *src, A_VAL(&color), tmp);
                     a = pow_lut[aa][A_VAL(dst)];
                     BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
                     BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                               dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                A_VAL(dst) = 255;
                SUB_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                break;
             }
          default:
             {
                a = pow_lut[*src][A_VAL(dst)];
                BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
                BLEND_SUB(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
/* RESHADE OPS */
static void
__imlib_ReCopyShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     A_VAL(dst) = A_VAL(&color);
                     RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(A_VAL(dst), *src, A_VAL(&color), tmp);
                     RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        if (*src)
          {
             A_VAL(dst) = *src;
             RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
          }
        src++;
        dst++;
     }
}
static void
__imlib_ReCopyShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   while (len--)
     {
        DATA32              tmp;
        if (*src)
          {
             RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
          }
        src++;
        dst++;
     }
}
static void
__imlib_ReBlendShapedSpanToRGB(DATA8 * src, DATA32 color, DATA32 * dst, int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color),
                              A_VAL(&color), dst);
                     break;
                  }
               default:
                  {
                     MULT(a, *src, A_VAL(&color), tmp);
                     BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                              dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                break;
             }
          default:
             {
                BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), *src,
                         dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
static void
__imlib_ReBlendShapedSpanToRGBA(DATA8 * src, DATA32 color, DATA32 * dst,
                                int len)
{
   if (A_VAL(&color) < 255)
     {
        while (len--)
          {
             DATA32              tmp;
             DATA8               a, aa;
             switch (*src)
               {
               case 0:
                  break;
               case 255:
                  {
                     a = pow_lut[A_VAL(&color)][A_VAL(dst)];
                     BLEND_COLOR(A_VAL(&color), A_VAL(dst), 255, A_VAL(dst));
                     BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                              dst);
                     break;
                  }
               default:
                  {
                     MULT(aa, *src, A_VAL(&color), tmp);
                     a = pow_lut[aa][A_VAL(dst)];
                     BLEND_COLOR(aa, A_VAL(dst), 255, A_VAL(dst));
                     BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a,
                              dst);
                     break;
                  }
               }
             src++;
             dst++;
          }
        return;
     }
   while (len--)
     {
        DATA32              tmp;
        DATA8               a;
        switch (*src)
          {
          case 0:
             break;
          case 255:
             {
                A_VAL(dst) = 255;
                RE_COPY(R_VAL(&color), G_VAL(&color), B_VAL(&color), dst);
                break;
             }
          default:
             {
                a = pow_lut[*src][A_VAL(dst)];
                BLEND_COLOR(*src, A_VAL(dst), 255, A_VAL(dst));
                BLEND_RE(R_VAL(&color), G_VAL(&color), B_VAL(&color), a, dst);
                break;
             }
          }
        src++;
        dst++;
     }
}
ImlibPointDrawFunction
__imlib_GetPointDrawFunction(ImlibOp op, char dst_alpha, char blend)
{
   /* [ operation ][ dst_alpha ][ blend ]  */
   static ImlibPointDrawFunction ptfuncs[4][2][2] =
      /* OP_COPY */
   { {{__imlib_CopyToRGB, __imlib_BlendToRGB},
      {__imlib_CopyToRGBA, __imlib_BlendToRGBA}},
   /* OP_ADD */
   {{__imlib_AddCopyToRGB, __imlib_AddBlendToRGB},
    {__imlib_AddCopyToRGBA, __imlib_AddBlendToRGBA}},
   /* OP_SUBTRACT */
   {{__imlib_SubCopyToRGB, __imlib_SubBlendToRGB},
    {__imlib_SubCopyToRGBA, __imlib_SubBlendToRGBA}},
   /* OP_RESHADE */
   {{__imlib_ReCopyToRGB, __imlib_ReBlendToRGB},
    {__imlib_ReCopyToRGBA, __imlib_ReBlendToRGBA}},
   };
   int                 opi = (op == OP_COPY) ? 0
      : (op == OP_ADD) ? 1
      : (op == OP_SUBTRACT) ? 2 : (op == OP_RESHADE) ? 3 : -1;
   if (opi == -1)
      return NULL;
   return ptfuncs[opi][!!dst_alpha][!!blend];
}
ImlibSpanDrawFunction
__imlib_GetSpanDrawFunction(ImlibOp op, char dst_alpha, char blend)
{
   static ImlibSpanDrawFunction spanfuncs[4][2][2] =
      /* OP_COPY */
   { {{__imlib_CopySpanToRGB, __imlib_BlendSpanToRGB},
      {__imlib_CopySpanToRGBA, __imlib_BlendSpanToRGBA}},
   /* OP_ADD */
   {{__imlib_AddCopySpanToRGB, __imlib_AddBlendSpanToRGB},
    {__imlib_AddCopySpanToRGBA, __imlib_AddBlendSpanToRGBA}},
   /* OP_SUBTRACT */
   {{__imlib_SubCopySpanToRGB, __imlib_SubBlendSpanToRGB},
    {__imlib_SubCopySpanToRGBA, __imlib_SubBlendSpanToRGBA}},
   /* OP_RESHADE */
   {{__imlib_ReCopySpanToRGB, __imlib_ReBlendSpanToRGB},
    {__imlib_ReCopySpanToRGBA, __imlib_ReBlendSpanToRGBA}},
   };
   int                 opi = (op == OP_COPY) ? 0
      : (op == OP_ADD) ? 1
      : (op == OP_SUBTRACT) ? 2 : (op == OP_RESHADE) ? 3 : -1;
   if (opi == -1)
      return NULL;
   return spanfuncs[opi][!!dst_alpha][!!blend];
}
ImlibShapedSpanDrawFunction
__imlib_GetShapedSpanDrawFunction(ImlibOp op, char dst_alpha, char blend)
{
   static ImlibShapedSpanDrawFunction shapedspanfuncs[4][2][2] =
      /* OP_COPY */
   { {{__imlib_CopyShapedSpanToRGB, __imlib_BlendShapedSpanToRGB},
      {__imlib_CopyShapedSpanToRGBA, __imlib_BlendShapedSpanToRGBA}},
   /* OP_ADD */
   {{__imlib_AddCopyShapedSpanToRGB, __imlib_AddBlendShapedSpanToRGB},
    {__imlib_AddCopyShapedSpanToRGBA, __imlib_AddBlendShapedSpanToRGBA}},
   /* OP_SUBTRACT */
   {{__imlib_SubCopyShapedSpanToRGB, __imlib_SubBlendShapedSpanToRGB},
    {__imlib_SubCopyShapedSpanToRGBA, __imlib_SubBlendShapedSpanToRGBA}},
   /* OP_RESHADE */
   {{__imlib_ReCopyShapedSpanToRGB, __imlib_ReBlendShapedSpanToRGB},
    {__imlib_ReCopyShapedSpanToRGBA, __imlib_ReBlendShapedSpanToRGBA}},
   };
   int                 opi = (op == OP_COPY) ? 0
      : (op == OP_ADD) ? 1
      : (op == OP_SUBTRACT) ? 2 : (op == OP_RESHADE) ? 3 : -1;
   if (opi == -1)
      return NULL;
   return shapedspanfuncs[opi][!!dst_alpha][!!blend];
}