1 #include "gd.h"
2
3 #include "gd_intern.h"
4 #include <math.h>
5
6 /*
7 * Rotate function Added on 2003/12
8 * by Pierre-Alain Joye (pierre@php.net)
9 **/
10 /* Begin rotate function */
11 #ifdef ROTATE_PI
12 #undef ROTATE_PI
13 #endif /* ROTATE_PI */
14
15 #define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180
gdImageSkewX(gdImagePtr dst,gdImagePtr src,int uRow,int iOffset,double dWeight,int clrBack,int ignoretransparent)16 void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent)
17 {
18 typedef int (*FuncPtr)(gdImagePtr, int, int);
19 int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
20 FuncPtr f;
21
22 int pxlOldLeft, pxlLeft=0, pxlSrc;
23
24 /* Keep clrBack as color index if required */
25 if (src->trueColor) {
26 pxlOldLeft = clrBack;
27 f = gdImageGetTrueColorPixel;
28 } else {
29 pxlOldLeft = clrBack;
30 clrBackR = gdImageRed(src, clrBack);
31 clrBackG = gdImageGreen(src, clrBack);
32 clrBackB = gdImageBlue(src, clrBack);
33 clrBackA = gdImageAlpha(src, clrBack);
34 clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
35 f = gdImageGetPixel;
36 }
37
38 for (i = 0; i < iOffset; i++) {
39 gdImageSetPixel (dst, i, uRow, clrBack);
40 }
41
42 if (i < dst->sx) {
43 gdImageSetPixel (dst, i, uRow, clrBack);
44 }
45
46 for (i = 0; i < src->sx; i++) {
47 pxlSrc = f (src,i,uRow);
48
49 r = (int)(gdImageRed(src,pxlSrc) * dWeight);
50 g = (int)(gdImageGreen(src,pxlSrc) * dWeight);
51 b = (int)(gdImageBlue(src,pxlSrc) * dWeight);
52 a = (int)(gdImageAlpha(src,pxlSrc) * dWeight);
53
54 pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
55
56 if (pxlLeft == -1) {
57 pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
58 }
59
60 r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
61 g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
62 b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
63 a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
64
65 if (r>255) {
66 r = 255;
67 }
68
69 if (g>255) {
70 g = 255;
71 }
72
73 if (b>255) {
74 b = 255;
75 }
76
77 if (a>127) {
78 a = 127;
79 }
80
81 if (ignoretransparent && pxlSrc == dst->transparent) {
82 pxlSrc = dst->transparent;
83 } else {
84 pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
85
86 if (pxlSrc == -1) {
87 pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
88 }
89 }
90
91 if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
92 gdImageSetPixel (dst, i+iOffset, uRow, pxlSrc);
93 }
94
95 pxlOldLeft = pxlLeft;
96 }
97
98 i += iOffset;
99
100 if (i < dst->sx) {
101 gdImageSetPixel (dst, i, uRow, pxlLeft);
102 }
103
104 gdImageSetPixel (dst, iOffset, uRow, clrBack);
105
106 i--;
107
108 while (++i < dst->sx) {
109 gdImageSetPixel (dst, i, uRow, clrBack);
110 }
111 }
112
gdImageSkewY(gdImagePtr dst,gdImagePtr src,int uCol,int iOffset,double dWeight,int clrBack,int ignoretransparent)113 void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent)
114 {
115 typedef int (*FuncPtr)(gdImagePtr, int, int);
116 int i, iYPos=0, r, g, b, a;
117 FuncPtr f;
118 int pxlOldLeft, pxlLeft=0, pxlSrc;
119
120 if (src->trueColor) {
121 f = gdImageGetTrueColorPixel;
122 } else {
123 f = gdImageGetPixel;
124 }
125
126 for (i = 0; i<=iOffset; i++) {
127 gdImageSetPixel (dst, uCol, i, clrBack);
128 }
129 r = (int)((double)gdImageRed(src,clrBack) * dWeight);
130 g = (int)((double)gdImageGreen(src,clrBack) * dWeight);
131 b = (int)((double)gdImageBlue(src,clrBack) * dWeight);
132 a = (int)((double)gdImageAlpha(src,clrBack) * dWeight);
133
134 pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a);
135
136 for (i = 0; i < src->sy; i++) {
137 pxlSrc = f (src, uCol, i);
138 iYPos = i + iOffset;
139
140 r = (int)((double)gdImageRed(src,pxlSrc) * dWeight);
141 g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight);
142 b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight);
143 a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight);
144
145 pxlLeft = gdImageColorAllocateAlpha(src, r, g, b, a);
146
147 if (pxlLeft == -1) {
148 pxlLeft = gdImageColorClosestAlpha(src, r, g, b, a);
149 }
150
151 r = gdImageRed(src,pxlSrc) - (gdImageRed(src,pxlLeft) - gdImageRed(src,pxlOldLeft));
152 g = gdImageGreen(src,pxlSrc) - (gdImageGreen(src,pxlLeft) - gdImageGreen(src,pxlOldLeft));
153 b = gdImageBlue(src,pxlSrc) - (gdImageBlue(src,pxlLeft) - gdImageBlue(src,pxlOldLeft));
154 a = gdImageAlpha(src,pxlSrc) - (gdImageAlpha(src,pxlLeft) - gdImageAlpha(src,pxlOldLeft));
155
156 if (r>255) {
157 r = 255;
158 }
159
160 if (g>255) {
161 g = 255;
162 }
163
164 if (b>255) {
165 b = 255;
166 }
167
168 if (a>127) {
169 a = 127;
170 }
171
172 if (ignoretransparent && pxlSrc == dst->transparent) {
173 pxlSrc = dst->transparent;
174 } else {
175 pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
176
177 if (pxlSrc == -1) {
178 pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
179 }
180 }
181
182 if ((iYPos >= 0) && (iYPos < dst->sy)) {
183 gdImageSetPixel (dst, uCol, iYPos, pxlSrc);
184 }
185
186 pxlOldLeft = pxlLeft;
187 }
188
189 i = iYPos;
190 if (i < dst->sy) {
191 gdImageSetPixel (dst, uCol, i, pxlLeft);
192 }
193
194 i--;
195 while (++i < dst->sy) {
196 gdImageSetPixel (dst, uCol, i, clrBack);
197 }
198 }
199
200 /* Rotates an image by 90 degrees (counter clockwise) */
gdImageRotate90(gdImagePtr src,int ignoretransparent)201 gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
202 {
203 int uY, uX;
204 int c,r,g,b,a;
205 gdImagePtr dst;
206 typedef int (*FuncPtr)(gdImagePtr, int, int);
207 FuncPtr f;
208
209 if (src->trueColor) {
210 f = gdImageGetTrueColorPixel;
211 } else {
212 f = gdImageGetPixel;
213 }
214 dst = gdImageCreateTrueColor(src->sy, src->sx);
215
216 if (dst != NULL) {
217 int old_blendmode = dst->alphaBlendingFlag;
218 dst->alphaBlendingFlag = 0;
219
220 dst->transparent = src->transparent;
221
222 gdImagePaletteCopy (dst, src);
223
224 for (uY = 0; uY<src->sy; uY++) {
225 for (uX = 0; uX<src->sx; uX++) {
226 c = f (src, uX, uY);
227 if (!src->trueColor) {
228 r = gdImageRed(src,c);
229 g = gdImageGreen(src,c);
230 b = gdImageBlue(src,c);
231 a = gdImageAlpha(src,c);
232 c = gdTrueColorAlpha(r, g, b, a);
233 }
234 if (ignoretransparent && c == dst->transparent) {
235 gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
236 } else {
237 gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
238 }
239 }
240 }
241 dst->alphaBlendingFlag = old_blendmode;
242 }
243
244 return dst;
245 }
246
247 /* Rotates an image by 180 degrees (counter clockwise) */
gdImageRotate180(gdImagePtr src,int ignoretransparent)248 gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
249 {
250 int uY, uX;
251 int c,r,g,b,a;
252 gdImagePtr dst;
253 typedef int (*FuncPtr)(gdImagePtr, int, int);
254 FuncPtr f;
255
256 if (src->trueColor) {
257 f = gdImageGetTrueColorPixel;
258 } else {
259 f = gdImageGetPixel;
260 }
261 dst = gdImageCreateTrueColor(src->sx, src->sy);
262
263 if (dst != NULL) {
264 int old_blendmode = dst->alphaBlendingFlag;
265 dst->alphaBlendingFlag = 0;
266
267 dst->transparent = src->transparent;
268
269 gdImagePaletteCopy (dst, src);
270
271 for (uY = 0; uY<src->sy; uY++) {
272 for (uX = 0; uX<src->sx; uX++) {
273 c = f (src, uX, uY);
274 if (!src->trueColor) {
275 r = gdImageRed(src,c);
276 g = gdImageGreen(src,c);
277 b = gdImageBlue(src,c);
278 a = gdImageAlpha(src,c);
279 c = gdTrueColorAlpha(r, g, b, a);
280 }
281
282 if (ignoretransparent && c == dst->transparent) {
283 gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent);
284 } else {
285 gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
286 }
287 }
288 }
289 dst->alphaBlendingFlag = old_blendmode;
290 }
291
292 return dst;
293 }
294
295 /* Rotates an image by 270 degrees (counter clockwise) */
gdImageRotate270(gdImagePtr src,int ignoretransparent)296 gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
297 {
298 int uY, uX;
299 int c,r,g,b,a;
300 gdImagePtr dst;
301 typedef int (*FuncPtr)(gdImagePtr, int, int);
302 FuncPtr f;
303
304 if (src->trueColor) {
305 f = gdImageGetTrueColorPixel;
306 } else {
307 f = gdImageGetPixel;
308 }
309 dst = gdImageCreateTrueColor (src->sy, src->sx);
310
311 if (dst != NULL) {
312 int old_blendmode = dst->alphaBlendingFlag;
313 dst->alphaBlendingFlag = 0;
314
315 dst->transparent = src->transparent;
316
317 gdImagePaletteCopy (dst, src);
318
319 for (uY = 0; uY<src->sy; uY++) {
320 for (uX = 0; uX<src->sx; uX++) {
321 c = f (src, uX, uY);
322 if (!src->trueColor) {
323 r = gdImageRed(src,c);
324 g = gdImageGreen(src,c);
325 b = gdImageBlue(src,c);
326 a = gdImageAlpha(src,c);
327 c = gdTrueColorAlpha(r, g, b, a);
328 }
329
330 if (ignoretransparent && c == dst->transparent) {
331 gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent);
332 } else {
333 gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
334 }
335 }
336 }
337 dst->alphaBlendingFlag = old_blendmode;
338 }
339
340 return dst;
341 }
342