From: Christophe CURIS <[email protected]>

The function RRotateImage contains code to handle efficiently the 4 simple
angles 0, 90, 180 and 270 degrees, which makes it a long function.

This patch separate the code for the different cases into dedicated
functions so the main function's code ends up being simple (aka: easier to
understand/review/maintain).

As a side effect, the function for the 180 degree function is not static
because it can be reused to flip an image both horizontally and vertically.

Signed-off-by: Christophe CURIS <[email protected]>
---
 wrlib/Makefile.am |   1 +
 wrlib/rotate.c    | 243 +++++++++++++++++++++++++++++++-----------------------
 wrlib/rotate.h    |  30 +++++++
 3 files changed, 169 insertions(+), 105 deletions(-)
 create mode 100644 wrlib/rotate.h

diff --git a/wrlib/Makefile.am b/wrlib/Makefile.am
index e9f357c..a9e6e83 100644
--- a/wrlib/Makefile.am
+++ b/wrlib/Makefile.am
@@ -35,6 +35,7 @@ libwraster_la_SOURCES =       \
        scale.c         \
        scale.h         \
        rotate.c        \
+       rotate.h        \
        flip.c          \
        convolve.c      \
        save_xpm.c      \
diff --git a/wrlib/rotate.c b/wrlib/rotate.c
index f2f92b9..84b34b7 100644
--- a/wrlib/rotate.c
+++ b/wrlib/rotate.c
@@ -25,8 +25,11 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+
 #include <X11/Xlib.h>
+
 #include "wraster.h"
+#include "rotate.h"
 
 #include <math.h>
 
@@ -34,15 +37,13 @@
 #define PI 3.14159265358979323846
 #endif
 
