diff --git a/wrlib/Makefile.am b/wrlib/Makefile.am index e9f357c4..a9e6e83d 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 f2f92b99..84b34b7a 100644 --- a/wrlib/rotate.c +++ b/wrlib/rotate.c @@ -25,8 +25,11 @@ #include #include #include + #include + #include "wraster.h" +#include "rotate.h" #include @@ -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; - - if (bpp == 3) { - 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] = 255; - - nptr += 4 * 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 if ((angle > 180.0 - min_usable_angle) && (angle < 180.0 + min_usable_angle)) { + return wraster_rotate_image_180(image); - 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 - min_usable_angle) && (angle < 270.0 + min_usable_angle)) { - nwidth = image->height; - nheight = image->width; + return rotate_image_270(image); - img = RCreateImage(nwidth, nheight, True); - if (!img) - return NULL; + } else { + return rotate_image_any(image, angle); + } +} - if (bpp == 3) { - unsigned char *optr, *nptr; +static RImage *rotate_image_90(RImage *source) +{ + RImage *target; + int nwidth, nheight; + int x, y; - optr = image->data; + nwidth = source->height; + nheight = source->width; - 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; + target = RCreateImage(nwidth, nheight, (source->format != RRGBFormat)); + if (!target) + return NULL; - nptr -= 4 * nwidth; - } - } - } else { - unsigned char *optr, *nptr; + if (source->format == RRGBFormat) { + unsigned char *optr, *nptr; - optr = image->data; + 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++; - 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++; - - 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 * (x - 1); + for (y = nheight; y; y--) { + nptr[0] = *optr++; + nptr[1] = *optr++; + nptr[2] = *optr++; + nptr[3] = *optr++; + + nptr += 4 * nwidth; + } + } } - return img; + return target; +} + +RImage *wraster_rotate_image_180(RImage *source) +{ + RImage *target; + int nwidth, nheight; + int x, y; + + nwidth = source->width; + nheight = source->height; + + target = RCreateImage(nwidth, nheight, (source->format != RRGBFormat)); + if (!target) + return NULL; + + if (source->format == RRGBFormat) { + unsigned char *optr, *nptr; + + optr = source->data; + nptr = target->data + nwidth * nheight * 3 - 3; + + 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 { + 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]; + + optr += 4; + nptr -= 4; + } + } + + return target; +} + +static RImage *rotate_image_270(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; + + 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 -= 3 * nwidth; + } + } + + } else { + 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 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 00000000..1a1d140f --- /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