gd_rotate.c 8.0 KB

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