]> granicus.if.org Git - php/commitdiff
Add support for gdEffectMultiply
authorChristoph M. Becker <cmbecker69@gmx.de>
Sun, 2 Oct 2016 17:06:59 +0000 (19:06 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Sun, 2 Oct 2016 17:10:13 +0000 (19:10 +0200)
gdLayerMultiply() has been introduced in libgd 2.1.1, and as such would have
been already available for imagelayereffect() with a system libgd. We port
the respective code to the bundled libgd, and also make IMG_EFFECT_MULTIPLY
available to userland.

UPGRADING
ext/gd/gd.c
ext/gd/libgd/gd.c
ext/gd/libgd/gd.h

index 055b313974e2ab72b7d4bc93ac218b7464b67dc9..38250ed303a1bd140072bee74b92b5bfe5276f8d 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -112,6 +112,9 @@ PHP 7.2 UPGRADE NOTES
 10. New Global Constants
 ========================================
 
+- GD:
+  . IMG_EFFECT_MULTIPLY
+
 - Standard:
   . PASSWORD_ARGON2_DEFAULT_MEMORY_COST
   . PASSWORD_ARGON2_DEFAULT_TIME_COST
index 6ff2a1c9405736d8f0bcd73af3c500485ae8989b..f8569779baaeb3392edd5ca68711bdbb7fbd819d 100644 (file)
@@ -1098,6 +1098,9 @@ PHP_MINIT_FUNCTION(gd)
        REGISTER_LONG_CONSTANT("IMG_EFFECT_ALPHABLEND", gdEffectAlphaBlend, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT);
+#ifdef gdEffectMultiply
+       REGISTER_LONG_CONSTANT("IMG_EFFECT_MULTIPLY", gdEffectMultiply, CONST_CS | CONST_PERSISTENT);
+#endif
 
        REGISTER_LONG_CONSTANT("IMG_CROP_DEFAULT", GD_CROP_DEFAULT, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IMG_CROP_TRANSPARENT", GD_CROP_TRANSPARENT, CONST_CS | CONST_PERSISTENT);
index 5c3593ed1b71e27cca5a7bcfb2e75f7b8ae0c7d9..afa8e287cceea96ad455b62c1413d0a67934918f 100644 (file)
@@ -93,7 +93,6 @@ extern int gdSinT[];
 
 static void gdImageBrushApply(gdImagePtr im, int x, int y);
 static void gdImageTileApply(gdImagePtr im, int x, int y);
-static int gdLayerOverlay(int dst, int src);
 static int gdAlphaOverlayColor(int src, int dst, int max);
 int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y);
 
@@ -756,14 +755,15 @@ void gdImageSetPixel (gdImagePtr im, int x, int y, int color)
                                                        im->tpixels[y][x] = color;
                                                        break;
                                                case gdEffectAlphaBlend:
-                                                       im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
-                                                       break;
                                                case gdEffectNormal:
                                                        im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
                                                        break;
                                                case gdEffectOverlay :
                                                        im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);
                                                        break;
+                                               case gdEffectMultiply :
+                                                       im->tpixels[y][x] = gdLayerMultiply(im->tpixels[y][x], color);
+                                                       break;
                                        }
                                } else {
                                        im->pixels[y][x] = color;
@@ -2951,7 +2951,7 @@ void gdImageSaveAlpha (gdImagePtr im, int saveAlphaArg)
        im->saveAlphaFlag = saveAlphaArg;
 }
 
-static int gdLayerOverlay (int dst, int src)
+int gdLayerOverlay (int dst, int src)
 {
        int a1, a2;
        a1 = gdAlphaMax - gdTrueColorGetAlpha(dst);
@@ -2984,6 +2984,28 @@ static int gdAlphaOverlayColor (int src, int dst, int max )
        }
 }
 
+int gdLayerMultiply (int dst, int src)
+{
+       int a1, a2, r1, r2, g1, g2, b1, b2;
+       a1 = gdAlphaMax - gdTrueColorGetAlpha(src);
+       a2 = gdAlphaMax - gdTrueColorGetAlpha(dst);
+
+       r1 = gdRedMax - (a1 * (gdRedMax - gdTrueColorGetRed(src))) / gdAlphaMax;
+       r2 = gdRedMax - (a2 * (gdRedMax - gdTrueColorGetRed(dst))) / gdAlphaMax;
+       g1 = gdGreenMax - (a1 * (gdGreenMax - gdTrueColorGetGreen(src))) / gdAlphaMax;
+       g2 = gdGreenMax - (a2 * (gdGreenMax - gdTrueColorGetGreen(dst))) / gdAlphaMax;
+       b1 = gdBlueMax - (a1 * (gdBlueMax - gdTrueColorGetBlue(src))) / gdAlphaMax;
+       b2 = gdBlueMax - (a2 * (gdBlueMax - gdTrueColorGetBlue(dst))) / gdAlphaMax ;
+
+       a1 = gdAlphaMax - a1;
+       a2 = gdAlphaMax - a2;
+       return ( ((a1*a2/gdAlphaMax) << 24) +
+                        ((r1*r2/gdRedMax) << 16) +
+                        ((g1*g2/gdGreenMax) << 8) +
+                        ((b1*b2/gdBlueMax))
+               );
+}
+
 void gdImageSetClip (gdImagePtr im, int x1, int y1, int x2, int y2)
 {
        if (x1 < 0) {
index 12832ded34052c99f75ec5fd0c4894c2ab9088fd..4b6f86e28c33575ef83373f7e1cfa5761262ac8b 100644 (file)
@@ -92,6 +92,7 @@ void php_gd_error(const char *format, ...);
 #define gdEffectAlphaBlend 1
 #define gdEffectNormal 2
 #define gdEffectOverlay 3
+#define gdEffectMultiply 4
 
 #define GD_TRUE 1
 #define GD_FALSE 0
@@ -104,6 +105,8 @@ void php_gd_error(const char *format, ...);
        The resulting color is opaque. */
 
 int gdAlphaBlend(int dest, int src);
+int gdLayerOverlay(int dst, int src);
+int gdLayerMultiply(int dest, int src);
 
 /**
  * Group: Transform