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