1 --- gd-2.0.33/gd.c.orig 2006-12-23 02:27:25.723423857 +0100
2 +++ gd-2.0.33/gd.c 2006-12-23 02:31:59.599031139 +0100
5 static void gdImageBrushApply (gdImagePtr im, int x, int y);
6 static void gdImageTileApply (gdImagePtr im, int x, int y);
8 +static int gdLayerOverlay(int dst, int src);
9 +static int gdAlphaOverlayColor(int src, int dst, int max);
11 BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y);
13 BGD_DECLARE(gdImagePtr) gdImageCreate (int sx, int sy)
16 if (gdImageBoundsSafeMacro (im, x, y))
20 - if (im->alphaBlendingFlag)
22 - im->tpixels[y][x] = gdAlphaBlend (im->tpixels[y][x], color);
26 - im->tpixels[y][x] = color;
28 + if (im->trueColor) {
29 + switch (im->alphaBlendingFlag) {
31 + case gdEffectReplace:
32 + im->tpixels[y][x] = color;
34 + case gdEffectAlphaBlend:
35 + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
37 + case gdEffectNormal:
38 + im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
40 + case gdEffectOverlay :
41 + im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);
47 @@ -2287,6 +2297,564 @@
53 + * Rotate function Added on 2003/12
54 + * by Pierre-Alain Joye (pajoye@pearfr.org)
56 +/* Begin rotate function */
59 +#endif /* ROTATE_PI */
61 +#define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180
62 +BGD_DECLARE(void) gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent)
64 + typedef int (*FuncPtr)(gdImagePtr, int, int);
65 + int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
68 + int pxlOldLeft, pxlLeft=0, pxlSrc;
70 + /* Keep clrBack as color index if required */
71 + if (src->trueColor) {
72 + pxlOldLeft = clrBack;
73 + f = gdImageGetTrueColorPixel;
75 + pxlOldLeft = clrBack;
76 + clrBackR = gdImageRed(src, clrBack);
77 + clrBackG = gdImageGreen(src, clrBack);
78 + clrBackB = gdImageBlue(src, clrBack);
79 + clrBackA = gdImageAlpha(src, clrBack);
80 + clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
81 + f = gdImageGetPixel;
84 + for (i = 0; i < iOffset; i++) {
85 + gdImageSetPixel (dst, i, uRow, clrBack);
89 + gdImageSetPixel (dst, i, uRow, clrBack);
92 + for (i = 0; i < src->sx; i++) {
93 + pxlSrc = f (src,i,uRow);
95 + r = (int)(gdImageRed(src,pxlSrc) * dWeight);
96 + g = (int)(gdImageGreen(src,pxlSrc) * dWeight);
97 + b = (int)(gdImageBlue(src,pxlSrc) * dWeight);
98 + a = (int)(gdImageAlpha(src,pxlSrc) * dWeight);
100 + pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
102 + if (pxlLeft == -1) {
103 + pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
106 + r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
107 + g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
108 + b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
109 + a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
127 + if (ignoretransparent && pxlSrc == dst->transparent) {
128 + pxlSrc = dst->transparent;
130 + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
132 + if (pxlSrc == -1) {
133 + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
137 + if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
138 + gdImageSetPixel (dst, i+iOffset, uRow, pxlSrc);
141 + pxlOldLeft = pxlLeft;
147 + gdImageSetPixel (dst, i, uRow, pxlLeft);
150 + gdImageSetPixel (dst, iOffset, uRow, clrBack);
154 + while (++i < dst->sx) {
155 + gdImageSetPixel (dst, i, uRow, clrBack);
159 +void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent)
161 + typedef int (*FuncPtr)(gdImagePtr, int, int);
162 + int i, iYPos=0, r, g, b, a;
164 + int pxlOldLeft, pxlLeft=0, pxlSrc;
166 + if (src->trueColor) {
167 + f = gdImageGetTrueColorPixel;
169 + f = gdImageGetPixel;
172 + for (i = 0; i<=iOffset; i++) {
173 + gdImageSetPixel (dst, uCol, i, clrBack);
175 + r = (int)((double)gdImageRed(src,clrBack) * dWeight);
176 + g = (int)((double)gdImageGreen(src,clrBack) * dWeight);
177 + b = (int)((double)gdImageBlue(src,clrBack) * dWeight);
178 + a = (int)((double)gdImageAlpha(src,clrBack) * dWeight);
180 + pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a);
182 + for (i = 0; i < src->sy; i++) {
183 + pxlSrc = f (src, uCol, i);
184 + iYPos = i + iOffset;
186 + r = (int)((double)gdImageRed(src,pxlSrc) * dWeight);
187 + g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight);
188 + b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight);
189 + a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight);
191 + pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
193 + if (pxlLeft == -1) {
194 + pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
197 + r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
198 + g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
199 + b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
200 + a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
218 + if (ignoretransparent && pxlSrc == dst->transparent) {
219 + pxlSrc = dst->transparent;
221 + pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
223 + if (pxlSrc == -1) {
224 + pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
228 + if ((iYPos >= 0) && (iYPos < dst->sy)) {
229 + gdImageSetPixel (dst, uCol, iYPos, pxlSrc);
232 + pxlOldLeft = pxlLeft;
237 + gdImageSetPixel (dst, uCol, i, pxlLeft);
241 + while (++i < dst->sy) {
242 + gdImageSetPixel (dst, uCol, i, clrBack);
246 +/* Rotates an image by 90 degrees (counter clockwise) */
247 +BGD_DECLARE(gdImagePtr) gdImageRotate90 (gdImagePtr src, int ignoretransparent)
252 + typedef int (*FuncPtr)(gdImagePtr, int, int);
255 + if (src->trueColor) {
256 + f = gdImageGetTrueColorPixel;
258 + f = gdImageGetPixel;
260 + dst = gdImageCreateTrueColor(src->sy, src->sx);
261 + dst->transparent = src->transparent;
264 + gdImagePaletteCopy (dst, src);
266 + for (uY = 0; uY<src->sy; uY++) {
267 + for (uX = 0; uX<src->sx; uX++) {
268 + c = f (src, uX, uY);
269 + if (!src->trueColor) {
270 + r = gdImageRed(src,c);
271 + g = gdImageGreen(src,c);
272 + b = gdImageBlue(src,c);
273 + a = gdImageAlpha(src,c);
274 + c = gdTrueColorAlpha(r, g, b, a);
276 + if (ignoretransparent && c == dst->transparent) {
277 + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
279 + gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
288 +/* Rotates an image by 180 degrees (counter clockwise) */
289 +BGD_DECLARE(gdImagePtr) gdImageRotate180 (gdImagePtr src, int ignoretransparent)
294 + typedef int (*FuncPtr)(gdImagePtr, int, int);
297 + if (src->trueColor) {
298 + f = gdImageGetTrueColorPixel;
300 + f = gdImageGetPixel;
302 + dst = gdImageCreateTrueColor(src->sx, src->sy);
303 + dst->transparent = src->transparent;
306 + gdImagePaletteCopy (dst, src);
308 + for (uY = 0; uY<src->sy; uY++) {
309 + for (uX = 0; uX<src->sx; uX++) {
310 + c = f (src, uX, uY);
311 + if (!src->trueColor) {
312 + r = gdImageRed(src,c);
313 + g = gdImageGreen(src,c);
314 + b = gdImageBlue(src,c);
315 + a = gdImageAlpha(src,c);
316 + c = gdTrueColorAlpha(r, g, b, a);
319 + if (ignoretransparent && c == dst->transparent) {
320 + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent);
322 + gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
331 +/* Rotates an image by 270 degrees (counter clockwise) */
332 +BGD_DECLARE(gdImagePtr) gdImageRotate270 (gdImagePtr src, int ignoretransparent)
337 + typedef int (*FuncPtr)(gdImagePtr, int, int);
340 + if (src->trueColor) {
341 + f = gdImageGetTrueColorPixel;
343 + f = gdImageGetPixel;
345 + dst = gdImageCreateTrueColor (src->sy, src->sx);
346 + dst->transparent = src->transparent;
349 + gdImagePaletteCopy (dst, src);
351 + for (uY = 0; uY<src->sy; uY++) {
352 + for (uX = 0; uX<src->sx; uX++) {
353 + c = f (src, uX, uY);
354 + if (!src->trueColor) {
355 + r = gdImageRed(src,c);
356 + g = gdImageGreen(src,c);
357 + b = gdImageBlue(src,c);
358 + a = gdImageAlpha(src,c);
359 + c = gdTrueColorAlpha(r, g, b, a);
362 + if (ignoretransparent && c == dst->transparent) {
363 + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent);
365 + gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
374 +BGD_DECLARE(gdImagePtr) gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
376 + typedef int (*FuncPtr)(gdImagePtr, int, int);
377 + gdImagePtr dst1,dst2,dst3;
379 + double dRadAngle, dSinE, dTan, dShear;
380 + double dOffset; /* Variable skew offset */
381 + int u, iShear, newx, newy;
382 + int clrBackR, clrBackG, clrBackB, clrBackA;
384 + /* See GEMS I for the algorithm details */
385 + dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
386 + dSinE = sin (dRadAngle);
387 + dTan = tan (dRadAngle / 2.0);
389 + newx = (int)(src->sx + src->sy * fabs(dTan));
393 + if (src->trueColor) {
394 + f = gdImageGetTrueColorPixel;
396 + f = gdImageGetPixel;
399 + dst1 = gdImageCreateTrueColor(newx, newy);
400 + /******* Perform 1st shear (horizontal) ******/
401 + if (dst1 == NULL) {
404 + dst1->alphaBlendingFlag = gdEffectReplace;
406 + if (dAngle == 0.0) {
407 + /* Returns copy of src */
408 + gdImageCopy (dst1, src,0,0,0,0,src->sx,src->sy);
412 + gdImagePaletteCopy (dst1, src);
414 + if (ignoretransparent) {
415 + if (gdImageTrueColor(src)) {
416 + dst1->transparent = src->transparent;
419 + dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127);
423 + dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
424 + dSinE = sin (dRadAngle);
425 + dTan = tan (dRadAngle / 2.0);
427 + for (u = 0; u < dst1->sy; u++) {
429 + dShear = ((double)(u + 0.5)) * dTan;
431 + dShear = ((double)(u - dst1->sy) + 0.5) * dTan;
434 + iShear = (int)floor(dShear);
435 + gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack, ignoretransparent);
439 + The 1st shear may use the original clrBack as color index
440 + Convert it once here
442 + if(!src->trueColor) {
443 + clrBackR = gdImageRed(src, clrBack);
444 + clrBackG = gdImageGreen(src, clrBack);
445 + clrBackB = gdImageBlue(src, clrBack);
446 + clrBackA = gdImageAlpha(src, clrBack);
447 + clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
453 + dOffset = (src->sx-1) * dSinE;
455 + dOffset = -dSinE * (src->sx - newx);
458 + newy = (int) ((double) src->sx * fabs( dSinE ) + (double) src->sy * cos (dRadAngle))+1;
460 + if (src->trueColor) {
461 + f = gdImageGetTrueColorPixel;
463 + f = gdImageGetPixel;
465 + dst2 = gdImageCreateTrueColor(newx, newy);
466 + if (dst2 == NULL) {
467 + gdImageDestroy(dst1);
470 + dst2->alphaBlendingFlag = gdEffectReplace;
471 + if (ignoretransparent) {
472 + dst2->transparent = dst1->transparent;
475 + for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) {
476 + iShear = (int)floor (dOffset);
477 + gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack, ignoretransparent);
481 + gdImageDestroy(dst1);
483 + newx = (int) ((double)src->sy * fabs (dSinE) + (double)src->sx * cos (dRadAngle)) + 1;
486 + if (src->trueColor) {
487 + f = gdImageGetTrueColorPixel;
489 + f = gdImageGetPixel;
491 + dst3 = gdImageCreateTrueColor(newx, newy);
492 + if (dst3 == NULL) {
493 + gdImageDestroy(dst2);
497 + dst3->alphaBlendingFlag = gdEffectReplace;
498 + if (ignoretransparent) {
499 + dst3->transparent = dst2->transparent;
502 + if (dSinE >= 0.0) {
503 + dOffset = (double)(src->sx - 1) * dSinE * -dTan;
505 + dOffset = dTan * ((double)(src->sx - 1) * -dSinE + (double)(1 - newy));
508 + for (u = 0; u < dst3->sy; u++, dOffset += dTan) {
509 + int iShear = (int)floor(dOffset);
510 + gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack, ignoretransparent);
513 + gdImageDestroy(dst2);
518 +BGD_DECLARE(gdImagePtr) gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent)
520 + gdImagePtr pMidImg;
521 + gdImagePtr rotatedImg;
527 + if (!gdImageTrueColor(src) && clrBack>=gdImageColorsTotal(src)) {
531 + while (dAngle >= 360.0) {
535 + while (dAngle < 0) {
539 + if (dAngle == 90.00) {
540 + return gdImageRotate90(src, ignoretransparent);
542 + if (dAngle == 180.00) {
543 + return gdImageRotate180(src, ignoretransparent);
545 + if(dAngle == 270.00) {
546 + return gdImageRotate270 (src, ignoretransparent);
549 + if ((dAngle > 45.0) && (dAngle <= 135.0)) {
550 + pMidImg = gdImageRotate90 (src, ignoretransparent);
552 + } else if ((dAngle > 135.0) && (dAngle <= 225.0)) {
553 + pMidImg = gdImageRotate180 (src, ignoretransparent);
555 + } else if ((dAngle > 225.0) && (dAngle <= 315.0)) {
556 + pMidImg = gdImageRotate270 (src, ignoretransparent);
559 + return gdImageRotate45 (src, dAngle, clrBack, ignoretransparent);
562 + if (pMidImg == NULL) {
566 + rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack, ignoretransparent);
567 + gdImageDestroy(pMidImg);
571 +/* End Rotate function */
573 +static int gdLayerOverlay (int dst, int src)
576 + a1 = gdAlphaMax - gdTrueColorGetAlpha(dst);
577 + a2 = gdAlphaMax - gdTrueColorGetAlpha(src);
578 + return ( ((gdAlphaMax - a1*a2/gdAlphaMax) << 24) +
579 + (gdAlphaOverlayColor( gdTrueColorGetRed(src), gdTrueColorGetRed(dst), gdRedMax ) << 16) +
580 + (gdAlphaOverlayColor( gdTrueColorGetGreen(src), gdTrueColorGetGreen(dst), gdGreenMax ) << 8) +
581 + (gdAlphaOverlayColor( gdTrueColorGetBlue(src), gdTrueColorGetBlue(dst), gdBlueMax ))
585 +static int gdAlphaOverlayColor (int src, int dst, int max )
587 + /* this function implements the algorithm
589 + * for dst[rgb] < 0.5,
590 + * c[rgb] = 2.src[rgb].dst[rgb]
591 + * and for dst[rgb] > 0.5,
592 + * c[rgb] = -2.src[rgb].dst[rgb] + 2.dst[rgb] + 2.src[rgb] - 1
598 + /* in the "light" zone */
599 + return dst + (src << 1) - (dst * src / max) - max;
601 + /* in the "dark" zone */
602 + return dst * src / max;
607 +/* End of part code from php */
609 /* When gd 1.x was first created, floating point was to be avoided.
610 These days it is often faster than table lookups or integer
611 arithmetic. The routine below is shamelessly, gloriously
612 --- gd-2.0.33/gd.h.orig 2006-12-23 01:06:10.281588261 +0100
613 +++ gd-2.0.33/gd.h 2006-12-23 01:48:20.989805102 +0100
615 #define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16)
616 #define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
617 #define gdTrueColorGetBlue(c) ((c) & 0x0000FF)
618 +#define gdEffectReplace 0
619 +#define gdEffectAlphaBlend 1
620 +#define gdEffectNormal 2
621 +#define gdEffectOverlay 3
623 /* This function accepts truecolor pixel values only. The
624 source color is composited with the destination color
627 int srcWidth, int srcHeight, int angle);
629 +gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent);
630 +gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
631 +gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
632 +gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
633 +gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
635 BGD_DECLARE(void) gdImageSetBrush (gdImagePtr im, gdImagePtr brush);
636 BGD_DECLARE(void) gdImageSetTile (gdImagePtr im, gdImagePtr tile);
637 BGD_DECLARE(void) gdImageSetAntiAliased (gdImagePtr im, int c);