]> git.pld-linux.org Git - packages/gd.git/blame - gd-rotate_from_php.patch
- added gd(imagerotate) Provides, release 9
[packages/gd.git] / gd-rotate_from_php.patch
CommitLineData
1e268c02 1--- ./gd.c.org Thu Jul 1 23:30:30 2004
3d5c58ed 2+++ ./gd.c Thu Aug 12 14:42:03 2004
1e268c02
PG
3@@ -738,14 +738,27 @@
4 default:
5 if (gdImageBoundsSafeMacro (im, x, y))
6 {
7- if (im->trueColor)
8- {
9- if (im->alphaBlendingFlag)
10- {
11- im->tpixels[y][x] = gdAlphaBlend (im->tpixels[y][x], color);
12- }
13- else
14- {
15+ if (im->trueColor) {
16+ if (im->alphaBlendingFlag) {
17+ switch (im->alphaBlendingFlag) {
18+ default:
19+ im->tpixels[y][x] = gdAlphaBlend (im->tpixels[y][x], color);
20+ break;
21+ case gdEffectReplace:
22+ im->tpixels[y][x] = color;
23+ break;
24+/* case gdEffectAlphaBlend:
25+ im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);
26+ break;
27+ case gdEffectNormal:
28+ im->tpixels[y][x] = gdFullAlphaBlend(im->tpixels[y][x], color);
29+ break;
30+ case gdEffectOverlay :
31+ im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);
32+ break; */
33+ }
34+
35+ } else {
36 im->tpixels[y][x] = color;
37 }
38 }
39@@ -2261,6 +2274,496 @@
40 }
41 }
42
43+/* Taken from php... dirty hack... */
44+/*
45+ * Rotate function Added on 2003/12
46+ * by Pierre-Alain Joye (pajoye@pearfr.org)
47+ **/
48+/* Begin rotate function */
49+#ifdef ROTATE_PI
50+#undef ROTATE_PI
51+#endif /* ROTATE_PI */
52+
53+#define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180
54+BGD_DECLARE(void) gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack)
55+{
56+ typedef int (*FuncPtr)(gdImagePtr, int, int);
57+ int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
58+ FuncPtr f;
59+
60+ int pxlOldLeft, pxlLeft=0, pxlSrc;
61+
62+ /* Keep clrBack as color index if required */
63+ if (src->trueColor) {
64+ pxlOldLeft = clrBack;
65+ f = gdImageGetTrueColorPixel;
66+ } else {
67+ pxlOldLeft = clrBack;
68+ clrBackR = gdImageRed(src, clrBack);
69+ clrBackG = gdImageGreen(src, clrBack);
70+ clrBackB = gdImageBlue(src, clrBack);
71+ clrBackA = gdImageAlpha(src, clrBack);
72+ clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
73+ f = gdImageGetPixel;
74+ }
75+
76+ for (i = 0; i < iOffset; i++) {
77+ gdImageSetPixel (dst, i, uRow, clrBack);
78+ }
79+
80+ if (i < dst->sx) {
81+ gdImageSetPixel (dst, i, uRow, clrBack);
82+ }
83+
84+ for (i = 0; i < src->sx; i++) {
85+ pxlSrc = f (src,i,uRow);
86+
87+ r = (int)(gdImageRed(src,pxlSrc) * dWeight);
88+ g = (int)(gdImageGreen(src,pxlSrc) * dWeight);
89+ b = (int)(gdImageBlue(src,pxlSrc) * dWeight);
90+ a = (int)(gdImageAlpha(src,pxlSrc) * dWeight);
91+
92+ pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
93+
94+ if (pxlLeft == -1) {
95+ pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
96+ }
97+
98+ r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
99+ g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
100+ b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
101+ a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
102+
103+ if (r>255) {
104+ r = 255;
105+ }
106+
107+ if (g>255) {
108+ g = 255;
109+ }
110+
111+ if (b>255) {
112+ b = 255;
113+ }
114+
115+ if (a>127) {
116+ a = 127;
117+ }
118+
119+ pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
120+
121+ if (pxlSrc == -1) {
122+ pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
123+ }
124+
125+ if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
126+ gdImageSetPixel (dst, i+iOffset, uRow, pxlSrc);
127+ }
128+
129+ pxlOldLeft = pxlLeft;
130+ }
131+
132+ i += iOffset;
133+
134+ if (i < dst->sx) {
135+ gdImageSetPixel (dst, i, uRow, pxlLeft);
136+ }
137+
138+ gdImageSetPixel (dst, iOffset, uRow, clrBack);
139+
140+ i--;
141+
142+ while (++i < dst->sx) {
143+ gdImageSetPixel (dst, i, uRow, clrBack);
144+ }
145+}
146+
147+void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack)
148+{
149+ typedef int (*FuncPtr)(gdImagePtr, int, int);
150+ int i, iYPos=0, r, g, b, a;
151+ FuncPtr f;
152+ int pxlOldLeft, pxlLeft=0, pxlSrc;
153+
154+ if (src->trueColor) {
155+ f = gdImageGetTrueColorPixel;
156+ } else {
157+ f = gdImageGetPixel;
158+ }
159+
160+ for (i = 0; i<=iOffset; i++) {
161+ gdImageSetPixel (dst, uCol, i, clrBack);
162+ }
163+ r = (int)((double)gdImageRed(src,clrBack) * dWeight);
164+ g = (int)((double)gdImageGreen(src,clrBack) * dWeight);
165+ b = (int)((double)gdImageBlue(src,clrBack) * dWeight);
166+ a = (int)((double)gdImageAlpha(src,clrBack) * dWeight);
167+
168+ pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a);
169+
170+ for (i = 0; i < src->sy; i++) {
171+ pxlSrc = f (src, uCol, i);
172+ iYPos = i + iOffset;
173+
174+ r = (int)((double)gdImageRed(src,pxlSrc) * dWeight);
175+ g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight);
176+ b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight);
177+ a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight);
178+
179+ pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
180+
181+ if (pxlLeft == -1) {
182+ pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
183+ }
184+
185+ r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
186+ g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
187+ b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
188+ a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
189+
190+ if (r>255) {
191+ r = 255;
192+ }
193+
194+ if (g>255) {
195+ g = 255;
196+ }
197+
198+ if (b>255) {
199+ b = 255;
200+ }
201+
202+ if (a>127) {
203+ a = 127;
204+ }
205+
206+ pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
207+
208+ if (pxlSrc == -1) {
209+ pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
210+ }
211+
212+ if ((iYPos >= 0) && (iYPos < dst->sy)) {
213+ gdImageSetPixel (dst, uCol, iYPos, pxlSrc);
214+ }
215+
216+ pxlOldLeft = pxlLeft;
217+ }
218+
219+ i = iYPos;
220+ if (i < dst->sy) {
221+ gdImageSetPixel (dst, uCol, i, pxlLeft);
222+ }
223+
224+ i--;
225+ while (++i < dst->sy) {
226+ gdImageSetPixel (dst, uCol, i, clrBack);
227+ }
228+}
229+
230+/* Rotates an image by 90 degrees (counter clockwise) */
3d5c58ed 231+BGD_DECLARE(gdImagePtr) gdImageRotate90 (gdImagePtr src)
1e268c02
PG
232+{
233+ int uY, uX;
234+ int c, r,g,b,a;
235+ gdImagePtr dst;
236+ typedef int (*FuncPtr)(gdImagePtr, int, int);
237+ FuncPtr f;
238+
239+ if (src->trueColor) {
240+ f = gdImageGetTrueColorPixel;
241+ } else {
242+ f = gdImageGetPixel;
243+ }
244+ dst = gdImageCreateTrueColor(src->sy, src->sx);
245+
246+ if (dst != NULL) {
247+ gdImagePaletteCopy (dst, src);
248+
249+ for (uY = 0; uY<src->sy; uY++) {
250+ for (uX = 0; uX<src->sx; uX++) {
251+ c = f (src, uX, uY);
252+ if (!src->trueColor) {
253+ r = gdImageRed(src,c);
254+ g = gdImageGreen(src,c);
255+ b = gdImageBlue(src,c);
256+ a = gdImageAlpha(src,c);
257+ c = gdTrueColorAlpha(r, g, b, a);
258+ }
259+ gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
260+ }
261+ }
262+ }
263+
264+ return dst;
265+}
266+
267+/* Rotates an image by 180 degrees (counter clockwise) */
3d5c58ed 268+BGD_DECLARE(gdImagePtr) gdImageRotate180 (gdImagePtr src)
1e268c02
PG
269+{
270+ int uY, uX;
271+ int c,r,g,b,a;
272+ gdImagePtr dst;
273+ typedef int (*FuncPtr)(gdImagePtr, int, int);
274+ FuncPtr f;
275+
276+ if (src->trueColor) {
277+ f = gdImageGetTrueColorPixel;
278+ } else {
279+ f = gdImageGetPixel;
280+ }
281+ dst = gdImageCreateTrueColor(src->sx, src->sy);
282+
283+ if (dst != NULL) {
284+ gdImagePaletteCopy (dst, src);
285+
286+ for (uY = 0; uY<src->sy; uY++) {
287+ for (uX = 0; uX<src->sx; uX++) {
288+ c = f (src, uX, uY);
289+ if (!src->trueColor) {
290+ r = gdImageRed(src,c);
291+ g = gdImageGreen(src,c);
292+ b = gdImageBlue(src,c);
293+ a = gdImageAlpha(src,c);
294+ c = gdTrueColorAlpha(r, g, b, a);
295+ }
296+ gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
297+ }
298+ }
299+ }
300+
301+ return dst;
302+}
303+
304+/* Rotates an image by 270 degrees (counter clockwise) */
3d5c58ed 305+BGD_DECLARE(gdImagePtr) gdImageRotate270 ( gdImagePtr src )
1e268c02
PG
306+{
307+ int uY, uX;
308+ int c,r,g,b,a;
309+ gdImagePtr dst;
310+ typedef int (*FuncPtr)(gdImagePtr, int, int);
311+ FuncPtr f;
312+
313+ if (src->trueColor) {
314+ f = gdImageGetTrueColorPixel;
315+ } else {
316+ f = gdImageGetPixel;
317+ }
318+ dst = gdImageCreateTrueColor(src->sy, src->sx);
319+
320+ if (dst != NULL) {
321+ gdImagePaletteCopy (dst, src);
322+
323+ for (uY = 0; uY<src->sy; uY++) {
324+ for (uX = 0; uX<src->sx; uX++) {
325+ c = f (src, uX, uY);
326+ if (!src->trueColor) {
327+ r = gdImageRed(src,c);
328+ g = gdImageGreen(src,c);
329+ b = gdImageBlue(src,c);
330+ a = gdImageAlpha(src,c);
331+ c = gdTrueColorAlpha(r, g, b, a);
332+ }
333+ gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
334+ }
335+ }
336+ }
337+
338+ return dst;
339+}
340+
3d5c58ed 341+BGD_DECLARE(gdImagePtr) gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
1e268c02
PG
342+{
343+ typedef int (*FuncPtr)(gdImagePtr, int, int);
344+ gdImagePtr dst1,dst2,dst3;
345+ FuncPtr f;
346+ double dRadAngle, dSinE, dTan, dShear;
347+ double dOffset; /* Variable skew offset */
348+ int u, iShear, newx, newy;
349+ int clrBackR, clrBackG, clrBackB, clrBackA;
350+
351+ /* See GEMS I for the algorithm details */
352+ dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
353+ dSinE = sin (dRadAngle);
354+ dTan = tan (dRadAngle / 2.0);
355+
356+ newx = (int)(src->sx + src->sy * fabs(dTan));
357+ newy = src->sy;
358+
359+ /* 1st shear */
360+ if (src->trueColor) {
361+ f = gdImageGetTrueColorPixel;
362+ } else {
363+ f = gdImageGetPixel;
364+ }
365+ dst1 = gdImageCreateTrueColor(newx, newy);
366+
367+ /******* Perform 1st shear (horizontal) ******/
368+ if (dst1 == NULL) {
369+ return NULL;
370+ }
371+ dst1->alphaBlendingFlag = gdEffectReplace;
372+
373+ if (dAngle == 0.0) {
374+ /* Returns copy of src */
375+ gdImageCopy (dst1, src,0,0,0,0,src->sx,src->sy);
376+ return dst1;
377+ }
378+
379+ gdImagePaletteCopy (dst1, src);
380+
381+ dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */
382+ dSinE = sin (dRadAngle);
383+ dTan = tan (dRadAngle / 2.0);
384+
385+ for (u = 0; u < dst1->sy; u++) {
386+ if (dTan >= 0.0) {
387+ dShear = ((double)(u + 0.5)) * dTan;
388+ } else {
389+ dShear = ((double)(u - dst1->sy) + 0.5) * dTan;
390+ }
391+
392+ iShear = (int)floor(dShear);
393+ gdImageSkewX(dst1, src, u, iShear, (dShear - iShear), clrBack);
394+ }
395+
396+ /*
397+ The 1st shear may use the original clrBack as color index
398+ Convert it once here
399+ */
400+ if(!src->trueColor) {
401+ clrBackR = gdImageRed(src, clrBack);
402+ clrBackG = gdImageGreen(src, clrBack);
403+ clrBackB = gdImageBlue(src, clrBack);
404+ clrBackA = gdImageAlpha(src, clrBack);
405+ clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
406+ }
407+ /* 2nd shear */
408+ newx = dst1->sx;
409+
410+ if (dSinE > 0.0) {
411+ dOffset = (src->sx-1) * dSinE;
412+ } else {
413+ dOffset = -dSinE * (src->sx - newx);
414+ }
415+
416+ newy = (int) ((double) src->sx * fabs( dSinE ) + (double) src->sy * cos (dRadAngle))+1;
417+
418+ if (src->trueColor) {
419+ f = gdImageGetTrueColorPixel;
420+ } else {
421+ f = gdImageGetPixel;
422+ }
423+ dst2 = gdImageCreateTrueColor(newx, newy);
424+ if (dst2 == NULL) {
425+ gdImageDestroy(dst1);
426+ return NULL;
427+ }
428+ dst2->alphaBlendingFlag = gdEffectReplace;
429+
430+ for (u = 0; u < dst2->sx; u++, dOffset -= dSinE) {
431+ iShear = (int)floor (dOffset);
432+ gdImageSkewY(dst2, dst1, u, iShear, (dOffset - (double)iShear), clrBack);
433+ }
434+
435+ /* 3rd shear */
436+ gdImageDestroy(dst1);
437+
438+ newx = (int) ((double)src->sy * fabs (dSinE) + (double)src->sx * cos (dRadAngle)) + 1;
439+ newy = dst2->sy;
440+
441+ if (src->trueColor) {
442+ f = gdImageGetTrueColorPixel;
443+ } else {
444+ f = gdImageGetPixel;
445+ }
446+ dst3 = gdImageCreateTrueColor(newx, newy);
447+ if (dst3 == NULL) {
448+ gdImageDestroy(dst2);
449+ return NULL;
450+ }
451+ if (dSinE >= 0.0) {
452+ dOffset = (double)(src->sx - 1) * dSinE * -dTan;
453+ } else {
454+ dOffset = dTan * ((double)(src->sx - 1) * -dSinE + (double)(1 - newy));
455+ }
456+
457+ for (u = 0; u < dst3->sy; u++, dOffset += dTan) {
458+ int iShear = (int)floor(dOffset);
459+ gdImageSkewX(dst3, dst2, u, iShear, (dOffset - iShear), clrBack);
460+ }
461+
462+ gdImageDestroy(dst2);
463+
464+ return dst3;
465+}
466+
3d5c58ed 467+BGD_DECLARE(gdImagePtr) gdImageRotate (gdImagePtr src, double dAngle, int clrBack)
1e268c02
PG
468+{
469+ gdImagePtr pMidImg;
470+ gdImagePtr rotatedImg;
471+ int r,g,b,a;
472+ if (src == NULL) {
473+ return NULL;
474+ }
475+
476+ if (!gdImageTrueColor(src) && clrBack>=gdImageColorsTotal(src)) {
477+ return NULL;
478+ }
479+
480+ while (dAngle >= 360.0) {
481+ dAngle -= 360.0;
482+ }
483+
484+ while (dAngle < 0) {
485+ dAngle += 360.0;
486+ }
487+
488+ if (dAngle == 90.00) {
489+ return gdImageRotate90(src);
490+ }
491+ if (dAngle == 180.00) {
492+ return gdImageRotate180(src);
493+ }
494+ if(dAngle == 270.00) {
495+ return gdImageRotate270 ( src);
496+ }
497+
498+ if ((dAngle > 45.0) && (dAngle <= 135.0)) {
499+ pMidImg = gdImageRotate90 (src);
500+ dAngle -= 90.0;
501+ } else if ((dAngle > 135.0) && (dAngle <= 225.0)) {
502+ pMidImg = gdImageRotate180 (src);
503+ dAngle -= 180.0;
504+ } else if ((dAngle > 225.0) && (dAngle <= 315.0)) {
505+ pMidImg = gdImageRotate270 (src);
506+ dAngle -= 270.0;
507+ } else {
508+ return gdImageRotate45 (src, dAngle, clrBack);
509+ }
510+
511+ if (pMidImg == NULL) {
512+ return NULL;
513+ }
514+
515+ if(!src->trueColor) {
516+ r = gdImageRed(src, clrBack);
517+ g = gdImageGreen(src, clrBack);
518+ b = gdImageBlue(src, clrBack);
519+ a = gdImageAlpha(src, clrBack);
520+ clrBack = gdTrueColorAlpha(r,g,b,a);
521+ }
522+
523+ rotatedImg = gdImageRotate45 (pMidImg, dAngle, clrBack);
524+ gdImageDestroy(pMidImg);
525+
526+ return rotatedImg;
527+}
528+/* End Rotate function */
529+
530+
531+/* End of part taken from php... dirty hack... */
532+
533 /* When gd 1.x was first created, floating point was to be avoided.
534 These days it is often faster than table lookups or integer
535 arithmetic. The routine below is shamelessly, gloriously
536--- ./gd.h.org Thu Aug 12 13:22:18 2004
537+++ ./gd.h Thu Aug 12 13:44:33 2004
538@@ -106,6 +106,10 @@
539 #define gdTrueColorGetRed(c) (((c) & 0xFF0000) >> 16)
540 #define gdTrueColorGetGreen(c) (((c) & 0x00FF00) >> 8)
541 #define gdTrueColorGetBlue(c) ((c) & 0x0000FF)
542+#define gdEffectReplace 0
543+#define gdEffectAlphaBlend 1
544+#define gdEffectNormal 2
545+#define gdEffectOverlay 3
546
547 /* This function accepts truecolor pixel values only. The
548 source color is composited with the destination color
549@@ -617,6 +621,12 @@
550 int srcX, int srcY,
551 int srcWidth, int srcHeight, int angle);
552
553+gdImagePtr gdImageRotate90(gdImagePtr src);
554+gdImagePtr gdImageRotate180(gdImagePtr src);
555+gdImagePtr gdImageRotate270(gdImagePtr src);
556+gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack);
557+gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack);
558+
559 BGD_DECLARE(void) gdImageSetBrush (gdImagePtr im, gdImagePtr brush);
560 BGD_DECLARE(void) gdImageSetTile (gdImagePtr im, gdImagePtr tile);
561 BGD_DECLARE(void) gdImageSetAntiAliased (gdImagePtr im, int c);
This page took 0.084189 seconds and 4 git commands to generate.