]> git.pld-linux.org Git - packages/gd.git/blob - gd-rotate_from_php.patch
- added gd(imagerotate) Provides, release 9
[packages/gd.git] / gd-rotate_from_php.patch
1 --- ./gd.c.org  Thu Jul  1 23:30:30 2004
2 +++ ./gd.c      Thu Aug 12 14:42:03 2004
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) */
231 +BGD_DECLARE(gdImagePtr) gdImageRotate90 (gdImagePtr src)
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) */
268 +BGD_DECLARE(gdImagePtr) gdImageRotate180 (gdImagePtr src)
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) */
305 +BGD_DECLARE(gdImagePtr) gdImageRotate270 ( gdImagePtr src )
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 +
341 +BGD_DECLARE(gdImagePtr) gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack)
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 +
467 +BGD_DECLARE(gdImagePtr) gdImageRotate (gdImagePtr src, double dAngle, int clrBack)
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.077301 seconds and 3 git commands to generate.