Change to the linux kernel coding style
[wmaker-crm.git] / wrlib / rotate.c
dissimilarity index 81%
index f69c8c9..472c51a 100644 (file)
-/* rotate.c - image rotation
- *
- * Raster graphics library
- *
- * Copyright (c) 2000-2003 Alfredo K. Kojima
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public
- *  License along with this library; if not, write to the Free
- *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include "wraster.h"
-
-#include <math.h>
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-
-static RImage *rotateImage(RImage *image, float angle);
-
-
-RImage*
-RRotateImage(RImage *image, float angle)
-{
-    RImage *img;
-    int nwidth, nheight;
-    int x, y;
-    int bpp = image->format == RRGBAFormat ? 4 : 3;
-
-    angle = ((int)angle % 360) + (angle - (int)angle);
-
-    if (angle == 0.0) {
-        return RCloneImage(image);
-
-    } else if (angle == 90.0) {
-        nwidth = image->height;
-        nheight = image->width;
-
-        img = RCreateImage(nwidth, nheight, True);
-        if (!img) {
-            return NULL;
-        }
-
-        if (bpp == 3) {
-            unsigned char *optr, *nptr;
-            unsigned offs;
-
-
-            offs = nwidth * 4;
-
-            optr = image->data;
-            nptr = img->data;
-
-            for (x = 0; x < nwidth; x++) {
-                nptr = img->data + x*4;
-                for (y = nheight; y; y--) {
-                    nptr[0] = *optr++;
-                    nptr[1] = *optr++;
-                    nptr[2] = *optr++;
-                    nptr[3] = 255;
-
-                    nptr += offs;
-                }
-            }
-        } else {
-            unsigned *optr, *nptr;
-            unsigned *p;
-
-            optr = (unsigned*)image->data;
-            p = (unsigned*)img->data;
-            for (x = 0; x < nwidth; x++) {
-                nptr = p++;
-                for (y = nheight; y; y--) {
-                    *nptr = *optr++;
-                    nptr += nwidth;
-                }
-            }
-        }
-    } else if (angle == 180.0) {
-
-        nwidth = image->width;
-        nheight = image->height;
-        img = RCreateImage(nwidth, nheight, True);
-        if (!img) {
-            return NULL;
-        }
-
-        if (bpp == 3) {
-            unsigned char *optr, *nptr;
-
-            optr = image->data;
-            nptr = img->data + nwidth * nheight * 4 - 4;
-
-            for (y = 0; y < nheight; y++) {
-                for (x = 0; x < nwidth; x++) {
-                    nptr[0] = optr[0];
-                    nptr[1] = optr[1];
-                    nptr[2] = optr[2];
-                    nptr[3] = 255;
-
-                    optr += 3;
-                    nptr -= 4;
-                }
-            }
-        } else {
-            unsigned *optr, *nptr;
-
-            optr = (unsigned*)image->data;
-            nptr = (unsigned*)img->data + nwidth * nheight - 1;
-
-            for (y = nheight*nwidth-1; y >= 0; y--) {
-                *nptr = *optr;
-                optr++;
-                nptr--;
-            }
-        }
-    } else if (angle == 270.0) {
-        nwidth = image->height;
-        nheight = image->width;
-
-        img = RCreateImage(nwidth, nheight, True);
-        if (!img) {
-            return NULL;
-        }
-
-        if (bpp == 3) {
-            unsigned char *optr, *nptr;
-            unsigned offs;
-
-
-            offs = nwidth * 4;
-
-            optr = image->data;
-            nptr = img->data;
-
-            for (x = 0; x < nwidth; x++) {
-                nptr = img->data + x*4;
-                for (y = nheight; y; y--) {
-                    nptr[0] = *optr++;
-                    nptr[1] = *optr++;
-                    nptr[2] = *optr++;
-                    nptr[3] = 255;
-
-                    nptr += offs;
-                }
-            }
-        } else {
-            unsigned *optr, *nptr;
-            unsigned *p;
-
-            optr = (unsigned*)image->data;
-            p = (unsigned*)img->data + nwidth*nheight;
-            for (x = 0; x < nwidth; x++) {
-                nptr = p--;
-                for (y = nheight; y; y--) {
-                    *nptr = *optr++;
-                    nptr -= nwidth;
-                }
-            }
-        }
-    } else {
-        img = rotateImage(image, angle);
-    }
-
-    return img;
-}
-
-
-
-
-/*
- * Image rotation through Bresenham's line algorithm:
- *
- * If a square must be rotate by angle a, like in:
- *  _______
- * |    B  |
- * |   /4\ |
- * |  /3 8\|
- * | /2 7 /|
- * |A1 6 / |      A_______B
- * | \5 / a| <--- |1 2 3 4|
- * |__C/_)_|      |5 6 7 8|
- *                C-------
- *
- * for each point P1 in the line from C to A
- *     for each point P2 in the perpendicular line starting at P1
- *             get pixel from the source and plot at P2
- *             increment pixel location from source
- *
- */
-
-
-static void
-copyLine(int x1, int y1, int x2, int y2, int nwidth, int format,
-         unsigned char *dst, unsigned char **src)
-{
-    unsigned char *s = *src;
-    int dx, dy;
-    int xi, yi;
-    int offset;
-    int dpr, dpru, p;
-
-    dx = abs(x2 - x1);
-    dy = abs(y2 - y1);
-
-    if (x1 > x2) xi = -1; else xi = 1;
-    if (y1 > y2) yi = -1; else yi = 1;
-
-    if (dx >= dy) {
-
-        dpr = dy << 1;
-        dpru = dpr - (dx << 1);
-        p = dpr - dx;
-
-        while (dx-- >= 0) {
-            /* fetch and draw the pixel */
-            offset = (x1 + y1 * nwidth) << 2;
-            dst[offset++] = *s++;
-            dst[offset++] = *s++;
-            dst[offset++] = *s++;
-            if (format == RRGBAFormat)
-                dst[offset++] = *s++;
-            else
-                dst[offset++] = 255;
-
-            /* calc next step */
-            if (p > 0) {
-                x1 += xi;
-                y1 += yi;
-                p += dpru;
-            } else {
-                x1 += xi;
-                p += dpr;
-            }
-        }
-    } else {
-
-        dpr = dx << 1;
-        dpru = dpr - (dy << 1);
-        p = dpr - dy;
-
-        while (dy-- >= 0) {
-            /* fetch and draw the pixel */
-            offset = (x1 + y1 * nwidth) << 2;
-            dst[offset++] = *s++;
-            dst[offset++] = *s++;
-            dst[offset++] = *s++;
-            if (format == RRGBAFormat)
-                dst[offset++] = *s++;
-            else
-                dst[offset++] = 255;
-
-            /* calc next step */
-            if (p > 0) {
-                x1 += xi;
-                y1 += yi;
-                p += dpru;
-            } else {
-                y1 += yi;
-                p += dpr;
-            }
-        }
-    }
-
-
-    *src = s;
-}
-
-
-static RImage*
-rotateImage(RImage *image, float angle)
-{
-    RImage *img;
-    int nwidth, nheight;
-    int x1, y1;
-    int x2, y2;
-    int dx, dy;
-    int xi, yi;
-    int xx, yy;
-    unsigned char *src, *dst;
-    int dpr, dpru, p;
-
-    /* only 180o for now */
-    if (angle > 180.0)
-        angle -= 180.0;
-
-
-    angle = (angle * PI) / 180.0;
-
-    nwidth = ceil(abs(cos(angle) * image->width))
-        + ceil(abs(cos(PI/2 - angle) * image->width));
-
-    nheight = ceil(abs(sin(angle) * image->height))
-        + ceil(abs(cos(PI/2 - angle) * image->height));
-
-    img = RCreateImage(nwidth, nheight, True);
-    if (!img)
-        return NULL;
-
-    src = image->data;
-    dst = img->data;
-
-    x1 = floor(abs(cos(PI/2 - angle)*image->width));
-    y1 = 0;
-
-    x2 = 0;
-    y2 = floor(abs(sin(PI/2 - angle)*image->width));
-
-    xx = floor(abs(cos(angle)*image->height)) - 1;
-    yy = nheight - 1;
-
-    printf("%ix%i, %i %i     %i %i %i\n",
-           nwidth, nheight, x1, y1, x2, y2, (int)((angle*180.0)/PI));
-
-    dx = abs(x2 - x1);
-    dy = abs(y2 - y1);
-
-    if (x1 > x2) xi = -1; else xi = 1;
-    if (y1 > y2) yi = -1; else yi = 1;
-
-    if (dx >= dy) {
-        dpr = dy << 1;
-        dpru = dpr - (dx << 1);
-        p = dpr - dx;
-
-        while (dx-- >= 0) {
-
-            copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
-
-            /* calc next step */
-
-            if (p > 0) {
-                x1 += xi;
-                y1 += yi;
-                xx += xi;
-                yy += yi;
-                p += dpru;
-            } else {
-                x1 += xi;
-                xx += xi;
-                p += dpr;
-            }
-        }
-    } else {
-        puts("NOT IMPLEMTENED");
-        return img;
-        dpr = dx << 1;
-        dpru = dpr - (dy << 1);
-        p = dpr - dy;
-
-        while (dy-- >= 0) {
-            xx = abs(x1*sin(angle*PI/180.0));
-            yy = abs(y1*cos(angle*PI/180.0));
-
-            copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
-
-            /* calc next step*/
-            if (p > 0) {
-                x1 += xi;
-                y1 += yi;
-                p += dpru;
-            } else {
-                y1 += yi;
-                p += dpr;
-            }
-        }
-    }
-
-    return img;
-}
-
+/* rotate.c - image rotation
+ *
+ * Raster graphics library
+ *
+ * Copyright (c) 2000-2003 Alfredo K. Kojima
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include "wraster.h"
+
+#include <math.h>
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+static RImage *rotateImage(RImage * image, float angle);
+
+RImage *RRotateImage(RImage * image, float angle)
+{
+       RImage *img;
+       int nwidth, nheight;
+       int x, y;
+       int bpp = image->format == RRGBAFormat ? 4 : 3;
+
+       angle = ((int)angle % 360) + (angle - (int)angle);
+
+       if (angle == 0.0) {
+               return RCloneImage(image);
+
+       } else if (angle == 90.0) {
+               nwidth = image->height;
+               nheight = image->width;
+
+               img = RCreateImage(nwidth, nheight, True);
+               if (!img) {
+                       return NULL;
+               }
+
+               if (bpp == 3) {
+                       unsigned char *optr, *nptr;
+                       unsigned offs;
+
+                       offs = nwidth * 4;
+
+                       optr = image->data;
+                       nptr = img->data;
+
+                       for (x = 0; x < nwidth; x++) {
+                               nptr = img->data + x * 4;
+                               for (y = nheight; y; y--) {
+                                       nptr[0] = *optr++;
+                                       nptr[1] = *optr++;
+                                       nptr[2] = *optr++;
+                                       nptr[3] = 255;
+
+                                       nptr += offs;
+                               }
+                       }
+               } else {
+                       unsigned *optr, *nptr;
+                       unsigned *p;
+
+                       optr = (unsigned *)image->data;
+                       p = (unsigned *)img->data;
+                       for (x = 0; x < nwidth; x++) {
+                               nptr = p++;
+                               for (y = nheight; y; y--) {
+                                       *nptr = *optr++;
+                                       nptr += nwidth;
+                               }
+                       }
+               }
+       } else if (angle == 180.0) {
+
+               nwidth = image->width;
+               nheight = image->height;
+               img = RCreateImage(nwidth, nheight, True);
+               if (!img) {
+                       return NULL;
+               }
+
+               if (bpp == 3) {
+                       unsigned char *optr, *nptr;
+
+                       optr = image->data;
+                       nptr = img->data + nwidth * nheight * 4 - 4;
+
+                       for (y = 0; y < nheight; y++) {
+                               for (x = 0; x < nwidth; x++) {
+                                       nptr[0] = optr[0];
+                                       nptr[1] = optr[1];
+                                       nptr[2] = optr[2];
+                                       nptr[3] = 255;
+
+                                       optr += 3;
+                                       nptr -= 4;
+                               }
+                       }
+               } else {
+                       unsigned *optr, *nptr;
+
+                       optr = (unsigned *)image->data;
+                       nptr = (unsigned *)img->data + nwidth * nheight - 1;
+
+                       for (y = nheight * nwidth - 1; y >= 0; y--) {
+                               *nptr = *optr;
+                               optr++;
+                               nptr--;
+                       }
+               }
+       } else if (angle == 270.0) {
+               nwidth = image->height;
+               nheight = image->width;
+
+               img = RCreateImage(nwidth, nheight, True);
+               if (!img) {
+                       return NULL;
+               }
+
+               if (bpp == 3) {
+                       unsigned char *optr, *nptr;
+                       unsigned offs;
+
+                       offs = nwidth * 4;
+
+                       optr = image->data;
+                       nptr = img->data;
+
+                       for (x = 0; x < nwidth; x++) {
+                               nptr = img->data + x * 4;
+                               for (y = nheight; y; y--) {
+                                       nptr[0] = *optr++;
+                                       nptr[1] = *optr++;
+                                       nptr[2] = *optr++;
+                                       nptr[3] = 255;
+
+                                       nptr += offs;
+                               }
+                       }
+               } else {
+                       unsigned *optr, *nptr;
+                       unsigned *p;
+
+                       optr = (unsigned *)image->data;
+                       p = (unsigned *)img->data + nwidth * nheight;
+                       for (x = 0; x < nwidth; x++) {
+                               nptr = p--;
+                               for (y = nheight; y; y--) {
+                                       *nptr = *optr++;
+                                       nptr -= nwidth;
+                               }
+                       }
+               }
+       } else {
+               img = rotateImage(image, angle);
+       }
+
+       return img;
+}
+
+/*
+ * Image rotation through Bresenham's line algorithm:
+ *
+ * If a square must be rotate by angle a, like in:
+ *  _______
+ * |    B  |
+ * |   /4\ |
+ * |  /3 8\|
+ * | /2 7 /|
+ * |A1 6 / |      A_______B
+ * | \5 / a| <--- |1 2 3 4|
+ * |__C/_)_|      |5 6 7 8|
+ *                C-------
+ *
+ * for each point P1 in the line from C to A
+ *     for each point P2 in the perpendicular line starting at P1
+ *             get pixel from the source and plot at P2
+ *             increment pixel location from source
+ *
+ */
+
+static void
+copyLine(int x1, int y1, int x2, int y2, int nwidth, int format, unsigned char *dst, unsigned char **src)
+{
+       unsigned char *s = *src;
+       int dx, dy;
+       int xi, yi;
+       int offset;
+       int dpr, dpru, p;
+
+       dx = abs(x2 - x1);
+       dy = abs(y2 - y1);
+
+       if (x1 > x2)
+               xi = -1;
+       else
+               xi = 1;
+       if (y1 > y2)
+               yi = -1;
+       else
+               yi = 1;
+
+       if (dx >= dy) {
+
+               dpr = dy << 1;
+               dpru = dpr - (dx << 1);
+               p = dpr - dx;
+
+               while (dx-- >= 0) {
+                       /* fetch and draw the pixel */
+                       offset = (x1 + y1 * nwidth) << 2;
+                       dst[offset++] = *s++;
+                       dst[offset++] = *s++;
+                       dst[offset++] = *s++;
+                       if (format == RRGBAFormat)
+                               dst[offset++] = *s++;
+                       else
+                               dst[offset++] = 255;
+
+                       /* calc next step */
+                       if (p > 0) {
+                               x1 += xi;
+                               y1 += yi;
+                               p += dpru;
+                       } else {
+                               x1 += xi;
+                               p += dpr;
+                       }
+               }
+       } else {
+
+               dpr = dx << 1;
+               dpru = dpr - (dy << 1);
+               p = dpr - dy;
+
+               while (dy-- >= 0) {
+                       /* fetch and draw the pixel */
+                       offset = (x1 + y1 * nwidth) << 2;
+                       dst[offset++] = *s++;
+                       dst[offset++] = *s++;
+                       dst[offset++] = *s++;
+                       if (format == RRGBAFormat)
+                               dst[offset++] = *s++;
+                       else
+                               dst[offset++] = 255;
+
+                       /* calc next step */
+                       if (p > 0) {
+                               x1 += xi;
+                               y1 += yi;
+                               p += dpru;
+                       } else {
+                               y1 += yi;
+                               p += dpr;
+                       }
+               }
+       }
+
+       *src = s;
+}
+
+static RImage *rotateImage(RImage * image, float angle)
+{
+       RImage *img;
+       int nwidth, nheight;
+       int x1, y1;
+       int x2, y2;
+       int dx, dy;
+       int xi, yi;
+       int xx, yy;
+       unsigned char *src, *dst;
+       int dpr, dpru, p;
+
+       /* only 180o for now */
+       if (angle > 180.0)
+               angle -= 180.0;
+
+       angle = (angle * PI) / 180.0;
+
+       nwidth = ceil(abs(cos(angle) * image->width))
+           + ceil(abs(cos(PI / 2 - angle) * image->width));
+
+       nheight = ceil(abs(sin(angle) * image->height))
+           + ceil(abs(cos(PI / 2 - angle) * image->height));
+
+       img = RCreateImage(nwidth, nheight, True);
+       if (!img)
+               return NULL;
+
+       src = image->data;
+       dst = img->data;
+
+       x1 = floor(abs(cos(PI / 2 - angle) * image->width));
+       y1 = 0;
+
+       x2 = 0;
+       y2 = floor(abs(sin(PI / 2 - angle) * image->width));
+
+       xx = floor(abs(cos(angle) * image->height)) - 1;
+       yy = nheight - 1;
+
+       printf("%ix%i, %i %i     %i %i %i\n", nwidth, nheight, x1, y1, x2, y2, (int)((angle * 180.0) / PI));
+
+       dx = abs(x2 - x1);
+       dy = abs(y2 - y1);
+
+       if (x1 > x2)
+               xi = -1;
+       else
+               xi = 1;
+       if (y1 > y2)
+               yi = -1;
+       else
+               yi = 1;
+
+       if (dx >= dy) {
+               dpr = dy << 1;
+               dpru = dpr - (dx << 1);
+               p = dpr - dx;
+
+               while (dx-- >= 0) {
+
+                       copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
+
+                       /* calc next step */
+
+                       if (p > 0) {
+                               x1 += xi;
+                               y1 += yi;
+                               xx += xi;
+                               yy += yi;
+                               p += dpru;
+                       } else {
+                               x1 += xi;
+                               xx += xi;
+                               p += dpr;
+                       }
+               }
+       } else {
+               puts("NOT IMPLEMTENED");
+               return img;
+               dpr = dx << 1;
+               dpru = dpr - (dy << 1);
+               p = dpr - dy;
+
+               while (dy-- >= 0) {
+                       xx = abs(x1 * sin(angle * PI / 180.0));
+                       yy = abs(y1 * cos(angle * PI / 180.0));
+
+                       copyLine(x1, y1, xx, yy, nwidth, image->format, dst, &src);
+
+                       /* calc next step */
+                       if (p > 0) {
+                               x1 += xi;
+                               y1 += yi;
+                               p += dpru;
+                       } else {
+                               y1 += yi;
+                               p += dpr;
+                       }
+               }
+       }
+
+       return img;
+}