Skip to content

Commit c8ce18c

Browse files
committed
- allow to keep or ignore the transparent color in imagerotate (thx
Ken Coar to report this "bug") - be sure to restore alphablending in imagefill - use zend_parse_parameter in imagerotate
1 parent f95651e commit c8ce18c

File tree

3 files changed

+82
-44
lines changed

3 files changed

+82
-44
lines changed

ext/gd/gd.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,23 +1208,19 @@ PHP_FUNCTION(imagecopyresampled)
12081208
Rotate an image using a custom angle */
12091209
PHP_FUNCTION(imagerotate)
12101210
{
1211-
zval **SIM, **ANGLE, **BGDCOLOR;
1211+
zval *SIM;
12121212
gdImagePtr im_dst, im_src;
12131213
double degrees;
12141214
long color;
1215+
long ignoretransparent = 0;
12151216

1216-
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &SIM, &ANGLE, &BGDCOLOR) == FAILURE) {
1217-
ZEND_WRONG_PARAM_COUNT();
1217+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rdl|l", &SIM, &degrees, &color, &ignoretransparent) == FAILURE) {
1218+
RETURN_FALSE;
12181219
}
12191220

1220-
ZEND_FETCH_RESOURCE(im_src, gdImagePtr, SIM, -1, "Image", le_gd);
1221-
1222-
convert_to_long_ex(BGDCOLOR);
1223-
color = Z_LVAL_PP(BGDCOLOR);
1221+
ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
12241222

1225-
convert_to_double_ex(ANGLE);
1226-
degrees = Z_DVAL_PP(ANGLE);
1227-
im_dst = gdImageRotate(im_src, degrees, color);
1223+
im_dst = gdImageRotate(im_src, degrees, color, ignoretransparent);
12281224

12291225
if (im_dst != NULL) {
12301226
ZEND_REGISTER_RESOURCE(return_value, im_dst, le_gd);

ext/gd/libgd/gd.c

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,6 +1890,7 @@ void gdImageFill(gdImagePtr im, int x, int y, int nc)
18901890

18911891
if (nc==gdTiled){
18921892
_gdImageFillTiled(im,x,y,nc);
1893+
im->alphaBlendingFlag = alphablending_bak;
18931894
return;
18941895
}
18951896

@@ -2192,7 +2193,7 @@ void gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int s
21922193
int tox, toy;
21932194
int ncR, ncG, ncB;
21942195
toy = dstY;
2195-
2196+
printf("srccpopy:%X", src->transparent);
21962197
for (y = srcY; y < (srcY + h); y++) {
21972198
tox = dstX;
21982199
for (x = srcX; x < (srcX + w); x++) {
@@ -2493,7 +2494,7 @@ void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i
24932494
#endif /* ROTATE_PI */
24942495

24952496
#define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180
2496-
void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack)
2497+
void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent)
24972498
{
24982499
typedef int (*FuncPtr)(gdImagePtr, int, int);
24992500
int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
@@ -2558,10 +2559,14 @@ void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double
25582559
a = 127;
25592560
}
25602561

2561-
pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
2562+
if (ignoretransparent && pxlSrc == dst->transparent) {
2563+
pxlSrc = dst->transparent;
2564+
} else {
2565+
pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
25622566

2563-
if (pxlSrc == -1) {
2564-
pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
2567+
if (pxlSrc == -1) {
2568+
pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
2569+
}
25652570
}
25662571

25672572
if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
@@ -2586,7 +2591,7 @@ void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double
25862591
}
25872592
}
25882593

2589-
void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack)
2594+
void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent)
25902595
{
25912596
typedef int (*FuncPtr)(gdImagePtr, int, int);
25922597
int i, iYPos=0, r, g, b, a;
@@ -2645,10 +2650,14 @@ void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double
26452650
a = 127;
26462651
}
26472652

