1 /* rotate.c - image rotation
3 * Raster graphics library
5 * Copyright (c) 2000-2003 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 #define PI 3.14159265358979323846
36 static RImage *rotateImage(RImage * image, float angle);
38 RImage *RRotateImage(RImage * image, float angle)
43 int bpp = image->format == RRGBAFormat ? 4 : 3;
45 angle = ((int)angle % 360) + (angle - (int)angle);
48 return RCloneImage(image);
50 } else if (angle == 90.0) {
51 nwidth = image->height;
52 nheight = image->width;
54 img = RCreateImage(nwidth, nheight, True);
60 unsigned char *optr, *nptr;
68 for (x = 0; x < nwidth; x++) {
69 nptr = img->data + x * 4;
70 for (y = nheight; y; y--) {
80 unsigned *optr, *nptr;
83 optr = (unsigned *)image->data;
84 p = (unsigned *)img->data;
85 for (x = 0; x < nwidth; x++) {
87 for (y = nheight; y; y--) {
93 } else if (angle == 180.0) {
95 nwidth = image->width;
96 nheight = image->height;
97 img = RCreateImage(nwidth, nheight, True);
103 unsigned char *optr, *nptr;
106 nptr = img->data + nwidth * nheight * 4 - 4;
108 for (y = 0; y < nheight; y++) {
109 for (x = 0; x < nwidth; x++) {
120 unsigned *optr, *nptr;
122 optr = (unsigned *)image->data;
123 nptr = (unsigned *)img->data + nwidth * nheight - 1;
125 for (y = nheight * nwidth - 1; y >= 0; y--) {
131 } else if (angle == 270.0) {
132 nwidth = image->height;
133 nheight = image->width;
135 img = RCreateImage(nwidth, nheight, True);
141 unsigned char *optr, *nptr;
149 for (x = 0; x < nwidth; x++) {
150 nptr = img->data + x * 4;
151 for (y = nheight; y; y--) {
161 unsigned *optr, *nptr;
164 optr = (unsigned *)image->data;
165 p = (unsigned *)img->data + nwidth * nheight;
166 for (x = 0; x < nwidth; x++) {
168 for (y = nheight; y; y--) {
175 img = rotateImage(image, angle);
182 * Image rotation through Bresenham's line algorithm:
184 * If a square must be rotate by angle a, like in:
190 * |A1 6 / | A_______B
191 * | \5 / a| <--- |1 2 3 4|
192 * |__C/_)_| |5 6 7 8|
195 * for each point P1 in the line from C to A
196 * for each point P2 in the perpendicular line starting at P1
197 * get pixel from the source and plot at P2
198 * increment pixel location from source
203 copyLine(int x1, int y1, int x2, int y2, int nwidth, int format, unsigned char *dst, unsigned char **src)
205 unsigned char *s = *src;
226 dpru = dpr - (dx << 1);
230 /* fetch and draw the pixel */
231 offset = (x1 + y1 * nwidth) << 2;
232 dst[offset++] = *s++;
233 dst[offset++] = *s++;
234 dst[offset++] = *s++;
235 if (format == RRGBAFormat)
236 dst[offset++] = *s++;
253 dpru = dpr - (dy << 1);
257 /* fetch and draw the pixel */
258 offset = (x1 + y1 * nwidth) << 2;
259 dst[offset++] = *s++;
260 dst[offset++] = *s++;
261 dst[offset++] = *s++;
262 if (format == RRGBAFormat)
263 dst[offset++] = *s++;
282 static RImage *rotateImage(RImage * image, float angle)
291 unsigned char *src, *dst;
294 /* only 180o for now */
298 angle = (angle * PI) / 180.0;
300 nwidth = ceil(abs(cos(angle) * image->width))
301 + ceil(abs(cos(PI / 2 - angle) * image->width));
303 nheight = ceil(abs(sin(angle) * image->height))
304 + ceil(abs(cos(PI / 2 - angle) * image->height));
306 img = RCreateImage(nwidth, nheight, True);
313 x1 = floor(abs(cos(PI / 2 - angle) * image->width));
317 y2 = floor(abs(sin(PI / 2 - angle) * image->width));
319 xx = floor(abs(cos(angle) * image->height)) - 1;
322 printf("%ix%i, %i %i %i %i %i\n", nwidth, nheight, x1, y1, x2, y2, (int)((angle * 180.0) / PI));
338 dpru = dpr - (dx << 1);
343 copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
360 puts("NOT IMPLEMTENED");
363 dpru = dpr - (dy << 1);
367 xx = abs(x1 * sin(angle * PI / 180.0));
368 yy = abs(y1 * cos(angle * PI / 180.0));
370 copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);