-static RImage *rotateImage(RImage *image, float angle);
+static RImage *rotate_image_90(RImage *source);
+static RImage *rotate_image_270(RImage *source);
+static RImage *rotate_image_any(RImage *source, float angle);
+
 
 RImage *RRotateImage(RImage *image, float angle)
 {
-       RImage *img;
-       int nwidth, nheight;
-       int x, y;
-       int bpp = image->format == RRGBAFormat ? 4 : 3;
-
        /*
         * Angle steps below this value would represent a rotation
         * of less than 1 pixel for a 4k wide image, so not worth
@@ -62,133 +63,165 @@ RImage *RRotateImage(RImage *image, float angle)
 
        } else if ((angle > 90.0 - min_usable_angle) &&
                                  (angle < 90.0 + min_usable_angle)) {
-               nwidth = image->height;
-               nheight = image->width;
+               return rotate_image_90(image);
 
-               img = RCreateImage(nwidth, nheight, True);
-               if (!img)
-                       return NULL;
+       } else if ((angle > 180.0 - min_usable_angle) &&
+                                 (angle < 180.0 + min_usable_angle)) {
+               return wraster_rotate_image_180(image);
 
-               if (bpp == 3) {
-                       unsigned char *optr, *nptr;
+       } else if ((angle > 270.0 - min_usable_angle) &&
+                                 (angle < 270.0 + min_usable_angle)) {
+               return rotate_image_270(image);
 
-                       optr = image->data;
-                       nptr = img->data;
+       } else {
+               return rotate_image_any(image, angle);
+       }
+}
 
-                       for (x = nwidth; x; x--) {
-                               nptr = img->data + 4 * (x - 1);
-                               for (y = nheight; y; y--) {
-                                       nptr[0] = *optr++;
-                                       nptr[1] = *optr++;
-                                       nptr[2] = *optr++;
-                                       nptr[3] = 255;
+static RImage *rotate_image_90(RImage *source)
+{
+       RImage *target;
+       int nwidth, nheight;
+       int x, y;
+
+       nwidth = source->height;
+       nheight = source->width;
+
+       target = RCreateImage(nwidth, nheight, (source->format != RRGBFormat));
+       if (!target)
+               return NULL;
+
+       if (source->format == RRGBFormat) {
+               unsigned char *optr, *nptr;
 
-                                       nptr += 4 * nwidth;
-                               }
+               optr = source->data;
+               for (x = nwidth; x; x--) {
+                       nptr = target->data + 3 * (x - 1);
+                       for (y = nheight; y; y--) {
+                               nptr[0] = *optr++;
+                               nptr[1] = *optr++;
+                               nptr[2] = *optr++;
+
+                               nptr += 3 * nwidth;
                        }
-               } else {
-                       unsigned char *optr, *nptr;
-
-                       optr = image->data;
-                       nptr = img->data;
-
-                       for (x = nwidth; x; x--) {
-                               nptr = img->data + 4 * (x - 1);
-                               for (y = nheight; y; y--) {
-                                       nptr[0] = *optr++;
-                                       nptr[1] = *optr++;
-                                       nptr[2] = *optr++;
-                                       nptr[3] = *optr++;
-
-                                       nptr += 4 * nwidth;
-                               }
+               }
+
+       } else {
+               unsigned char *optr, *nptr;
+
+               optr = source->data;
+               for (x = nwidth; x; x--) {
+                       nptr = target->data + 4 * (x - 1);
+                       for (y = nheight; y; y--) {
+                               nptr[0] = *optr++;
+                               nptr[1] = *optr++;
+                               nptr[2] = *optr++;
+                               nptr[3] = *optr++;
+
+                               nptr += 4 * nwidth;
                        }
                }
-       } else if ((angle > 180.0 - min_usable_angle) &&
-                                 (angle < 180.0 + min_usable_angle)) {
+       }
 
-               nwidth = image->width;
-               nheight = image->height;
-               img = RCreateImage(nwidth, nheight, True);
-               if (!img)
-                       return NULL;
+       return target;
+}
 
-               if (bpp == 3) {
-                       unsigned char *optr, *nptr;
+RImage *wraster_rotate_image_180(RImage *source)
+{
+       RImage *target;
+       int nwidth, nheight;
+       int x, y;
 
-                       optr = image->data;
-                       nptr = img->data + nwidth * nheight * 4 - 4;
+       nwidth = source->width;
+       nheight = source->height;
 
-                       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;
+       target = RCreateImage(nwidth, nheight, (source->format != RRGBFormat));
+       if (!target)
+               return NULL;
 
-                                       optr += 3;
-                                       nptr -= 4;
-                               }
-                       }
-               } else {
-                       unsigned *optr, *nptr;
+       if (source->format == RRGBFormat) {
+               unsigned char *optr, *nptr;
 
-                       optr = (unsigned *)image->data;
-                       nptr = (unsigned *)img->data + nwidth * nheight - 1;
+               optr = source->data;
+               nptr = target->data + nwidth * nheight * 3 - 3;
 
-                       for (y = nheight * nwidth - 1; y >= 0; y--) {
-                               *nptr = *optr;
-                               optr++;
-                               nptr--;
+               for (y = 0; y < nheight; y++) {
+                       for (x = 0; x < nwidth; x++) {
+                               nptr[0] = optr[0];
+                               nptr[1] = optr[1];
+                               nptr[2] = optr[2];
+
+                               optr += 3;
+                               nptr -= 3;
                        }
                }
-       } else if ((angle > 270.0 - min_usable_angle) &&
-                                 (angle < 270.0 + min_usable_angle)) {
-               nwidth = image->height;
-               nheight = image->width;
 
-               img = RCreateImage(nwidth, nheight, True);
-               if (!img)
-                       return NULL;
+       } else {
+               unsigned char *optr, *nptr;
+
+               optr = source->data;
+               nptr = target->data + nwidth * nheight * 4 - 4;
+
+               for (y = nheight * nwidth - 1; y >= 0; y--) {
+                       nptr[0] = optr[0];
+                       nptr[1] = optr[1];
+                       nptr[2] = optr[2];
+                       nptr[3] = optr[3];
 
-               if (bpp == 3) {
-                       unsigned char *optr, *nptr;
+                       optr += 4;
+                       nptr -= 4;
+               }
+       }
 
-                       optr = image->data;
+       return target;
+}
 
-                       for (x = nwidth; x; x--) {
-                               nptr = img->data + 4 * nwidth * nheight - x * 4;
-                               for (y = nheight; y; y--) {
-                                       nptr[0] = *optr++;
-                                       nptr[1] = *optr++;
-                                       nptr[2] = *optr++;
-                                       nptr[3] = 255;
+static RImage *rotate_image_270(RImage *source)
+{
+       RImage *target;
+       int nwidth, nheight;
+       int x, y;
 
-                                       nptr -= 4 * nwidth;
-                               }
-                       }
-               } else {
-                       unsigned char *optr, *nptr;
+       nwidth = source->height;
+       nheight = source->width;
 
-                       optr = image->data;
+       target = RCreateImage(nwidth, nheight, (source->format != RRGBFormat));
+       if (!target)
+               return NULL;
+
+       if (source->format == RRGBFormat) {
+               unsigned char *optr, *nptr;
 
-                       for (x = nwidth; x; x--) {
-                               nptr = img->data + 4 * nwidth * nheight - x * 4;
-                               for (y = nheight; y; y--) {
-                                       nptr[0] = *optr++;
-                                       nptr[1] = *optr++;
-                                       nptr[2] = *optr++;
-                                       nptr[3] = *optr++;
+               optr = source->data;
+               for (x = nwidth; x; x--) {
+                       nptr = target->data + 3 * nwidth * nheight - x * 3;
+                       for (y = nheight; y; y--) {
+                               nptr[0] = *optr++;
+                               nptr[1] = *optr++;
+                               nptr[2] = *optr++;
 
-                                       nptr -= 4 * nwidth;
-                               }
+                               nptr -= 3 * nwidth;
                        }
                }
+
        } else {
-               img = rotateImage(image, angle);
+               unsigned char *optr, *nptr;
+
+               optr = source->data;
+               for (x = nwidth; x; x--) {
+                       nptr = target->data + 4 * nwidth * nheight - x * 4;
+                       for (y = nheight; y; y--) {
+                               nptr[0] = *optr++;
+                               nptr[1] = *optr++;
+                               nptr[2] = *optr++;
+                               nptr[3] = *optr++;
+
+                               nptr -= 4 * nwidth;
+                       }
+               }
        }
 
-       return img;
+       return target;
 }
 
 /*
@@ -294,11 +327,11 @@ copyLine(int x1, int y1, int x2, int y2, int nwidth, int 
format, unsigned char *
 }
 #endif
 
-static RImage *rotateImage(RImage *image, float angle)
+static RImage *rotate_image_any(RImage *source, float angle)
 {
        (void) angle;
        puts("NOT FULLY IMPLEMENTED");
-       return RCloneImage(image);
+       return RCloneImage(source);
 #if 0
        RImage *img;
        int nwidth, nheight;
diff --git a/wrlib/rotate.h b/wrlib/rotate.h
new file mode 100644
index 0000000..1a1d140
--- /dev/null
+++ b/wrlib/rotate.h
@@ -0,0 +1,30 @@
+/*
+ * Raster graphics library
+ *
+ * Copyright (c) 2014 Window Maker Team
+ *
+ *  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.
+ */
+
+#ifndef WRASTER_ROTATE_H
+#define WRASTER_ROTATE_H
+
+
+/*
+ * Returns a new image, rotated by 180 degrees
+ */
+RImage *wraster_rotate_image_180(RImage *source);
+
+
+#endif
-- 
2.0.0


-- 
To unsubscribe, send mail to [email protected].

Reply via email to