2648-
pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
2653+
if (ignoretransparent && pxlSrc == dst->transparent) {
2654+
pxlSrc = dst->transparent;
2655+
} else {
2656+
pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
26492657

2650-
if (pxlSrc == -1) {
2651-
pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
2658+
if (pxlSrc == -1) {
2659+
pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
2660+
}
26522661
}
26532662

26542663
if ((iYPos >= 0) && (iYPos < dst->sy)) {
@@ -2670,7 +2679,7 @@ void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double
26702679
}
26712680

26722681
/* Rotates an image by 90 degrees (counter clockwise) */
2673-
gdImagePtr gdImageRotate90 (gdImagePtr src)
2682+
gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
26742683
{
26752684
int uY, uX;
26762685
int c,r,g,b,a;
@@ -2684,6 +2693,7 @@ gdImagePtr gdImageRotate90 (gdImagePtr src)
26842693
f = gdImageGetPixel;
26852694
}
26862695
dst = gdImageCreateTrueColor(src->sy, src->sx);
2696+
dst->transparent = src->transparent;
26872697

26882698
if (dst != NULL) {
26892699
gdImagePaletteCopy (dst, src);
@@ -2698,7 +2708,11 @@ gdImagePtr gdImageRotate90 (gdImagePtr src)
26982708
a = gdImageAlpha(src,c);
26992709
c = gdTrueColorAlpha(r, g, b, a);
27002710
}
2701-
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
2711+
if (ignoretransparent && c == dst->transparent) {
2712+
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
2713+
} else {
2714+
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
2715+
}
27022716
}
27032717
}
27042718
}
@@ -2707,7 +2721,7 @@ gdImagePtr gdImageRotate90 (gdImagePtr src)
27072721
}
27082722

27092723
/* Rotates an image by 180 degrees (counter clockwise) */
2710-
gdImagePtr gdImageRotate180 (gdImagePtr src)
2724+
gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
27112725
{
27122726
int uY, uX;
27132727
int c,r,g,b,a;
@@ -2721,6 +2735,7 @@ gdImagePtr gdImageRotate180 (gdImagePtr src)
27212735
f = gdImageGetPixel;
27222736
}
27232737
dst = gdImageCreateTrueColor(src->sx, src->sy);
2738+
dst->transparent = src->transparent;
27242739

27252740
if (dst != NULL) {
27262741
gdImagePaletteCopy (dst, src);
@@ -2735,7 +2750,11 @@ gdImagePtr gdImageRotate180 (gdImagePtr src)
27352750
a = gdImageAlpha(src,c);
27362751
c = gdTrueColorAlpha(r, g, b, a);
27372752
}
2738-
gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
2753+
if (ignoretransparent && c == dst->transparent) {
2754+
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
2755+
} else {
2756+
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
2757+
}
27392758
}
27402759
}
27412760
}
@@ -2744,7 +2763,7 @@ gdImagePtr gdImageRotate180 (gdImagePtr src)
27442763
}
27452764

27462765
/* Rotates an image by 270 degrees (counter clockwise) */
2747-
gdImagePtr gdImageRotate270 ( gdImagePtr src )
2766+
gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
27482767
{
27492768
int uY, uX;
27502769
int c,r,g,b,a;
@@ -2758,6 +2777,7 @@ gdImagePtr gdImageRotate270 ( gdImagePtr src )
27582777
f = gdImageGetPixel;
27592778
}
27602779
dst = gdImageCreateTrueColor (src->sy, src->sx);
2780+
dst->transparent = src->transparent;
27612781

27622782
if (dst != NULL) {
27632783
gdImagePaletteCopy (dst, src);
@@ -2772,15 +2792,19 @@ gdImagePtr gdImageRotate270 ( gdImagePtr src )
27722792
a = gdImageAlpha(src,c);
27732793
c = gdTrueColorAlpha(r, g, b, a);
27742794
}
2775-
gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
2795+
if (ignoretransparent && c == dst->transparent) {
2796+
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
2797+
} else {
2798+
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
2799+
}
27762800
}
27772801
}
27782802
}
27792803

27802804
return dst;
27812805
}
27822806

2783-
gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
2807+
gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
27842808
{
27852809
typedef int (*FuncPtr)(gdImagePtr, int, int);
27862810
gdImagePtr dst1,dst2,dst3;
@@ -2820,6 +2844,15 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
28202844

28212845
gdImagePaletteCopy (dst1, src);
28222846

2847+
if (ignoretransparent) {
2848+
if (gdImageTrueColor(src)) {
2849+
dst1->transparent = src->transparent;
2850+
} else {
2851+
2852+
dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127);
2853+
}
2854+
}
2855+
28232856
dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
28242857
dSinE = sin (dRadAngle);
28252858
dTan = tan (dRadAngle / 2.0);
@@ -2832,7 +2865,7 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
28322865
}
28332866

28342867
iShear = (int)floor(dShear);
2835-
gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack);
2868+
gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent);
28362869
}
28372870

28382871
/*
@@ -2868,10 +2901,13 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
28682901
return NULL;
28692902
}
28702903
dst2->alphaBlendingFlag = gdEffectReplace;
2904+
if (ignoretransparent) {
2905+
dst2->transparent = dst1->transparent;
2906+
}
28712907

28722908
for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) {
28732909
iShear = (int)floor (dOffset);
2874-
gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack);
2910+
gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack, ignoretransparent);
28752911
}
28762912

28772913
/* 3rd shear */
@@ -2890,23 +2926,29 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
28902926
gdImageDestroy(dst2);
28912927
return NULL;
28922928
}
2929+
2930+
dst3->alphaBlendingFlag = gdEffectReplace;
2931+
if (ignoretransparent) {
2932+
dst3->transparent = dst2->transparent;
2933+
}
2934+
28932935
if (dSinE >= 0.0) {
28942936
dOffset = (double)(src->sx - 1) * dSinE * -dTan;
28952937
} else {
28962938
dOffset = dTan * ((double)(src->sx - 1) * -dSinE + (double)(1 - newy));
28972939
}
28982940

28992941
for (u = 0; u < dst3->sy; u++, dOffset += dTan) {
2900-
int iShear = (int)floor(dOffset);
2901-
gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack);
2942+
int iShear = (int)floor(dOffset);
2943+
gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack, ignoretransparent);
29022944
}
29032945

29042946
gdImageDestroy(dst2);
29052947

29062948
return dst3;
29072949
}
29082950

2909-
gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack)
2951+
gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
29102952
{
29112953
gdImagePtr pMidImg;
29122954
gdImagePtr rotatedImg;
@@ -2928,33 +2970,33 @@ gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack)
29282970
}
29292971

29302972
if (dAngle == 90.00) {
2931-
return gdImageRotate90(src);
2973+
return gdImageRotate90(src, ignoretransparent);
29322974
}
29332975
if (dAngle == 180.00) {
2934-
return gdImageRotate180(src);
2976+
return gdImageRotate180(src, ignoretransparent);
29352977
}
29362978
if(dAngle == 270.00) {
2937-
return gdImageRotate270 ( src);
2979+
return gdImageRotate270 (src, ignoretransparent);
29382980
}
29392981

29402982
if ((dAngle > 45.0) && (dAngle <= 135.0)) {
2941-
pMidImg = gdImageRotate90 (src);
2983+
pMidImg = gdImageRotate90 (src, ignoretransparent);
29422984
dAngle -= 90.0;
29432985
} else if ((dAngle > 135.0) && (dAngle <= 225.0)) {
2944-
pMidImg = gdImageRotate180 (src);
2986+
pMidImg = gdImageRotate180 (src, ignoretransparent);
29452987
dAngle -= 180.0;
29462988
} else if ((dAngle > 225.0) && (dAngle <= 315.0)) {
2947-
pMidImg = gdImageRotate270 (src);
2989+
pMidImg = gdImageRotate270 (src, ignoretransparent);
29482990
dAngle -= 270.0;
29492991
} else {
2950-
return gdImageRotate45 (src, dAngle, clrBack);
2992+
return gdImageRotate45 (src, dAngle, clrBack, ignoretransparent);
29512993
}
29522994

29532995
if (pMidImg == NULL) {
29542996
return NULL;
29552997
}
29562998

2957-
rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack);
2999+
rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack, ignoretransparent);
29583000
gdImageDestroy(pMidImg);
29593001

29603002
return rotatedImg;

ext/gd/libgd/gd.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,11 @@ void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
536536
substituted automatically. */
537537
void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);
538538

539-
gdImagePtr gdImageRotate90(gdImagePtr src);
540-
gdImagePtr gdImageRotate180(gdImagePtr src);
541-
gdImagePtr gdImageRotate270(gdImagePtr src);
542-
gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack);
543-
gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack);
539+
gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent);
540+
gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
541+
gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
542+
gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
543+
gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
544544

545545
void gdImageSetBrush(gdImagePtr im, gdImagePtr brush);
546546
void gdImageSetTile(gdImagePtr im, gdImagePtr tile);

0 commit comments

Comments
 (0)